# Design System

# CSS Utilities

Does what it says on the tin. It center-aligns text with `text-align` and uses
`margin-inline: auto` to center align on the reading mode direction.

```html
<header class="all-center">
  <h1>A page header</h1>
  <p>
    Donec ullamcorper nulla non metus auctor fringilla. Integer posuere erat a
    ante venenatis dapibus posuere velit aliquet. Aenean eu leo quam.
    Pellentesque ornare sem lacinia quam venenatis vestibulum. Curabitur blandit
    tempus porttitor. Donec ullamcorper nulla non metus auctor fringilla. Duis
    mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia
    odio sem nec elit. Cum sociis natoque penatibus et magnis dis parturient
    montes, nascetur ridiculus mus.
  </p>
</header>
```

## Avatar

The avatar utility adds a consistent treatment to images of authors and prevents
them being shrunk/grown by flexbox layouts.

You can affect the size of the avatar in your context by setting a value for
`--avatar-size`, which has a default value of `65px`.

The `.avatar` class can be added directly to an image, or a direct parent, such
as a link.

```html
<img class="avatar" src="/path-to-image.jpg" alt="Example's profile shot" />

<a href="#" class="avatar">
  <img class="avatar" src="/path-to-image.jpg" alt="Example's profile shot" />
</a>
```

## Flow

The flow utility provides flow and rhythm between direct sibling elements.
Where `--flow-space` is not defined: the default value is 1em, which equals
the font size of the affected element.

