Only this pageAll pages
Powered by GitBook
1 of 25

Dude Coding Standards

Loading...

HTML

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

PHP

Loading...

Loading...

CSS

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Blocks

Resources

Section blocks

This is an example on what structure should be used in Gutenberg Blocks.

<section class="block block-example">
  <div class="container">
     <!-- Content -->
  </div>
</section>

Accessible HTML Guidelines

How to write HTML at Dude.

On this page you'll find examples on how to write HTML according to Dude Coding Standards.

Dude Coding Standards

Welcome to the Dude Coding Standards (DCS) documentation by Finnish digital agency Dude, locally known literally as Digitoimisto Dude Oy.

WIP-note for staff: This Space is meant for public Coding Standards documentation only that should be visible for everyone online. Everything else in tech should be located in Internal Development Docs or Public Company Handbook.

Development at Dude

You are browsing the technical Coding Standards handbook of Dude, the Finnish digital agency. This handbook is supposed to be helpful for both internal and external members of Dude. It consists of best practices in programming at Dude.

Base for development

We are committed to keep this handbook under continuous development. If we notice issues in our tech, workflow, DevOps or anything related, we will improve on those areas. If you have any suggestions to this handbook, please send them to [email protected]. Thanks!

Please note: As most of this documentation includes pretty common best practices, it may also have something strictly specific to our company culture. It may not be easily followed by a external member of our community so please advice.

What is Dude?

Dude is a shortened name of a Finnish boutique web design agency formed in 2013 in Jyväskylä, Finland. Our main product is customized WordPress websites, weshops and web services for companies.

Our area of operation is currently Finland, but as we are a part for active WordPress community, actively publishing our tools and ways with open source licenses and using English as a development language, hence this documentation landing page is in English as well.

Related documentation

Headings

We use the word "heading" instead of "title".

Please note: Class names should go hand in hand with CSS Naming Conventions.

<h2 class="heading-block">Heading</h2>

Sometimes headings don't need any class. So do not add classes without reason. No class needed in following cases:

  • If the heading follow the generic typographic styles

  • If the heading style is used only once

  • If there is no component or classes in CSS

Upper title/Prefix

Or prefix. Whatever you like to call them.

Wrong

Why it is wrong

Assistive tools and keyboards see this as: paragraph, title. They are not linked to each other. For seeing users this is no problem as we have styled the small paragraph but for others it causes confusion.

Right

Why it is right

This markup actually links the smaller prefix title to the main title. Remember to always use unique id for this in both aria-describedby and id attribute values. This can be easily achieved with WordPress's function.

CSS and SCSS Guidelines

Dude uses SCSS and modern CSS for styles. Our way of doing cascading style sheets is our own hybrid that is based on and the style guide used by by WordPress. Practically this brings us the is-* and has-* naming conventions in selectors.

The Guidelines are based on stylelint standards we have defined. Our stylelint config extends stylelint-config-standard and stylelint-config-recommended-scss. View the full .stylelintrc here:

<p>Smaller prefix title</p>
<h1>The main title</h1>
<p aria-describedby="unique-sanitized-title-id">
    Smaller prefix title
</p>

<h1 id="unique-sanitized-title-id">
    The main title
</h1>
sanitize_title()

Naming classes

Blocks

Our custom blocks are named:

.block

Items inside block:

.block-header
.block-content
.block-footer

Please note: If there is no need for these items, they don't need to be added. For example if there is other items, you don't need an extra div inside container.

Items

These can be columns, upsells, grids, masonries, social media walls, logowalls, etc.

Parent

.items {
}

Children

.item.item-something {
}

Wrappers

Site-header and site-footer follow the WordPress guidelines:

.site-header {
}
.site-footer {
}

Content width container is always:

.container {
}

Something "smaller" like text:

.content {
}

Other general wrappers:

.wrapper-something {
}

Headings

We use heading instead of title.

.heading-something {
}

Icons

.wrapper-icons {
}

Buttons and links

Defined in _button.scss component.

.wrapper-button,
.wrapper-link {
}

Custom properties and variables

Variable naming conventions

Defined format:

 --category-element-property-state: value;

Examples for the root variable partials

--color-goldenrod: #fdcb68;
--spacing-container-inline-padding: 2rem;
--typography-weight-regular: 400;
--typography-size-15: 15px;
--typography-line-height: 1.5;

Examples of how variables in block/component and other files could be named

--color-menu-item-background: var(—color-white);
--color-menu-item-background-hover: var(--color-light-grey);
--color-menu-item-text: var(--color-black);
--color-menu-item-text-current: var(--color-navy);
--color-menu-item-text-hover: var(--color-teal);
--spacing-menu-item-link-padding: 2rem;

We don't need separate breakpoint-specific variables.

