Components
Asides
Use asides to provide information that's related to but distinct from the content in the body of the post or codelab. Asides should generally be short—no more than 2–3 lines.
There are several kinds of asides, each for a different purpose.
Note asides
{% Aside %}
Use the note aside to provide supplemental information.
{% endAside %}
Use the note aside to provide supplemental information.
Asides can contain links and formatted text, including code.
{% Aside %}
Here is some code:
```js
const foo = 'bar';
function() {
console.log('hello world');
}
```
Here is a fancy [named markdown link][google].
{% endAside %}
[google]: https://google.com
Here is some code:
const foo = 'bar';
function() {
console.log('hello world');
}
Here is a fancy named markdown link.
Caution asides
{% Aside 'caution' %}
Use the caution aside to indicate a potential pitfall or complication.
{% endAside %}
Use the caution aside to indicate a potential pitfall or complication.
Warning asides
{% Aside 'warning' %}
The warning aside is stronger than a caution aside; use it to tell the reader
not to do something.
{% endAside %}
The warning aside is stronger than a caution aside; use it to tell the reader not to do something.
Success asides
{% Aside 'success' %}
Use the success aside to describe a successful action or an error-free status.
{% endAside %}
Use the success aside to describe a successful action or an error-free status.
Important asides
{% Aside 'important' %}
Use the important aside to indicate a common problem that the reader wouldn't know
without specialized knowledge of the topic.
{% endAside %}
Use the important aside to indicate a common problem that the reader wouldn't know without specialized knowledge of the topic.
Key-term asides
{% Aside 'key-term' %}
Use the key-term aside to define a term that's essential to understanding an
idea in the body copy. Key-term asides should be a single sentence that
includes the term in italics. For example, "A _portal_ is…"
{% endAside %}
Use the key-term aside to define a term that's essential to understanding an idea in the body copy. Key-term asides should be a single sentence that includes the term in italics. For example, "A portal is…"
Codelab asides
{% Aside 'codelab' %}
Use the codelab aside to link to an associated codelab.
{% endAside %}
Get started: Measure your page performance with Lighthouse.
Example asides
{% Aside 'example' %}
Use the example aside to give an example use case.
{% endAside %}
Advertising platform Criteo recently ran a competition with more than 150 teams testing different machine learning models to evaluate how differential privacy concepts such as noise insertion and aggregation might impact advertising performance. It's helpful to examine these concepts since they underlie several of the Privacy Sandbox APIs.
Blockquotes
Use blockquotes to emphasize a quotation that's important to the main idea of a post. (For example, in a case study you might include a quotation from someone on the partner organization's management team.)
Always include a <cite>
element indicating the quote's source at the end of a block quote:
<blockquote>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Proin dictum a massa sit amet ullamcorper.
</p>
<cite>
Jon Doe
</cite>
</blockquote>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin dictum a massa sit amet ullamcorper.
Jon Doe
Buttons
In general, you shouldn't need to add buttons to your posts. These buttons are shown for reference.
<button class="material-button button-text color-primary">
Text button
</button>
<button class="material-button button-filled color-bg bg-primary">
Filled button
</button>
<button class="material-button button-filled button-round color-bg bg-primary">
Round button
</button>
Browser Compat
With the BrowserCompat
shortcode, you can embed an MDN - Browser Compatibility Data widget in your post. You have to pass in the dot-separated feature ID, as used on BCD Schema, e.g. for Web/API/BackgroundFetchEvent the ID is api.BackgroundFetchEvent
.
{% BrowserCompat 'api.BackgroundFetchEvent' %}
- chrome 74, Supported 74
- firefox, Not supported ×
- edge 79, Supported 79
- safari, Not supported ×
The widget will use 🗑 symbols to represent features that are deprecated:
- chrome 1, Supported 1
- firefox 1, Supported 1
- edge 12, Supported 12
- safari 1.3, Supported 1.3
The following JavaScript snippet, run from the DevTools console, will display the correct ID for a given MDN page that's currently open:
window.alert(document.querySelector(".bc-github-link")?.href.match(/title=(.+?)\+/)[1] ?? "No browser compat widget found on the page.")
Chrome Date
Use ChromeDate
when you want to refer to a specific milestone date in the Chrome release schedule.
- Chrome 111 (stable date): {% ChromeDate 111 %}
- Chrome 111 (stable date): {% ChromeDate 111, "stableDate" %}
- Chrome 111 (earliest beta date): {% ChromeDate 111, "earliestBetaDate" %}
- Chrome 111 (final beta date): {% ChromeDate 111, "finalBetaDate" %}
- Chrome 111 (stable date): March 6, 2023
- Chrome 111 (stable date): March 6, 2023
- Chrome 111 (earliest beta date): February 8, 2023
- Chrome 111 (final beta date): February 28, 2023
Code
developer.chrome.com uses the same syntax highlighter as web.dev.
See the Code post for more details.
Columns
Columns can be used to place elements side-by-side. This works well for blocks of code or images. On mobile the columns will stack vertically.
{% Columns %}
{% Column %}
{% Img src="image/foR0vJZKULb5AGJExlazy1xYDgI2/iuwBXAyKJMz4b7oRyIdI.jpg", alt="ALT_TEXT_HERE", width="380", height="240" %}
Original
{% endColumn %}
{% Column %}
{% Img src="image/foR0vJZKULb5AGJExlazy1xYDgI2/iuwBXAyKJMz4b7oRyIdI.jpg", alt="ALT_TEXT_HERE", width="380", height="240", params={flip: 'h'} %}
Flipped
{% endColumn %}
{% endColumns %}
{% Columns %}
{% Column %} <!-- Include a newline to mix markdown with shortcodes -->
```js
// v1
const config = {
foo: 'bar',
baz: 'qux',
};
```
{% endColumn %}
{% Column %}
```js
// v2
const config = {
up: 'down',
left: 'right',
};
```
{% endColumn %}
{% endColumns %}
// v1
const config = {
foo: 'bar',
baz: 'qux',
};
// v2
const config = {
up: 'down',
left: 'right',
};
Compare
{% Compare 'better' %}
The right way to do something
{% endCompare %}
{% Compare 'worse' %};
Don't do it this way!
{% endCompare %}
Do
The right way to do something
Don't
Don't do it this way!
Compare with caption
{% Compare 'worse' %}
Bad code example
{% CompareCaption %}
Explanation of why example is **bad**.
{% endCompareCaption %}
{% endCompare %}
{% Compare 'better' %}
Good code example
{% CompareCaption %}
Explanation of why example is **good**.
{% endCompareCaption %}
{% endCompare %}
Don't
Bad code example
Do
Good code example
Compare with custom labels
To support localization all custom labels will need to be added to the site/_data/i18n/common.yml
file.
# site/_data/i18n/common.yml
compare_unhelpful:
en: 'Unhelpful'
compare_helpful:
en: 'Helpful'
{% Compare 'worse', 'unhelpful' %}
Lorem ipsum dolor sit amet.
{% endCompare %}
{% Compare 'better', 'helpful' %}
Lorem ipsum dolor sit amet.
{% endCompare %}
Unhelpful
Lorem ipsum dolor sit amet.
Helpful
Lorem ipsum dolor sit amet.
Compare with fenced code block
{% Compare 'better' %}
```js
const x = 0;
```
{% endCompare %}
{% Compare 'worse' %}
```js
var x = 0;
```
{% endCompare %}
Do
const x = 0;
Don't
var x = 0;
Details (accordion functionality)
Use a details section to hide extra information from the user until it's needed. It can have an optional preview. Use this component if you need an accordion or expandable section.
{% Details %}
{% DetailsSummary %}
A brief summary goes here
{% endDetailsSummary %}
The body of the Details component goes here, and **can** contain markdown.
{% endDetails %}
A brief summary goes here
A brief summary goes here
The body of the Details component goes here, and can contain markdown.
The details shortcode also supports using headers in the summary.
{% Details %}
{% DetailsSummary %}
### A normal heading goes here
{% endDetailsSummary %}
The body of the Details component goes here, and **can** contain markdown.
{% endDetails %}
A normal heading goes here
A normal heading goes here
The body of the Details component goes here, and can contain markdown.
{% Details %}
{% DetailsSummary %}
### Details component summary
This is an optional preview.
{% endDetailsSummary %}
This is the body of the Details component.
It **can** contain markdown.
```js
const bar = 'foo';
console.log(bar);
```
{% endDetails %}
Details component summaryThis is an optional preview.
Details component summary
This is an optional preview.
This is the body of the Details component. It can contain markdown.
const bar = 'foo';
console.log(bar);
Glitches
Create a Glitch
- Remix the web-dev-hello-webpage or web-dev-hello-express template.
- Click Project options and update the description of the Glitch.
- Update
README.md
. - Update
package.json
(if it exists). - Add the project to the web.dev team on Glitch.
- Set the avatar of the project to the web.dev logo.
Embed a Glitch
{% Glitch {
id: 'tabindex-zero',
path: 'index.html',
previewSize: 0,
allow: []
} %}
<!-- Or just the Glitch ID -->
{% Glitch 'tabindex-zero' %}
It's OK to adjust the height
of the Glitch wrapper element if you need more or less space.
Shortcode object fields allow for modifying how the embed is presented:
- {
string | string[]
}allow?
List of feature policies of an IFrame either as an array of strings, or as a;
separated list. By default the following policies are enabled:'camera', 'clipboard-read', 'clipboard-write', 'encrypted-media', 'geolocation', 'microphone', 'midi'
- {
string
}id
ID of Glitch project. - {
string
}path?
Lets you specify which source code file to show. - {
number
}previewSize?
Defines what percentage of the embed should be dedicated to the preview, default is 100. - {
number
}height?
Height, in pixels, of the Glitch wrapper element.
Images
Images should always use the {% Img %}
shortcode. This shortcode will be generated for you when you upload your image to our CDN. See the Add an image or video guide for upload instructions.
{% Img src="image/foR0vJZKULb5AGJExlazy1xYDgI2/w9i7lEqGw5J5b3jx5fAu.jpg", alt="ALT_TEXT_HERE", width="800", height="450" %}
Images with a white background should use the .screenshot
class to give them a border so they don't appear to "float" on the page.
{% Img src='image/BrQidfK9jaQyIHwdw91aVpkPiib2/TDNgfhI9byR4eeGQ0Xxv.png', alt='Screenshot', height="302", width="770", class="screenshot" %}
<!-- Add the .screenshot--filled modifier to give the screenshot padding and a grey background. -->
{% Img src='image/BrQidfK9jaQyIHwdw91aVpkPiib2/TDNgfhI9byR4eeGQ0Xxv.png', alt='Screenshot', height="302", width="770", class="screenshot screenshot--filled" %}
Full bleed images
Full bleed images break out of the main column.
<div class="type--full-bleed">
{% Img src="image/foR0vJZKULb5AGJExlazy1xYDgI2/w9i7lEqGw5J5b3jx5fAu.jpg", alt="ALT_TEXT_HERE", width="800", height="450" %}
</div>
Inline images
To place an image inline with text use either the .float-left
or .float-right
class.
<!-- !important: note the commas after each property -->
{% Img
class="float-right",
src="image/foR0vJZKULb5AGJExlazy1xYDgI2/w9i7lEqGw5J5b3jx5fAu.jpg",
alt="ALT_TEXT_HERE",
width="800",
height="450"
%}
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sint eaque iure eveniet assumenda ea natus perspiciatis, atque totam fugit labore amet facere, dignissimos sequi cumque repellat dolorum, quaerat voluptatibus sit!
Captions
To include a caption along with an image, use <figure>
with <figcaption>
and place the Img
shortcode snippet inside:
<figure>
{% Img src="image/foR0vJZKULb5AGJExlazy1xYDgI2/w9i7lEqGw5J5b3jx5fAu.jpg", alt="ALT_TEXT_HERE", width="800", height="450" %}
<figcaption>
A good boy.
</figcaption>
</figure>
Labels
Labels can be used to display a filename associated with a code snippet.
{% Label %}filename.js:{% endLabel %}
```js
console.log('hello');
```
console.log('hello');
Lists
See the Lists section of the Grammar, mechanics, and usage post for information about when to use each list type.
Use standard Markdown syntax for lists: 1.
for ordered lists and -
for unordered lists.
Ordered list
1. Lorem ipsum dolor sit amet…
1. Lorem ipsum dolor sit amet…
1. Lorem ipsum dolor sit amet…
- Lorem ipsum dolor sit amet…
- Lorem ipsum dolor sit amet…
- Lorem ipsum dolor sit amet…
Unordered list
- Lorem ipsum dolor sit amet…
- Lorem ipsum dolor sit amet…
- Lorem ipsum dolor sit amet…
- Lorem ipsum dolor sit amet…
- Lorem ipsum dolor sit amet…
- Lorem ipsum dolor sit amet…
Definition list
First Term
: This is the definition of the first term.
Second Term
: This is one definition of the second term.
: This is another definition of the second term.
- First Term
- This is the definition of the first term.
- Second Term
- This is one definition of the second term.
- This is another definition of the second term.
Partials
Use partials to reuse the same piece of content across a series of articles without having to rewrite it. Like a banner asking for feedback.
{% Partial 'devtools/banner.md' %}
Interested in helping improve DevTools? Sign up to participate in Google User Research here.
Tabs
Use web-tabs
component to display information in a form of horizontal tabs. Attribute title
becomes the title of the corresponding tab panel.
<web-tabs>
<web-tab title="Tab 1 (html)">
<p>I'm content of Tab 1</p>
</web-tab>
<web-tab title="Tab 2 (markdown)">
Here goes content of Tab 2. Now **with** some _markdown_.
You must include a line break between the html and markdown to get the
markdown to work (this is a limiation of markdown parsers).
</web-tab>
<web-tab title="Tab 3 (with code)">
This is Tab 3. It has a code snippet inside.
You must include a line break between the html and teh markdown to get the
markdown to work. Also, be sure to unindent the markdown otherwise syntax
highlighting will not work.
```js
const hello = 'world';
```
</web-tab>
</web-tabs>
I'm content of Tab 1
Here goes content of Tab 2. Now with some markdown.
You must include a line break between the html and markdown to get the markdown to work (this is a limiation of markdown parsers).
This is Tab 3. It has a code snippet inside.
You must include a line break between the html and teh markdown to get the markdown to work. Also, be sure to unindent the markdown otherwise syntax highlighting will not work.
const hello = 'world';
Tables
By default tables are only as wide as their content and are horizontally centered.
<table>
<thead>
<tr>
<th>Person</th>
…
</tr>
</thead>
<tr>
<td>Someone Lastname</td>
…
</tr>
</table>
Person | Number | Third Column |
---|---|---|
Someone Lastname | 900 | Nullam |
Person Name | 1200 | Vestibulum |
Another Person | 1500 | Vivamus |
Last One | 2800 | Morbi |
Tables with borders
To give a table vertical borders add the .with-borders
class.
<table class="with-borders">
<thead>
<tr>
<th>Person</th>
…
</tr>
</thead>
<tr>
<td>Someone Lastname</td>
…
</tr>
</table>
Person | Number | Third Column |
---|---|---|
Someone Lastname | 900 | Nullam |
Person Name | 1200 | Vestibulum |
Another Person | 1500 | Vivamus |
Last One | 2800 | Morbi |
Tables with tinted header
To give a table a tinted header add the .with-heading-tint
class.
<table class="with-heading-tint">
<thead>
<tr>
<th>Person</th>
…
</tr>
</thead>
<tr>
<td>Someone Lastname</td>
…
</tr>
</table>
Person | Number | Third Column |
---|---|---|
Someone Lastname | 900 | Nullam |
Person Name | 1200 | Vestibulum |
Another Person | 1500 | Vivamus |
Last One | 2800 | Morbi |
Tables with a caption
To give a table a caption add a <caption>
element.
<table>
<caption>Tables can have captions now.</caption>
<thead>
<tr>
<th>Person</th>
…
</tr>
</thead>
<tr>
<td>Someone Lastname</td>
…
</tr>
</table>
Person | Number | Third Column |
---|---|---|
Someone Lastname | 900 | Nullam quis risus eget urna mollis ornare vel eu leo. |
Person Name | 1200 | Vestibulum id ligula porta felis euismod semper. Donec ullamcorper nulla non metus auctor fringilla. |
Another Person | 1500 | Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nullam id dolor id nibh ultricies vehicula ut id elit. |
Last One | 2800 | Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Cras mattis consectetur purus sit amet fermentum. |
Full width tables
To make a table take up the full width add the width-full
class.
<table class="width-full">
<thead>
<tr>
<th>Person</th>
…
</tr>
</thead>
<tr>
<td>Someone Lastname</td>
…
</tr>
</table>
Person | Number | Third Column |
---|---|---|
Someone Lastname | 900 | Nullam quis risus eget urna mollis ornare vel eu leo. |
Person Name | 1200 | Vestibulum id ligula porta felis euismod semper. Donec ullamcorper nulla non metus auctor fringilla. |
Another Person | 1500 | Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nullam id dolor id nibh ultricies vehicula ut id elit. |
Last One | 2800 | Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Cras mattis consectetur purus sit amet fermentum. |
Non-overflowing tables
By default all tables will overflow-x
on small screens in order to be responsive. To prevent this from happening add the fixed-table
class.
<!-- Resize your screen and compare this table to the one above it. -->
<table class="fixed-table width-full">
<thead>
<tr>
<th>Person</th>
…
</tr>
</thead>
<tr>
<td>Someone Lastname</td>
…
</tr>
</table>
Person | Number | Third Column |
---|---|---|
Someone Lastname | 900 | Nullam quis risus eget urna mollis ornare vel eu leo. |
Person Name | 1200 | Vestibulum id ligula porta felis euismod semper. Donec ullamcorper nulla non metus auctor fringilla. |
Another Person | 1500 | Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nullam id dolor id nibh ultricies vehicula ut id elit. |
Last One | 2800 | Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Cras mattis consectetur purus sit amet fermentum. |
Video
Videos should always use the {% Video %}
shortcode. This shortcode will be generated for you when you upload your video to our CDN. See the Add an image or video guide for upload instructions.
{% Video src='video/tcFciHGuF3MxnTr1y5ue01OGLBn2/1601081394086.mp4' %}
Note that the video src
property can either be a string or an array of strings for multiple sources.
See the Add an image or video guide.
YouTube
Use the {% YouTube %}
shortcode to embed a YouTube video.
{% YouTube id="qPD2yc8BoDk" %}
<!-- You can pass an optional start time as well -->
{% YouTube id="qPD2yc8BoDk", startTime="1678" %}