Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Welcome to the Dude Coding Standards (DCS) documentation by Finnish digital agency Dude, locally known literally as Digitoimisto Dude Oy.
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.
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!
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.
Or prefix. Whatever you like to call them.
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.
<p>Smaller prefix title</p>
<h1>The main title</h1>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 sanitize_title() function.
<p aria-describedby="unique-sanitized-title-id">
Smaller prefix title
</p>
<h1 id="unique-sanitized-title-id">
The main title
</h1>Working with SVGs, the Dude way
How to write HTML at Dude.
On this page you'll find examples on how to write HTML according to Dude Coding Standards.
Please also see the installation in Air-light Debuggers or on . Your editors should lint automatically after installing these tools.
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.MissingUnslashWith 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.phpYou should always comment your code as thorough as possible. For indentation we use to char space. Always use the latest .editorconfig:
First we define the main fonts and then the context where we are using the font families.
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:
Copy the viewBox attribute and its values.
Minimize the contents of the file with the in VSCode.
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.
How to create an accessible search form.
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.
This example has the proper form according to . 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.
: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);
}<ul><li>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</li></ul><ul>
<li>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</li>
</ul>// Force color for color themes not to change this to unreadable colors
// stylelint-disable-next-line declaration-no-important<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><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><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>Defined format:
--category-element-property-state: value;--color-goldenrod: #fdcb68;
--spacing-container-inline-padding: 2rem;
--typography-weight-regular: 400;
--typography-size-15: 15px;
--typography-line-height: 1.5;--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.
Always check out your .stylelintrc for the latest rules. Aim for readable CSS. Use the "inception rule", do not go too deep.
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);
}
}
}
}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 {
}Our custom blocks are named:
.blockItems inside block:
.block-header.block-content.block-footerThese can be columns, upsells, grids, masonries, social media walls, logowalls, etc.
.items {
}.item.item-something {
}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 {
}We use heading instead of title.
.heading-something {
}.wrapper-icons {
}Defined in _button.scss component.
.wrapper-button,
.wrapper-link {
}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.
<div class="col">
<a href="<?php echo esc_url( get_the_permalink() ); ?>" class="global-link"></a>
<h2>Title</h2>
<p>Descriptive text.</p>
</div>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" aria-hidden="true" tabindex="-1"></a>
<h2>
<a href="<?php echo esc_url( get_the_permalink() ); ?>">
Title
</a>
</h2>
<p>Descriptive text.</p>
</div>We use the word "heading" instead of "title".
<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
Under this doc you'll find out how you should do the markup of HTML elements.
Dude uses SCSS and modern CSS for styles. Our way of doing cascading style sheets is our own hybrid that is based on SMACSS (Scalable and Modular Architecture for CSS) and the style guide used by Gutenberg 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:
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.
By default, the Gutenberg block icons in the WP dashboard will contain a black fill. Follow these steps to nuke that annoying fill:
Add a class name directly to the SVG. Ex: class="gutenberg-icon"
In the _colors.scss file, apply a color value (most likely, white) to the SVG, like so:
Here’s the SVG’s code:
Add your new SVG file to the nav-walker.php file:
Now let’s hide that path. Add these rulesets and declarations to your theme’s nav files:
In _nav-desktop.scss
In _nav-mobile.scss
svg.icon {
color: var(--color-whisper);
}
svg {
color: var(--color-east-side);
}
a svg {
color: var(--color-purple-mountains-majesty);
}.gutenberg-icon {
color: var(--color-white);
}<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>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>'; .hover-intent > .dropdown-toggle svg {
.hide {
opacity: 0;
}
} .dropdown-toggle.toggled-on {
.hide {
opacity: 0;
}
}When working with decorative SVG icons, add the aria-hidden="true" attribute to your SVG file.
<svg aria-hidden="true">
...
</svg>