Skip to content

Coding standards

Sam Richard edited this page Jan 20, 2022 · 3 revisions

Prettier

The project uses Prettier to format the source code. Some Google standards may be overlooked in favor of the Prettier style guide.

Javascript style guide

Reading

Project considerations

Javascript file names and variables should follow the naming principles for the project:

  • File names must be written in kebab-case
  • Variable names must be written in lowerCamelCase
  • Local variables should have an underscore at the end of its name, i.e. let myLocalVar_ = true;

Note: Before adding any new code, make sure to take a look at the codebase, analyze and understand it and follow established patterns.

All Javascript files must start with the following license disclaimer:

/**
 * Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

If you need to add some configurations, plugins, collections, etc… to Eleventy, do so in the .eleventy.js file and add them following existing patterns. Similarly, if you need to add some configurations, plugins, etc… to Vite, do so in the vite.config.js file and add them following existing patterns. HTML transformations should be done via a PostHTML plugin, inside lib/transforms, and added as a plugin to the Vite PostHTML plugin in vite.config.js.

Extending our Build Process

Code to extend our build process should be placed under the lib folder in one of the following sub-folders:

Javascript on ChromeOS.dev pages

Before adding any new Javascript, make sure you explore all HTML and CSS alternatives and determine that and none of them worked as needed.

main.js is the entry point of the Javascript code and it’s located in the site/js/ folder.

Global components should be initialized on the DOMContentLoaded event handler following the pattern defined by MainNavigation class. i.e. the Navigation

Components used on a specific page will use Dynamic imports, so they are loaded only when needed. To add components using dynamic imports place your code on load handler following the pattern defined by toc component.

HTML style guide

The project is powered by Nunjucks which is a templating language, however, all the templates are written to HTML files.

The html structure plays an important role for accessibility, therefore, it’s very important to make sure that the semantic element clearly describes its meaning properly according to the designs.

Reading

Project considerations

  • File names must be written in kebab-case
  • Major navigation blocks should be wrap by the nav element
  • The html structure should include the proper accessibility attributes following the accessibility recommendations
  • When styling text check the existing class type and its elements in _typography.scss file. Use it like <h1 class=”type--h1”> some title </h1>

Things to avoid

  • To avoid adding too many classes to an element, don’t double up a class in the html, use @extend in the element styling. For example: You can use type--* to add typography style to the elements like: <h3 class="icon-card__title type--h5 ">{{title}}</h3> Notice that the element already has an icon-card__title class, so, you might extend the %type--h5 in the icon-card__title class.
    • Don't use spans or divs unless there isn’t another element that makes sense, verify the purpose of the element you are placing and select the best semantic element to match it.

Images

  • All images, except our UI icons, favicon, and PWA icons, are served from an image-optimization CDN. All image URLs for images served from the CDN should be prefixed with ix:// instead of a domain to be properly transformed, so if an image was available at posts/foo/image.png on the CDN, the URL should be ix://posts/foo/image.png in our codebase. If you need help uploading an image to our CDN, please reach out to one of the site administrators.
  • Images should include the alt attribute with a description text. If the image is decorative it should have alt=”’ Image alt

Anchor tags

  • Don't include target="_blank". We want to preserve default behavior unless there's a great need to.
  • Don’t manually include rel="noopener", our build process will automatically add it.

CSS style guide

  • All component styles are written in the scss syntax of Sass and compiled to generate a single CSS file.
  • Layout is based on Fluid layout web page design, that means there are no "standard breakpoints", but rather there are component and layout based breakpoints

Project considerations

  • File names must be written in kebab-case
  • Each component has a separate Sass file with its own style scope, and should be placed on the components folder (site/sass/components/_*.scss), then imported on style.scss Sass file (site/sass/style.scss)
  • Any style file must have an overview description at the beginning
// <file overview>
.component-class {
  // <definitions>
}
  • Each Sass partial should only have one block (see next), or component, in it.
  • Following BEM style pattern, all nested styles must be nested by ampersand &__element to generate a single class.
<section class="component">
  <article class="component__text">
    Lorem ipsum dolor sit amet...
  </article>
</section>
// <file overview>
.component {
  display: flex;
  &__text {
    color: var(--white);
  }
}
  • Avoid using “arbitrary numbers” without a coherent use. When selecting a number that may look arbitrary please add a comment explaining your reasoning.
  • Do not use base64 encoded images in CSS
  • Use absolute paths (/foo/bar) in URLs
  • Use margin for spacing between elements and padding for spacing inside an element.
  • When using display: grid is preferred to use gap for adding spacing around items on the grid.
  • Prefixes like -webkit and -moz- are blocked by project linter, but you can use // sass-lint:disable-line no-vendor-prefix at the end of the line to disable it. Please use it just in certain circumstances like override browser-specific styling.
  • Group common styles.
&__first-element,
&__second-element {
  background-color: var(--black);
  color: var(--white);
  display: block;
}
  • Do not style HTML tags directly unless you have no other way to style an element, for example styling HTML generated from markdown files or markdownIt plugins.
  • In case of using any breakpoint (requirement only) the project has a dependency to create safe breakpoints. You can Read more about how to use it. Make sure to keep the component scope
// <file overview>
.component {
  display: flex;

  @include mq(700px) {
    // <definitions>
  }
}

CSS Variables

  • Global variables must be written to the _vars.scss SASS file (site/sass/globals/_vars.scss) .
  • Local variables must be written to its specific component Sass file, at the beginning of the file, keeping the component scope.
// <file overview>
.component {
   $my-local-variable: #cecece display: flex;
   &__text {
      color: var(--my-local-variable);
   }
}
  • Variable names must be written in kebab-case.
  • Use Google colors variables provided by _colors.scss file (site/sass/globals/_colors.scss)
  • Do not add new colors, only if it is a requirement.

Typography

Typography for the site is defined in typography.scss. This file contains general styling for anchors across the site, and a base class for texts called .type. The .type class defines the flow and spacing of elements for long format content (content from .md files). Headings are defined to change size using the clamp function between a min value that will work for small viewports and a max value that will work for large viewports. For browsers that don't support clamp the font size will be the same across all viewports (medium size font).

Here is an example of the compiled CSS for type--h1.

.type--h1 {
  font-size: pxEm(48px);
  line-height: 1.1666666667;
  letter-spacing: pxEm(-0.5px);
}

@supports (font-size: clamp(pxEm(36px), 5.859375vw, pxEm(60px))) {
  .type--h1 {
    font-size: clamp(pxEm(36px), 5.859375vw, pxEm(60px));
    line-height: 1.2;
  }
}
  • Changes in global typography styles must be written to the _typography.scss SASS file.
  • When writing a new component use classes defined on typography file. Do not redeclare font-size or font-family in component styles unless there is no other way..
  • Use classes provided by _typography.scss file (site/sass/components/_typography.scsss) instead of styling html tags fonts.

Modern functionality

We encourage using modern CSS when it is possible to provide users an enhanced experience when their browser allows it.

One of those modern utilities is the he clamp function, which allows us to specify a min, variable, and max value we want something to be. Clamp is currently supported in Chromium browsers and Firefox will support it soon, so we can start using it. With it, we can, in conjunction with @supports, deliver modern code for browsers that support it, and fallback code for browsers that don't.

%blockquote__before {
  width: 0.25rem;

  @supports (width: clamp(1px, 1vw, 2px)) {
    width: clamp(0.25rem, 1vw, 0.5rem);
  }
}

What the above will do is set the width to .25rem (4px) if 1vw < 4px, 1vw if 4px < 1vw < .5rem, and .5rem if 1vw < .5rem. This does mean that Safari browsers will always have the smaller width of .25rem.

Units

  • Giving the approach used on the project (Fluid layout), we encourage the use of relative units such as em, rem, ch and so on. In case you are not familiar using them, the project has two mixins to help you to convert pixels to rems and ems, pxRem and pxEm.
// <file overview>
.component {
  padding: pxRem(16px) pxRem(24px);
}

Here's a small cheatsheet conversion table between pixels and rems.

Px Rem
8 0.5
16 1
20 1.25
24 1.5
28 1.75
32 2
40 2.5

Reading

Nunjucks style guide

  • The project uses Prettier as code formatter and it does not support nunjucks syntax formatting the code as HTML.
  • Conditional and variable definitions need to be written in a single line.
<title>
  {% if section != 'index' %} {% block title %}{% endblock %} - {% endif %}
</title>
  • New components will be located at templates/_components level.
  • Macros follow the same name convention as the file that includes them using camelCase.

icon-card.html

{% macro iconCard(data, defaultText) -%}
<article class="icon-card">
  ...
</article>
{%- endmacro %}
  • Macros need to be documented.. Use JSDoc style documentation for all macros
<!--{#
  Renders content with a CTA.

  @param {object} content - Main content for the macro
  @param {string} content.title - Title of macro
  @param {string} content.body - Main body content of the macro
  @param {number} [content.weight] - Weight of the macro (optional)
  @param {object} cta - Call to Action
  @param {string} cta.title - Title of the CTA
  @param {string} cta.url - URL of the CTA
 #}-->
{% macro myMacro(content, cta) -%}
<article class="my-macro”>
   ...
</article>
{%- endmacro %}

Reading

General reading

These resources will help you write cleaner code.

Clone this wiki locally