We can just redefine the values of each original custom property within the scope of each media/container query. Which would work well if the nav mobile and desktop partials are ever consolidated in the future.

Defining font families

First we define the main fonts and then the context where we are using the font families.

:root {
  // Brand fonts
  --typography-family-whatever: Whatever;
  
  // Contexts
  --typography-paragraph: var(--typography-family-whatever);
  --typography-heading: var(--typography-family-whatever);
  --typography-upper-headings: var(--typography-family-whatever2);
}

SVGs and accessibility

When working with decorative SVG icons, add the aria-hidden="true" attribute to your SVG file.

<svg aria-hidden="true">
...
</svg>

SVGs

Working with SVGs, the Dude way

SMACSS (Scalable and Modular Architecture for CSS)
Gutenberg

Global links

Wrong

Why it is wrong

In this example we have an empty hyperlink element that is still readable with screen reader devices. It tells the blind nothing so it's a huge accessibility issue. And that's not all, the element is also not browsable via keyboard because its styles fill up the whole column.

Right

Why it is right

This example ignores the global link from screen readers and keyboards so that it serves only for seeing users. For assistive devices we use a normal link in title

<div class="col">
  <a href="<?php echo esc_url( get_the_permalink() ); ?>" class="global-link"></a>
  <h2>Title</h2>
  <p>Descriptive text.</p>
</div>
<div class="col">
  <a href="<?php echo esc_url( get_the_permalink() ); ?>" class="global-link" aria-hidden="true" tabindex="-1"></a>
  <h2>
    <a href="<?php echo esc_url( get_the_permalink() ); ?>">
      Title
    </a>
  </h2>
  <p>Descriptive text.</p>
</div>

Importing SVG files into a project

Important steps for all Dev Dudes to follow when adding SVGs to a project:

  1. Manually remove clipPaths from the file. This includes <g>, <clipPath>, and <def> tags, plus any additional child elements wrapped in <def> tags. Here’s a visual example where the tags to remove are commented out:

<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- <g clip-path="url(#clip0_6597_3671)"> -->
<path d="M2.25 0.75H22.75C22.75 0.75 23.75 0.75 23.75 1.75V22.25C23.75 22.25 23.75 23.25 22.75 23.25H2.25C2.25 23.25 1.25 23.25 1.25 22.25V1.75C1.25 1.75 1.25 0.75 2.25 0.75Z" stroke="#3A3A3A" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.5 6.5V5H10.5V6.5" stroke="#3A3A3A" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7.5 10.75V5" stroke="#3A3A3A" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M13.75 5H20" stroke="#3A3A3A" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M13.75 9.5H20" stroke="#3A3A3A" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.5 14H20" stroke="#3A3A3A" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.5 18.5H20" stroke="#3A3A3A" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<!-- </g> -->
<!-- <defs> -->
<!-- <clipPath id="clip0_6597_3671"> -->
<!-- <rect width="24" height="24" fill="white" transform="translate(0.5)"/> -->
<!-- </clipPath> -->
<!-- </defs> -->
</svg>
  1. Copy the viewBox attribute and its values.

  2. Minimize the contents of the file with the svgo extension in VSCode.

  3. Paste the viewBox attribute back into the file after the height attribute.

    • If the SVG is missing the viewbox attribute and its values, the SVG will be broken and the front-end Dude on the project will wonder why their pretty SVG styles aren’t showing up in the browser.

Stylelint

Disabling rules

If for some reason you need to use something in different manner than declared in .stylelintrc you should have good arguments in favor to it. You should comment the change accordingly:

// Force color for color themes not to change this to unreadable colors
// stylelint-disable-next-line declaration-no-important

Naming Conventions

HTML elements

Under this doc you'll find out how you should do the markup of HTML elements.

Linting PHP with PHP_CodeSniffer

Please also see the installation in Air-light Debuggers or on . Your editors should lint automatically after installing these tools.

Disabling rules

If for some reason you need to use something that has been disallowed in phpcs.xml you should have good arguments in favor to it. You should comment the change accordingly:

<?php
// This rule is disabled in this file because...
// phpcs:disable WordPress.Security.ValidatedSanitizedInput.MissingUnslash

PHP Code Beautifier and Fixer (phpcbf)

With phpcbf it's quick to fix the most common errors that are not right accoring to your project phpcs.xml.

phpcbf --standard=phpcs.xml page.php

General linting and coding rules

You should always comment your code as thorough as possible. For indentation we use to char space. Always use the latest .editorconfig:

Styling SVGs

Change SVG colors the easy way with currentColor

If you need to change the color of the SVG with CSS, plug the currentColor value into the stroke and/or fill attributes. With currentColor, the color applied to the SVG will be the same color that’s already declared in the SVG’s parent element. You can also change the color to something else by adding a color declaration directly to an SVG ruleset.