[More info](https://piccalil.li/quick-tip/flow-utility/)

```html
<article class="flow">
  <p>
    Nullam id dolor id nibh ultricies vehicula ut id elit. Nulla vitae elit
    libero, a pharetra augue.
  </p>
  <p>
    Nulla vitae elit libero, a pharetra augue. Cras justo odio, dapibus ac
    facilisis in, egestas eget quam.
  </p>
  <p style="--flow-space: 2em">
    Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
  </p>
</article>
```

You can also use the `flow-space` generated utility that allows you to use
the **spacing design tokens**. For example, If you want that last paragraph
to have a `Size 2` spacing, you would change the code to the following:

```html
<article class="flow">
  <p>
    Nullam id dolor id nibh ultricies vehicula ut id elit. Nulla vitae elit
    libero, a pharetra augue.
  </p>
  <p>
    Nulla vitae elit libero, a pharetra augue. Cras justo odio, dapibus ac
    facilisis in, egestas eget quam.
  </p>
  <p class="flow-space-size-2">
    Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
  </p>
</article>
```

## Focus ring

A box-shadow powered focus ring that uses a transparent outline to provide
focus for high contrast users. The box-shadow helps to support border-radius
elements.

```html
<button class="my-cool-button focus-ring">My cool button</button>
```

You can customise the `--focus-ring-padding-color`, which creates the
illusion of space, but it's actually just the background.

```css
.my-cool-button {
  --focus-ring-padding-color: goldenrod;
}
```

## Region

A container that provides consistent vertical spacing for
chunks/sections/regions of content.

```html
<div class="region">I have consistent space now.</div>
```

## Over Scroll

Provides a container that _contains_ overflowing content. This should be sized externally, either with [flex basis](https://piccalil.li/tutorial/build-a-responsive-media-browser-with-css/#heading-making-the-nav-shrinkable), or with units, like the example below.

```html
<div class="over-scroll" style="max-height: 10rem">
  <p>
    Leo malesuada nibh sed quam curae sollicitudin laoreet aptent fermentum
    tristique elit feugiat ultricies eget pulvinar rutrum venenatis turpis
    integer neque blandit aliquet morbi ligula risus hendrerit inceptos metus
    senectus mollis convallis vulputate scelerisque dictum vehicula etiam massa
    justo
  </p>
  <p>
    Leo malesuada nibh sed quam curae sollicitudin laoreet aptent fermentum
    tristique elit feugiat ultricies eget pulvinar rutrum venenatis turpis
    integer neque blandit aliquet morbi ligula risus hendrerit inceptos metus
    senectus mollis convallis vulputate scelerisque dictum vehicula etiam massa
    justo
  </p>
</div>
```

## Scrollbar

Provides a scrollbar only if there is overflow content. This utility only provides the scrollbar and **not** the rule which determines which direction scrolling occurs (`overflow-x`, `overflow-y`, `overflow`), so the element that this is applied to needs to deal with that.

### Example

```html
<div class="table-wrapper scrollbar">
  <table></table>
</div>
```

## Visually hidden

If you hide an element with `display: none`, it can also hide it from assistive
technology, such as screen readers. This utility allows you to get the effect
of `display: none`, without the a11y issues.

```html
<p class="visually-hidden">
  You can't see me, but a screen reader can still access me
</p>
```

## Wrapper

A horizontally centered wrapper that provides a consistent central column.
This should be used in all contexts where the content needs to be in the
center of the page.

```html
<div class="wrapper">I am centered and have a nice, consistent gutter.</div>
```

You can add an [exception](https://cube.fyi/exception.html) to create a narrow
wrapper, too. Add `data-size="narrow"` to the element and it will have a reduced
width and **no gutter**.

```html
<div class="wrapper" data-size="narrow">I am a reduced width wrapper</div>
```

You can also remove inline padding by adding `data-flush`.

```html
<div class="wrapper" data-flush>I am a flush wrapper</div>
```

# Welcome to the web.dev design system

<nav class="cluster" aria-label="key sections">
<a href="#for-developers">For developers</a>
<a href="#for-authors">For authors</a>
<a href="#about-the-css">About the CSS</a>
</nav>

This design system will help you to maintain consistency around the web.dev website by providing CSS structure, design tokens, typography rules and spacing rules, along with a comprehensive component library.

## Quick start

<div class="breakout">
<div class="auto-grid gap-top-size-2">
  
  <a class="card flow bg-mid-bg" href="{{ item.url }}">
    <h3>{{ item.title }}</h3>
    <p>{{ item.summary }}</p>
  </a>
  
</div>
</div>

## For developers

This design system should be treated as the source of truth for **any** front-end development work that requires CSS.

### About the CSS

The design system is built around [CUBE CSS](https://cube.fyi/), a methodology that’s orientated towards simplicity and pragmatism. Versus the previous system on web.dev, a lot of CSS is declared as high up as possible—globally—rather than concentrated on complex BEM components.

The CSS is pre-processed using SCSS, which in turn, uses [Gorko](https://github.com/hankchizljaw/gorko) to provide structure, mixins and generated utility classes. The design system uses utilities regularly, so ensure you read up on [how Gorko generates them](https://github.com/hankchizljaw/gorko#utility-class-generator). They are [defined here](https://github.com/GoogleChrome/web.dev/blob/main/src/scss/_config.scss#L19).

Everything in CSS is powered by [design tokens](https://piccalil.li/tutorial/what-are-design-tokens/), which are [defined here](https://github.com/GoogleChrome/web.dev/blob/main/src/site/_data/design/tokens.json). The design tokens mainly define colors, fonts, spacing, sizes, transitions and decorative elements, such as border radius.

Lastly, the whole design system is **theme-driven**. This means that tokens are applied to contexts, rather than directly to elements. This makes working with dark/light themes much easier with less authored code. [Read more in the color section](/design-system/colors/#theme-usage).

### SCSS file and folder structure

The structure is as follows:

```plaintext
src
└── scss
    ├── blocks
    ├── compositions
    ├── functions
    ├── mixins
    ├── pages
    ├── utilities
    ├── web-components
    ├── _config.scss
    ├── _fonts.scss
    ├── _reset.scss
    ├── _rollout.scss
    ├── _themes.scss (generated)
    ├── _tokens.scss (generated)
    └── next.scss
```

The Sass folder mostly resembles the CUBE CSS structure and is as follows:

1. `blocks`: [contained components](https://cube.fyi/block.htm)
2. `compositions`: [layout compositions](/design-system/css-compositions/)
3. `functions`: Sass functions used across the SCSS files
4. `mixins`: Sass mixins used across the SCSS files
5. `pages`: specific styles for pages and page types
6. `utilities`: [core utilities](/design-system/css-utilities/)
7. `web-components`: styles for [specific web-components](https://github.com/GoogleChrome/web.dev/tree/main/src/lib/components)
8. `_config.scss`: core [Gorko configuration](https://github.com/andy-piccalilli/gorko#configuration)
9. `_fonts.scss`: `@font-face` declarations
10. `_reset.scss`: a [lightweight CSS reset](https://piccalil.li/blog/a-modern-css-reset/)
11. `_rollout.scss`: Temporary styles to provide a bridge between the old system and new system while the new system is rolled out
12. `_themes.scss`: an auto-generated file by `src/site/_data/design/themes.js`
13. `_tokens.scss`: an auto-generated file by `src/site/_data/design/tokens.js`
14. `next.css`: the main SCSS file that pulls everything together and defines [global CSS](https://cube.fyi/css.html)

## For authors

Please use the same [component guide in the handbook](/handbook/web-dev-components/) as always.

## How to use the pattern/component generator

To prevent repetitive file creation, you can use the pattern generator to create a new pattern, or pattern's variant with a npm task.

### Example

Let's say you want a new pattern called "my-pattern":

```bash
npm run patterns:create -- -p my-pattern -n my-pattern -t My\ Pattern
```

This will create the following folder and file structure:

```plaintext
web.dev
└── src/
    └── component-library/
        └── my-pattern/
            ├── my-pattern.njk
            ├── my-pattern.json
            └── my-pattern.md
```

Let's you want to create a variant of "my-pattern":

```bash
npm run patterns:create -- -p my-pattern/variants -n my-pattern-primary -t Primary
```

It'll result in this structure:

```plaintext
web.dev
└── src/
    └── components/
        └── patterns/
            └── my-pattern/
                ├── my-pattern.njk
                ├── my-pattern.json
                ├── my-pattern.md
                └── variants/
                    ├── my-pattern-primary.njk
                    └── my-pattern-primary.json
```

### Arguments

There are 2 required arguments to pass in—`-p` and `-n`. The rest are optional.

Make sure you add the `--` _after_ `npm run patterns:create` so the arguments get passed into the task.

Also make sure you escape spaces with a `\`.

- `-p` is the path from `src/components/patterns`
- `-n` is the file name
- `-t` is the title. If this is not set, the `-n` will be used
- `-sm` allows you to skip markup being generated if you are generating a variant