svg.icon {
  color: var(--color-whisper);
}

svg {
  color: var(--color-east-side);
}

a svg {
  color: var(--color-purple-mountains-majesty);
}

Gutenberg block SVGs (i.e., the icons in the WordPress dashboard)

By default, the Gutenberg block icons in the WP dashboard will contain a black fill. Follow these steps to nuke that annoying fill:

  1. Add a class name directly to the SVG. Ex: class="gutenberg-icon"

  2. In the _colors.scss file, apply a color value (most likely, white) to the SVG, like so:

.gutenberg-icon {
  color: var(--color-white);
}

Styling commonly used SVGs

The plus-sign inside of the circle used in sub-menu toggles. Specifically, the SVG containing the line path that disappears on toggle/click.

Here’s the SVG’s code:

<svg class="dropdown-toggle-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="11"/><path class="hide" d="M12 6v13"/><path d="M6 12h13"/></svg>

Add your new SVG file to the nav-walker.php file:

ob_start();

  require get_theme_file_path( 'svg/dropdown-plus.svg' );

  $icon = ob_get_clean();
  $output .= '<button class="dropdown-toggle" aria-expanded="false" aria-label="' . get_default_localization( 'Open child menu' ) . '">';
  $output .= $icon . '</button>';   

Now let’s hide that path. Add these rulesets and declarations to your theme’s nav files:

In _nav-desktop.scss

  .hover-intent > .dropdown-toggle svg {
    .hide {
      opacity: 0;
    }
  }

In _nav-mobile.scss

  .dropdown-toggle.toggled-on {
    .hide {
      opacity: 0;
    }
  }

Nesting

Always check out your .stylelintrc for the latest rules. Aim for readable CSS. Use the "inception rule", do not go too deep.

Wrong

Why it is wrong

Too much speficity. Hard to maintain.

.block-example {
  > div.block-related-element {
    .element-that-should-be-global {
      a.something-specific {
        background: var(--color-background-block-example);
        color: var(--color-brand);
        font-size: var(--font-size-large);
      }
    }
  }
}

Right

Why it is right

We are just styling the link here so no need for extra nesting and specificity. Just cut to the chase and define with class.

.block-example .something-specific {
  background: var(--color-background-block-example);
  color: var(--color-brand);
  font-size: var(--font-size-large);
}

If it's going to be a global style, you can even simplify it and add it outside the scope. Remember to choose classes wisely.

.something-specific {

}

Block libraryAir by Dude

Search form

How to create an accessible search form.

Wrong

Why it is wrong

In here we have a fully functional search form for visual people. However, labels contain text and inputs that are not accessible programmatically. Also in this example icon has been created by adding SVG inside label and hidden submit via styles. This means the user with keyboard or assistive devices can't use the form. Also for attribute is completely missing. Role is defined incorrectly for the form itself, that's wrong because form has role="form" explicitly built-in already.

<form role="search" method="get" class="search-form" action="/?">
  <label class="search-bar">
    <span class="screen-reader-text"><?php ask_e( 'Search: Search' ); ?></span>
    <input type="search" class="search-field" placeholder="<?php ask_e( 'Search: Search' ); ?>" value="" name="s">
  </label>
  <label class="icon">
    <input type="submit" class="search-submit">
    <?php include get_theme_file_path( '/svg/search.svg' ); ?>
  </label>
</form>

Right

Why it is right

This example has the proper form according to a11ymatters.com example. The search bar label is hidden visually with screen-reader-text class because in the layout it's not visible and normally seeing people still see the actual placeholder. The assistive devices will still read the label.

<form method="get" class="search-form" action="/?">
  <div role="search">

    <label class="search-bar screen-reader-text" for="search-field">
       <?php ask_e( 'Search: Search' ); ?>
    </label>

    <input id="search-field" type="search" class="search-field" placeholder="<?php ask_e( 'Search: Search' ); ?>" value="" name="s">

    <button class="search-submit">
      <?php include get_theme_file_path( '/svg/search.svg' ); ?>
    </button>
  </div>
</form>
devpackages/.stylelintrc at master · digitoimistodude/devpackagesGitHub
Logo
Air by Dude
Logo
Internal Development Docs
devpackages/.editorconfig at master · digitoimistodude/devpackagesGitHub
Logo

Lists

Wrong

Why it is wrong

Hard to read.

<ul><li>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</li></ul>

Right

Why it is right

Easy to read.

<ul>
  <li>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</li>
</ul>

PHP Guidelines

This documentation is under construction. Come back on later time when we have more stuff here!

PHP back-end development

In PHP development we use the official WordPress Coding Standards (WPCS) and WordPress Theme Coding Standards with some exceptions. You can see the exceptions in our phpcs.xml but besides this we have some project-based rules.