blob: d8caf130d6a3c378da55916e19d8bedad0b83169 [file] [log] [blame]
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +00001<?xml version="1.0"?>
jensmeiert@google.com864b0dc2012-07-17 20:17:21 +00002<?xml-stylesheet type="text/xsl" href="styleguide.xsl"?>
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +00003<GUIDE title="Google HTML/CSS Style Guide">
4 <p class="revision">
5
mark@chromium.org5684bbc2013-07-12 18:53:13 +00006 Revision 2.23
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +00007 </p>
8
9 <OVERVIEW>
10 <CATEGORY title="Important Note">
mark@chromium.org8190c132013-03-21 16:03:26 +000011 <STYLEPOINT title="Displaying Hidden Details in This Guide">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +000012 <SUMMARY>
13 This style guide contains many details that are initially
14 hidden from view. They are marked by the triangle icon, which you
15 see here on your left. Click it now.
mark@chromium.org8190c132013-03-21 16:03:26 +000016 You should see “Hooray” appear below.
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +000017 </SUMMARY>
18 <BODY>
19 <p>
20 Hooray! Now you know you can expand points to get more
mark@chromium.org8190c132013-03-21 16:03:26 +000021 details. Alternatively, there’s a “toggle all” at the
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +000022 top of this document.
23 </p>
24 </BODY>
25 </STYLEPOINT>
26 </CATEGORY>
27 <CATEGORY title="Background">
28
29 <p>
30 This document defines formatting and style rules for HTML and
31 CSS. It aims at improving collaboration, code quality, and
32 enabling supporting infrastructure. It applies to raw,
33 working files that use HTML and CSS, including GSS
34 files. Tools are free to obfuscate, minify, and compile as
35 long as the general code quality is maintained.
36 </p>
37
38
39 </CATEGORY>
40 </OVERVIEW>
41
42 <CATEGORY title="General Style Rules">
43 <STYLEPOINT title="Protocol">
44 <SUMMARY>
45 Omit the protocol from embedded resources.
46 </SUMMARY>
47 <BODY>
48 <p>
49 Omit the protocol portion (<code>http:</code>,
50 <code>https:</code>) from URLs pointing to images and other
51 media files, style sheets, and scripts unless the respective
52 files are not available over both protocols.
53 </p>
54 <p>
mark@chromium.org8190c132013-03-21 16:03:26 +000055 Omitting the protocol—which makes the URL
56 relative—prevents mixed content issues and results in
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +000057 minor file size savings.
58 </p>
59 <BAD_CODE_SNIPPET>
60 &lt;!-- Not recommended --&gt;
61 &lt;script src="http://www.google.com/js/gweb/analytics/autotrack.js"&gt;&lt;/script&gt;
62 </BAD_CODE_SNIPPET>
63 <CODE_SNIPPET>
64 &lt;!-- Recommended --&gt;
65 &lt;script src="//www.google.com/js/gweb/analytics/autotrack.js"&gt;&lt;/script&gt;
66 </CODE_SNIPPET>
67 <BAD_CODE_SNIPPET>
68 /* Not recommended */
69 .example {
70 background: url(http://www.google.com/images/example);
71 }
72 </BAD_CODE_SNIPPET>
73 <CODE_SNIPPET>
74 /* Recommended */
75 .example {
76 background: url(//www.google.com/images/example);
77 }
78 </CODE_SNIPPET>
79 </BODY>
80 </STYLEPOINT>
81
82 </CATEGORY>
83
84 <CATEGORY title="General Formatting Rules">
85 <STYLEPOINT title="Indentation">
86 <SUMMARY>
87 Indent by 2 spaces at a time.
88 </SUMMARY>
89 <BODY>
90 <p>
mark@chromium.org8190c132013-03-21 16:03:26 +000091 Don’t use tabs or mix tabs and spaces for indentation.
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +000092 </p>
93 <CODE_SNIPPET>
94 &lt;ul&gt;
95 &lt;li&gt;Fantastic
96 &lt;li&gt;Great
97 &lt;/ul&gt;
98 </CODE_SNIPPET>
99 <CODE_SNIPPET>
100 .example {
101 color: blue;
102 }
103 </CODE_SNIPPET>
104 </BODY>
105 </STYLEPOINT>
106 <STYLEPOINT title="Capitalization">
107 <SUMMARY>
108 Use only lowercase.
109 </SUMMARY>
110 <BODY>
111 <p>
mark@chromium.org8190c132013-03-21 16:03:26 +0000112 All code has to be lowercase: This applies to HTML element names,
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000113 attributes, attribute values (unless
mark@chromium.org8190c132013-03-21 16:03:26 +0000114 <code>text/CDATA</code>), CSS selectors, properties, and
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000115 property values (with the exception of strings).
116 </p>
117 <BAD_CODE_SNIPPET>
118 &lt;!-- Not recommended --&gt;
119 &lt;A HREF="/"&gt;Home&lt;/A&gt;
120 </BAD_CODE_SNIPPET>
121 <CODE_SNIPPET>
122 &lt;!-- Recommended --&gt;
123 &lt;img src="google.png" alt="Google"&gt;
124 </CODE_SNIPPET>
mark@chromium.org8190c132013-03-21 16:03:26 +0000125 <BAD_CODE_SNIPPET>
126 /* Not recommended */
127 color: #E5E5E5;
128 </BAD_CODE_SNIPPET>
129 <CODE_SNIPPET>
130 /* Recommended */
131 color: #e5e5e5;
132 </CODE_SNIPPET>
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000133 </BODY>
134 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000135 <STYLEPOINT title="Trailing Whitespace">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000136 <SUMMARY>
137 Remove trailing white spaces.
138 </SUMMARY>
139 <BODY>
140 <p>
141 Trailing white spaces are unnecessary and can complicate
142 diffs.
143 </p>
144 <BAD_CODE_SNIPPET>
145 &lt;!-- Not recommended --&gt;
146 &lt;p&gt;What?_
147 </BAD_CODE_SNIPPET>
148 <CODE_SNIPPET>
149 &lt;!-- Recommended --&gt;
150 &lt;p&gt;Yes please.
151 </CODE_SNIPPET>
152 </BODY>
153 </STYLEPOINT>
154 </CATEGORY>
155
156 <CATEGORY title="General Meta Rules">
157 <STYLEPOINT title="Encoding">
158 <SUMMARY>
159 Use UTF-8 (no BOM).
160 </SUMMARY>
161 <BODY>
162 <p>
163 Make sure your editor uses UTF-8 as character encoding,
164 without a byte order mark.
165 </p>
166 <p>
167 Specify the encoding in HTML templates and documents via
168 <code>&lt;meta charset="utf-8"&gt;</code>. Do not specify
169 the encoding of style sheets as these assume UTF-8.
170 </p>
171 <p>
172 (More on encodings and when and how to specify them can be
mark@chromium.orgc8c76a22012-11-28 20:26:27 +0000173 found in <a href="http://www.w3.org/International/tutorials/tutorial-char-enc/">Handling
174 character encodings in HTML and CSS</a>.)
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000175 </p>
176 </BODY>
177 </STYLEPOINT>
178 <STYLEPOINT title="Comments">
179 <SUMMARY>
180 Explain code as needed, where possible.
181 </SUMMARY>
182 <BODY>
183 <p>
jensmeiert@google.com1e1b50b2012-07-17 20:12:10 +0000184 Use comments to explain code: What does it cover, what
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000185 purpose does it serve, why is respective solution used or
186 preferred?
187 </p>
188 <p>
189 (This item is optional as it is not deemed a realistic
190 expectation to always demand fully documented code. Mileage
191 may vary heavily for HTML and CSS code and depends on the
mark@chromium.org8190c132013-03-21 16:03:26 +0000192 project’s complexity.)
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000193 </p>
194 </BODY>
195 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000196 <STYLEPOINT title="Action Items">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000197 <SUMMARY>
198 Mark todos and action items with <code>TODO</code>.
199 </SUMMARY>
200 <BODY>
201 <p>
202 Highlight todos by using the keyword <code>TODO</code> only,
203 not other common formats like <code>@@</code>.
204 </p>
205 <p>
206 Append a contact (username or mailing list) in parentheses
207 as with the format <code>TODO(contact)</code>.
208 </p>
209 <p>
210 Append action items after a colon as in <code>TODO: action
211 item</code>.
212 </p>
213
214 <CODE_SNIPPET>
215 {# TODO(john.doe): revisit centering #}
216 &lt;center&gt;Test&lt;/center&gt;
217 </CODE_SNIPPET>
218
219 <CODE_SNIPPET>
220 &lt;!-- TODO: remove optional tags --&gt;
221 &lt;ul&gt;
222 &lt;li&gt;Apples&lt;/li&gt;
223 &lt;li&gt;Oranges&lt;/li&gt;
224 &lt;/ul&gt;
225 </CODE_SNIPPET>
226 </BODY>
227 </STYLEPOINT>
228 </CATEGORY>
229
230 <CATEGORY title="HTML Style Rules">
mark@chromium.org8190c132013-03-21 16:03:26 +0000231 <STYLEPOINT title="Document Type">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000232 <SUMMARY>
233 Use HTML5.
234 </SUMMARY>
235 <BODY>
236 <p>
237 HTML5 (HTML syntax) is preferred for all HTML documents:
238 <code>&lt;!DOCTYPE html&gt;</code>.
239 </p>
240 <p>
mark@chromium.org8190c132013-03-21 16:03:26 +0000241 (It’s recommended to use HTML, as <code>text/html</code>. Do not use
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000242 XHTML. XHTML, as <a href="http://hixie.ch/advocacy/xhtml"><code>application/xhtml+xml</code></a>,
243 lacks both browser and infrastructure support and offers
244 less room for optimization than HTML.)
245 </p>
jensmeiert@google.com1e1b50b2012-07-17 20:12:10 +0000246 <p>
247 Although fine with HTML, do not close void elements, i.e. write
248 <code>&lt;br&gt;</code>, not <code>&lt;br /&gt;</code>.
249 </p>
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000250 </BODY>
251 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000252 <STYLEPOINT title="HTML Validity">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000253 <SUMMARY>
254 Use valid HTML where possible.
255 </SUMMARY>
256 <BODY>
257 <p>
258 Use valid HTML code unless that is not possible due to
259 otherwise unattainable performance goals regarding file size.
260 </p>
261
262 <p>
mark@chromium.org8190c132013-03-21 16:03:26 +0000263 Use tools such as the <a href="http://validator.w3.org/nu/">W3C
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000264 HTML validator</a> to test.
265 </p>
266 <p>
267 Using valid HTML is a measurable baseline quality attribute
268 that contributes to learning about technical requirements
269 and constraints, and that ensures proper HTML usage.
270 </p>
271 <BAD_CODE_SNIPPET>
272 &lt;!-- Not recommended --&gt;
273 &lt;title&gt;Test&lt;/title&gt;
274 &lt;article&gt;This is only a test.
275 </BAD_CODE_SNIPPET>
276 <CODE_SNIPPET>
277 &lt;!-- Recommended --&gt;
278 &lt;!DOCTYPE html&gt;
279 &lt;meta charset="utf-8"&gt;
280 &lt;title&gt;Test&lt;/title&gt;
281 &lt;article&gt;This is only a test.&lt;/article&gt;
282 </CODE_SNIPPET>
283 </BODY>
284 </STYLEPOINT>
285 <STYLEPOINT title="Semantics">
286 <SUMMARY>
287 Use HTML according to its purpose.
288 </SUMMARY>
289 <BODY>
290 <p>
mark@chromium.org8190c132013-03-21 16:03:26 +0000291 Use elements (sometimes incorrectly called “tags”) for what
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000292 they have been created for. For example, use heading
293 elements for headings, <code>p</code> elements for
294 paragraphs, <code>a</code> elements for anchors, etc.
295 </p>
296 <p>
297 Using HTML according to its purpose is important for
298 accessibility, reuse, and code efficiency reasons.
299 </p>
300
301 <BAD_CODE_SNIPPET>
302 &lt;!-- Not recommended --&gt;
303 &lt;div onclick="goToRecommendations();"&gt;All recommendations&lt;/div&gt;
304 </BAD_CODE_SNIPPET>
305 <CODE_SNIPPET>
306 &lt;!-- Recommended --&gt;
307 &lt;a href="recommendations/"&gt;All recommendations&lt;/a&gt;
308 </CODE_SNIPPET>
309 </BODY>
310 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000311 <STYLEPOINT title="Multimedia Fallback">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000312 <SUMMARY>
313 Provide alternative contents for multimedia.
314 </SUMMARY>
315 <BODY>
316 <p>
317 For multimedia, such as images, videos, animated objects via
318 <code>canvas</code>, make sure to offer alternative
319 access. For images that means use of meaningful alternative
320 text (<code>alt</code>) and for video and audio transcripts
321 and captions, if available.
322 </p>
323 <p>
324 Providing alternative contents is important for
jensmeiert@google.com1e1b50b2012-07-17 20:12:10 +0000325 accessibility reasons: A blind user has few cues to tell
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000326 what an image is about without <code>@alt</code>, and other
327 users may have no way of understanding what video or audio
328 contents are about either.
329 </p>
330 <p>
331 (For images whose <code>alt</code> attributes would
332 introduce redundancy, and for images whose purpose is purely
333 decorative which you cannot immediately use CSS for, use no
334 alternative text, as in <code>alt=""</code>.)
335 </p>
336
337 <BAD_CODE_SNIPPET>
338 &lt;!-- Not recommended --&gt;
339 &lt;img src="spreadsheet.png"&gt;
340 </BAD_CODE_SNIPPET>
341 <CODE_SNIPPET>
342 &lt;!-- Recommended --&gt;
343 &lt;img src="spreadsheet.png" alt="Spreadsheet screenshot."&gt;
344 </CODE_SNIPPET>
345 </BODY>
346 </STYLEPOINT>
347
mark@chromium.org8190c132013-03-21 16:03:26 +0000348 <STYLEPOINT title="Separation of Concerns">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000349 <SUMMARY>
350 Separate structure from presentation from behavior.
351 </SUMMARY>
352 <BODY>
353 <p>
354 Strictly keep structure (markup), presentation (styling),
355 and behavior (scripting) apart, and try to keep the
356 interaction between the three to an absolute minimum.
357 </p>
358 <p>
359 That is, make sure documents and templates contain only HTML
360 and HTML that is solely serving structural purposes. Move
361 everything presentational into style sheets, and everything
362 behavioral into scripts.
363 </p>
364 <p>
365 In addition, keep the contact area as small as possible by
366 linking as few style sheets and scripts as possible from
367 documents and templates.
368 </p>
369 <p>
370 Separating structure from presentation from behavior is
371 important for maintenance reasons. It is always more
372 expensive to change HTML documents and templates than it is
373 to update style sheets and scripts.
374 </p>
375
376 <BAD_CODE_SNIPPET>
377 &lt;!-- Not recommended --&gt;
378 &lt;!DOCTYPE html&gt;
379 &lt;title&gt;HTML sucks&lt;/title&gt;
380 &lt;link rel="stylesheet" href="base.css" media="screen"&gt;
381 &lt;link rel="stylesheet" href="grid.css" media="screen"&gt;
382 &lt;link rel="stylesheet" href="print.css" media="print"&gt;
383 &lt;h1 style="font-size: 1em;"&gt;HTML sucks&lt;/h1&gt;
mark@chromium.org8190c132013-03-21 16:03:26 +0000384 &lt;p&gt;I’ve read about this on a few sites but now I’m sure:
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000385 &lt;u&gt;HTML is stupid!!1&lt;/u&gt;
mark@chromium.org8190c132013-03-21 16:03:26 +0000386 &lt;center&gt;I can’t believe there’s no way to control the styling of
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000387 my website without doing everything all over again!&lt;/center&gt;
388 </BAD_CODE_SNIPPET>
389 <CODE_SNIPPET>
390 &lt;!-- Recommended --&gt;
391 &lt;!DOCTYPE html&gt;
392 &lt;title&gt;My first CSS-only redesign&lt;/title&gt;
393 &lt;link rel="stylesheet" href="default.css"&gt;
394 &lt;h1&gt;My first CSS-only redesign&lt;/h1&gt;
mark@chromium.org8190c132013-03-21 16:03:26 +0000395 &lt;p&gt;I’ve read about this on a few sites but today I’m actually
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000396 doing it: separating concerns and avoiding anything in the HTML of
397 my website that is presentational.
mark@chromium.org8190c132013-03-21 16:03:26 +0000398 &lt;p&gt;It’s awesome!
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000399 </CODE_SNIPPET>
400 </BODY>
401 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000402 <STYLEPOINT title="Entity References">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000403 <SUMMARY>
404 Do not use entity references.
405 </SUMMARY>
406 <BODY>
407 <p>
408 There is no need to use entity references like
409 <code>&amp;mdash;</code>, <code>&amp;rdquo;</code>, or
410 <code>&amp;#x263a;</code>, assuming the same encoding
411 (UTF-8) is used for files and editors as well as among
412 teams.
413 </p>
414 <p>
415 The only exceptions apply to characters with special meaning
416 in HTML (like <code>&lt;</code> and <code>&amp;</code>) as
mark@chromium.org8190c132013-03-21 16:03:26 +0000417 well as control or “invisible” characters (like no-break
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000418 spaces).
419 </p>
420 <BAD_CODE_SNIPPET>
421 &lt;!-- Not recommended --&gt;
422 The currency symbol for the Euro is &amp;ldquo;&amp;eur;&amp;rdquo;.
423 </BAD_CODE_SNIPPET>
424 <CODE_SNIPPET>
425 &lt;!-- Recommended --&gt;
mark@chromium.org8190c132013-03-21 16:03:26 +0000426 The currency symbol for the Euro is “€”.
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000427 </CODE_SNIPPET>
428 </BODY>
429 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000430 <STYLEPOINT title="Optional Tags">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000431 <SUMMARY>
432 Omit optional tags (optional).
433 </SUMMARY>
434 <BODY>
435 <p>
436 For file size optimization and scannability purposes,
437 consider omitting optional tags.
438 The <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#syntax-tag-omission">HTML5
439 specification</a> defines what tags can be omitted.
440 </p>
441 <p>
442 (This approach may require a grace period to be established
mark@chromium.org8190c132013-03-21 16:03:26 +0000443 as a wider guideline as it’s significantly different
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000444 from what web developers are typically taught. For
mark@chromium.org8190c132013-03-21 16:03:26 +0000445 consistency and simplicity reasons it’s best served
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000446 omitting all optional tags, not just a selection.)
447 </p>
448 <BAD_CODE_SNIPPET>
449 &lt;!-- Not recommended --&gt;
450 &lt;!DOCTYPE html&gt;
451 &lt;html&gt;
452 &lt;head&gt;
453 &lt;title&gt;Spending money, spending bytes&lt;/title&gt;
454 &lt;/head&gt;
455 &lt;body&gt;
456 &lt;p&gt;Sic.&lt;/p&gt;
457 &lt;/body&gt;
458 &lt;/html&gt;
459 </BAD_CODE_SNIPPET>
460 <CODE_SNIPPET>
461 &lt;!-- Recommended --&gt;
462 &lt;!DOCTYPE html&gt;
463 &lt;title&gt;Saving money, saving bytes&lt;/title&gt;
464 &lt;p&gt;Qed.
465 </CODE_SNIPPET>
466 </BODY>
467 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000468 <STYLEPOINT title="type Attributes">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000469 <SUMMARY>
470 Omit <code>type</code> attributes for style sheets and scripts.
471 </SUMMARY>
472 <BODY>
473 <p>
474 Do not use <code>type</code> attributes for style sheets
475 (unless not using CSS) and scripts (unless not using
476 JavaScript).
477 </p>
478 <p>
479 Specifying <code>type</code> attributes in these contexts is
480 not necessary as HTML5 implies
481 <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/semantics.html#attr-style-type"><code>text/css</code></a>
482 and
483 <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#attr-script-type"><code>text/javascript</code></a>
484 as defaults. This can be safely done even for older browsers.
485 </p>
486 <BAD_CODE_SNIPPET>
487 &lt;!-- Not recommended --&gt;
488 &lt;link rel="stylesheet" href="//www.google.com/css/maia.css"
489 type="text/css"&gt;
490 </BAD_CODE_SNIPPET>
491 <CODE_SNIPPET>
492 &lt;!-- Recommended --&gt;
493 &lt;link rel="stylesheet" href="//www.google.com/css/maia.css"&gt;
494 </CODE_SNIPPET>
495 <BAD_CODE_SNIPPET>
496 &lt;!-- Not recommended --&gt;
497 &lt;script src="//www.google.com/js/gweb/analytics/autotrack.js"
498 type="text/javascript"&gt;&lt;/script&gt;
499 </BAD_CODE_SNIPPET>
500 <CODE_SNIPPET>
501 &lt;!-- Recommended --&gt;
502 &lt;script src="//www.google.com/js/gweb/analytics/autotrack.js"&gt;&lt;/script&gt;
503 </CODE_SNIPPET>
504 </BODY>
505 </STYLEPOINT>
506 </CATEGORY>
507
508 <CATEGORY title="HTML Formatting Rules">
mark@chromium.org8190c132013-03-21 16:03:26 +0000509 <STYLEPOINT title="General Formatting">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000510 <SUMMARY>
511 Use a new line for every block, list, or table element, and
512 indent every such child element.
513 </SUMMARY>
514 <BODY>
515 <p>
516 Independent of the styling of an element (as CSS allows
517 elements to assume a different role per <code>display</code>
518 property), put every block, list, or table element on a new
519 line.
520 </p>
521 <p>
522 Also, indent them if they are child elements of a block,
523 list, or table element.
524 </p>
525 <p>
526 (If you run into issues around whitespace between list items
mark@chromium.org8190c132013-03-21 16:03:26 +0000527 it’s acceptable to put all <code>li</code> elements in one
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000528 line. A linter is encouraged to throw a warning instead of
529 an error.)
530 </p>
531 <CODE_SNIPPET>
532 &lt;blockquote&gt;
533 &lt;p&gt;&lt;em&gt;Space&lt;/em&gt;, the final frontier.&lt;/p&gt;
534 &lt;/blockquote&gt;
535 </CODE_SNIPPET>
536 <CODE_SNIPPET>
537 &lt;ul&gt;
538 &lt;li&gt;Moe
539 &lt;li&gt;Larry
540 &lt;li&gt;Curly
541 &lt;/ul&gt;
542 </CODE_SNIPPET>
543 <CODE_SNIPPET>
544 &lt;table&gt;
545 &lt;thead&gt;
546 &lt;tr&gt;
547 &lt;th scope="col"&gt;Income
548 &lt;th scope="col"&gt;Taxes
549 &lt;tbody&gt;
550 &lt;tr&gt;
551 &lt;td&gt;$ 5.00
552 &lt;td&gt;$ 4.50
553 &lt;/table&gt;
554 </CODE_SNIPPET>
555 </BODY>
556 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000557 <STYLEPOINT title="HTML Quotation Marks">
jensmeiert@google.com1e1b50b2012-07-17 20:12:10 +0000558 <SUMMARY>
mark@chromium.orgc8c76a22012-11-28 20:26:27 +0000559 When quoting attributes values, use double quotation marks.
jensmeiert@google.com1e1b50b2012-07-17 20:12:10 +0000560 </SUMMARY>
561 <BODY>
562 <p>
mark@chromium.orgc8c76a22012-11-28 20:26:27 +0000563 Use double (<code>""</code>) rather than single quotation marks
564 (<code>''</code>) around attribute values.
jensmeiert@google.com1e1b50b2012-07-17 20:12:10 +0000565 </p>
566 <BAD_CODE_SNIPPET>
567 &lt;!-- Not recommended --&gt;
568 &lt;a class='maia-button maia-button-secondary'&gt;Sign in&lt;/a&gt;
569 </BAD_CODE_SNIPPET>
570 <CODE_SNIPPET>
571 &lt;!-- Recommended --&gt;
572 &lt;a class="maia-button maia-button-secondary"&gt;Sign in&lt;/a&gt;
573 </CODE_SNIPPET>
574 </BODY>
575 </STYLEPOINT>
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000576 </CATEGORY>
577
578 <CATEGORY title="CSS Style Rules">
mark@chromium.org8190c132013-03-21 16:03:26 +0000579 <STYLEPOINT title="CSS Validity">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000580 <SUMMARY>
581 Use valid CSS where possible.
582 </SUMMARY>
583 <BODY>
584 <p>
585 Unless dealing with CSS validator bugs or requiring
586 proprietary syntax, use valid CSS code.
587 </p>
588
589 <p>
mark@chromium.org8190c132013-03-21 16:03:26 +0000590 Use tools such as the <a href="http://jigsaw.w3.org/css-validator/">W3C
mark@chromium.orgc8c76a22012-11-28 20:26:27 +0000591 CSS validator</a> to test.
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000592 </p>
593 <p>
594 Using valid CSS is a measurable baseline quality attribute
595 that allows to spot CSS code that may not have any effect
596 and can be removed, and that ensures proper CSS usage.
597 </p>
598 </BODY>
599 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000600 <STYLEPOINT title="ID and Class Naming">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000601 <SUMMARY>
602 Use meaningful or generic ID and class names.
603 </SUMMARY>
604 <BODY>
605 <p>
606 Instead of presentational or cryptic names, always use ID
607 and class names that reflect the purpose of the element in
608 question, or that are otherwise generic.
609 </p>
610 <p>
611 Names that are specific and reflect the purpose of the
612 element should be preferred as these are most understandable
613 and the least likely to change.
614 </p>
615 <p>
616 Generic names are simply a fallback for elements that have no
617 particular or no meaning different from their siblings. They are
mark@chromium.org8190c132013-03-21 16:03:26 +0000618 typically needed as “helpers.”
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000619 </p>
620 <p>
621 Using functional or generic names reduces the probability of
622 unnecessary document or template changes.
623 </p>
624 <BAD_CODE_SNIPPET>
625 /* Not recommended: meaningless */
626 #yee-1901 {}
627
628 /* Not recommended: presentational */
629 .button-green {}
630 .clear {}
631 </BAD_CODE_SNIPPET>
632 <CODE_SNIPPET>
633 /* Recommended: specific */
634 #gallery {}
635 #login {}
636 .video {}
637
638 /* Recommended: generic */
639 .aux {}
640 .alt {}
641 </CODE_SNIPPET>
642 </BODY>
643 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000644 <STYLEPOINT title="ID and Class Name Style">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000645 <SUMMARY>
646 Use ID and class names that are as short as possible but as long as
647 necessary.
648 </SUMMARY>
649 <BODY>
650 <p>
651 Try to convey what an ID or class is about while being as
652 brief as possible.
653 </p>
654 <p>
655 Using ID and class names this way contributes to acceptable
656 levels of understandability and code efficiency.
657 </p>
658 <BAD_CODE_SNIPPET>
659 /* Not recommended */
660 #navigation {}
661 .atr {}
662 </BAD_CODE_SNIPPET>
663 <CODE_SNIPPET>
664 /* Recommended */
665 #nav {}
666 .author {}
667 </CODE_SNIPPET>
668 </BODY>
669 </STYLEPOINT>
670
mark@chromium.org8190c132013-03-21 16:03:26 +0000671 <STYLEPOINT title="Type Selectors">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000672 <SUMMARY>
673 Avoid qualifying ID and class names with type selectors.
674 </SUMMARY>
675 <BODY>
676 <p>Unless necessary (for example with helper classes), do not
677 use element names in conjunction with IDs or classes.
678 </p>
679 <p>
mark@chromium.org8190c132013-03-21 16:03:26 +0000680 Avoiding unnecessary ancestor selectors is useful for <a href="http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/">performance
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000681 reasons</a>.
682 </p>
683 <BAD_CODE_SNIPPET>
684 /* Not recommended */
685 ul#example {}
686 div.error {}
687 </BAD_CODE_SNIPPET>
688 <CODE_SNIPPET>
689 /* Recommended */
690 #example {}
691 .error {}
692 </CODE_SNIPPET>
693 </BODY>
694 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000695 <STYLEPOINT title="Shorthand Properties">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000696 <SUMMARY>
697 Use shorthand properties where possible.
698 </SUMMARY>
699 <BODY>
700 <p>
mark@chromium.org8190c132013-03-21 16:03:26 +0000701 CSS offers a variety of <a href="http://www.w3.org/TR/CSS21/about.html#shorthand">shorthand</a>
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000702 properties (like <code>font</code>)
703 that should be used whenever possible, even in cases where
704 only one value is explicitly set.
705 </p>
706 <p>
707 Using shorthand properties is useful for code efficiency and
708 understandability.
709 </p>
710 <BAD_CODE_SNIPPET>
711 /* Not recommended */
712 border-top-style: none;
713 font-family: palatino, georgia, serif;
714 font-size: 100%;
715 line-height: 1.6;
716 padding-bottom: 2em;
717 padding-left: 1em;
718 padding-right: 1em;
719 padding-top: 0;
720 </BAD_CODE_SNIPPET>
721 <CODE_SNIPPET>
722 /* Recommended */
723 border-top: 0;
724 font: 100%/1.6 palatino, georgia, serif;
725 padding: 0 1em 2em;
726 </CODE_SNIPPET>
727 </BODY>
728 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000729 <STYLEPOINT title="0 and Units">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000730 <SUMMARY>
mark@chromium.org8190c132013-03-21 16:03:26 +0000731 Omit unit specification after “0” values.
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000732 </SUMMARY>
733 <BODY>
734 <p>
735 Do not use units after <code>0</code> values unless they are
736 required.
737 </p>
738 <CODE_SNIPPET>
739 margin: 0;
740 padding: 0;
741 </CODE_SNIPPET>
742 </BODY>
743 </STYLEPOINT>
744 <STYLEPOINT title="Leading 0s">
745 <SUMMARY>
mark@chromium.org8190c132013-03-21 16:03:26 +0000746 Omit leading “0”s in values.
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000747 </SUMMARY>
748 <BODY>
749 <p>
750 Do not use put <code>0</code>s in front of values or lengths
751 between -1 and 1.
752 </p>
753 <CODE_SNIPPET>
754 font-size: .8em;
755 </CODE_SNIPPET>
756 </BODY>
757 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000758 <STYLEPOINT title="Hexadecimal Notation">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000759 <SUMMARY>
760 Use 3 character hexadecimal notation where possible.
761 </SUMMARY>
762 <BODY>
763 <p>
764 For color values that permit it, 3 character hexadecimal
765 notation is shorter and more succinct.
766 </p>
767 <BAD_CODE_SNIPPET>
768 /* Not recommended */
769 color: #eebbcc;
770 </BAD_CODE_SNIPPET>
771 <CODE_SNIPPET>
772 /* Recommended */
773 color: #ebc;
774 </CODE_SNIPPET>
775 </BODY>
776 </STYLEPOINT>
777 <STYLEPOINT title="Prefixes">
778 <SUMMARY>
779 Prefix selectors with an application-specific prefix (optional).
780 </SUMMARY>
781 <BODY>
782 <p>
783 In large projects as well as for code that gets embedded in
784 other projects or on external sites use prefixes (as
785 namespaces) for ID and class names. Use short, unique
786 identifiers followed by a dash.
787 </p>
788
789
790 <p>
791 Using namespaces helps preventing naming conflicts and can
792 make maintenance easier, for example in search and replace
793 operations.
794 </p>
795 <CODE_SNIPPET>
796 .adw-help {} /* AdWords */
797 #maia-note {} /* Maia */
798 </CODE_SNIPPET>
799 </BODY>
800 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000801 <STYLEPOINT title="ID and Class Name Delimiters">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000802 <SUMMARY>
803 Separate words in ID and class names by a hyphen.
804 </SUMMARY>
805 <BODY>
806 <p>
807 Do not concatenate words and abbreviations in selectors by
808 any characters (including none at all) other than hyphens,
809 in order to improve understanding and scannability.
810 </p>
811 <BAD_CODE_SNIPPET>
mark@chromium.org8190c132013-03-21 16:03:26 +0000812 /* Not recommended: does not separate the words “demo” and “image” */
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000813 .demoimage {}
814
815 /* Not recommended: uses underscore instead of hyphen */
816 .error_status {}
817 </BAD_CODE_SNIPPET>
818 <CODE_SNIPPET>
819 /* Recommended */
820 #video-id {}
821 .ads-sample {}
822 </CODE_SNIPPET>
823 </BODY>
824 </STYLEPOINT>
825 <STYLEPOINT title="Hacks">
826 <SUMMARY>
mark@chromium.org8190c132013-03-21 16:03:26 +0000827 Avoid user agent detection as well as CSS “hacks”—try a different
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000828 approach first.
829 </SUMMARY>
830 <BODY>
831 <p>
mark@chromium.org8190c132013-03-21 16:03:26 +0000832 It’s tempting to address styling differences over user
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000833 agent detection or special CSS filters, workarounds, and
834 hacks. Both approaches should be considered last resort in
835 order to achieve and maintain an efficient and manageable
836 code base. Put another way, giving detection and hacks a
837 free pass will hurt projects in the long run as projects
838 tend to take the way of least resistance. That is, allowing
839 and making it easy to use detection and hacks means using
mark@chromium.org8190c132013-03-21 16:03:26 +0000840 detection and hacks more frequently—and more frequently
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000841 is too frequently.
842 </p>
843
844
845 </BODY>
846 </STYLEPOINT>
847 </CATEGORY>
848
849 <CATEGORY title="CSS Formatting Rules">
mark@chromium.org8190c132013-03-21 16:03:26 +0000850 <STYLEPOINT title="Declaration Order">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000851 <SUMMARY>
852 Alphabetize declarations.
853 </SUMMARY>
854 <BODY>
855 <p>
856 Put declarations in alphabetical order in order to achieve
857 consistent code in a way that is easy to remember and
858 maintain.
859 </p>
860 <p>
861 Ignore vendor-specific prefixes for sorting purposes. However,
862 multiple vendor-specific prefixes for a certain CSS property should
863 be kept sorted (e.g. -moz prefix comes before -webkit).
864 </p>
865 <CODE_SNIPPET>
866 background: fuchsia;
867 border: 1px solid;
868 -moz-border-radius: 4px;
869 -webkit-border-radius: 4px;
870 border-radius: 4px;
871 color: black;
872 text-align: center;
873 text-indent: 2em;
874 </CODE_SNIPPET>
875 </BODY>
876 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000877 <STYLEPOINT title="Block Content Indentation">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000878 <SUMMARY>
879 Indent all block content.
880 </SUMMARY>
881 <BODY>
882 <p>
883 Indent all <a href="http://www.w3.org/TR/CSS21/syndata.html#block">block
884 content</a>, that is rules within rules as well as declarations, so to
885 reflect hierarchy and improve understanding.
886 </p>
887 <CODE_SNIPPET>
888 @media screen, projection {
889
890 html {
891 background: #fff;
892 color: #444;
893 }
894
895 }
896 </CODE_SNIPPET>
897 </BODY>
898 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000899 <STYLEPOINT title="Declaration Stops">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000900 <SUMMARY>
901 Use a semicolon after every declaration.
902 </SUMMARY>
903 <BODY>
904 <p>
905 End every declaration with a semicolon for consistency and
906 extensibility reasons.
907 </p>
908 <BAD_CODE_SNIPPET>
909 /* Not recommended */
910 .test {
911 display: block;
912 height: 100px
913 }
914 </BAD_CODE_SNIPPET>
915 <CODE_SNIPPET>
916 /* Recommended */
917 .test {
918 display: block;
919 height: 100px;
920 }
921 </CODE_SNIPPET>
922 </BODY>
923 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000924 <STYLEPOINT title="Property Name Stops">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000925 <SUMMARY>
mark@chromium.org8190c132013-03-21 16:03:26 +0000926 Use a space after a property name’s colon.
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000927 </SUMMARY>
928 <BODY>
929 <p>
930 Always use a single space between property and value (but no
931 space between property and colon) for consistency reasons.
932 </p>
933 <BAD_CODE_SNIPPET>
934 /* Not recommended */
935 h3 {
936 font-weight:bold;
937 }
938 </BAD_CODE_SNIPPET>
939 <CODE_SNIPPET>
940 /* Recommended */
941 h3 {
942 font-weight: bold;
943 }
944 </CODE_SNIPPET>
945 </BODY>
946 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +0000947 <STYLEPOINT title="Declaration Block Separation">
948 <SUMMARY>
949 Use a space between the last selector and the declaration block.
950 </SUMMARY>
951 <BODY>
952 <p>
953 Always use a single space between the last selector and the opening
954 brace that begins the <a href="http://www.w3.org/TR/CSS21/syndata.html#rule-sets">declaration
955 block</a>.
956 </p>
957 <p>
958 The opening brace should be on the same line as the last selector in a
959 given rule.
960 </p>
961 <BAD_CODE_SNIPPET>
962 /* Not recommended: missing space */
963 #video{
964 margin-top: 1em;
965 }
966
967 /* Not recommended: unnecessary line break */
968 #video
969 {
970 margin-top: 1em;
971 }
972 </BAD_CODE_SNIPPET>
973 <CODE_SNIPPET>
974 /* Recommended */
975 #video {
976 margin-top: 1em;
977 }
978 </CODE_SNIPPET>
979 </BODY>
980 </STYLEPOINT>
981 <STYLEPOINT title="Selector and Declaration Separation">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +0000982 <SUMMARY>
983 Separate selectors and declarations by new lines.
984 </SUMMARY>
985 <BODY>
986 <p>
987 Always start a new line for each selector and declaration.
988 </p>
989 <BAD_CODE_SNIPPET>
990 /* Not recommended */
991 a:focus, a:active {
992 position: relative; top: 1px;
993 }
994 </BAD_CODE_SNIPPET>
995 <CODE_SNIPPET>
996 /* Recommended */
997 h1,
998 h2,
999 h3 {
1000 font-weight: normal;
1001 line-height: 1.2;
1002 }
1003 </CODE_SNIPPET>
1004 </BODY>
1005 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +00001006 <STYLEPOINT title="Rule Separation">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +00001007 <SUMMARY>
1008 Separate rules by new lines.
1009 </SUMMARY>
1010 <BODY>
1011 <p>
mark@chromium.org8190c132013-03-21 16:03:26 +00001012 Always put a blank line (two line breaks) between rules.
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +00001013 </p>
1014 <CODE_SNIPPET>
1015 html {
1016 background: #fff;
1017 }
1018
1019 body {
1020 margin: auto;
1021 width: 50%;
1022 }
1023 </CODE_SNIPPET>
1024 </BODY>
1025 </STYLEPOINT>
mark@chromium.org8190c132013-03-21 16:03:26 +00001026 <STYLEPOINT title="CSS Quotation Marks">
jensmeiert@google.com1e1b50b2012-07-17 20:12:10 +00001027 <SUMMARY>
mark@chromium.orgc8c76a22012-11-28 20:26:27 +00001028 Use single quotation marks for attribute selectors and property values.
jensmeiert@google.com1e1b50b2012-07-17 20:12:10 +00001029 </SUMMARY>
1030 <BODY>
1031 <p>
mark@chromium.orgc8c76a22012-11-28 20:26:27 +00001032 Use single (<code>''</code>) rather than double (<code>""</code>)
1033 quotation marks for attribute selectors or property values. Do not
1034 use quotation marks in URI values (<code>url()</code>).
1035 </p>
1036 <p>
1037 Exception: If you do need to use the <code>@charset</code> rule,
mark@chromium.org8190c132013-03-21 16:03:26 +00001038 use double quotation marks—<a href="http://www.w3.org/TR/CSS21/syndata.html#charset">single
mark@chromium.orgc8c76a22012-11-28 20:26:27 +00001039 quotation marks are not permitted</a>.
jensmeiert@google.com1e1b50b2012-07-17 20:12:10 +00001040 </p>
1041 <BAD_CODE_SNIPPET>
1042 /* Not recommended */
1043 @import url("//www.google.com/css/maia.css");
1044
1045 html {
1046 font-family: "open sans", arial, sans-serif;
1047 }
1048 </BAD_CODE_SNIPPET>
1049 <CODE_SNIPPET>
1050 /* Recommended */
1051 @import url(//www.google.com/css/maia.css);
1052
1053 html {
1054 font-family: 'open sans', arial, sans-serif;
1055 }
1056 </CODE_SNIPPET>
1057 </BODY>
1058 </STYLEPOINT>
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +00001059 </CATEGORY>
1060
1061 <CATEGORY title="CSS Meta Rules">
1062
mark@chromium.org8190c132013-03-21 16:03:26 +00001063 <STYLEPOINT title="Section Comments">
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +00001064 <SUMMARY>
1065 Group sections by a section comment (optional).
1066 </SUMMARY>
1067 <BODY>
1068 <p>
jensmeiert@google.com1e1b50b2012-07-17 20:12:10 +00001069 If possible, group style sheet sections together by using
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +00001070 comments. Separate sections with new lines.
1071 </p>
1072 <CODE_SNIPPET>
1073 /* Header */
1074
1075 #adw-header {}
1076
1077 /* Footer */
1078
1079 #adw-footer {}
1080
1081 /* Gallery */
1082
1083 .adw-gallery {}
1084 </CODE_SNIPPET>
1085 </BODY>
1086 </STYLEPOINT>
1087 </CATEGORY>
1088
mark@chromium.org5684bbc2013-07-12 18:53:13 +00001089
1090
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +00001091 <PARTING_WORDS>
1092 <p>
1093 <em>Be consistent.</em>
1094 </p>
1095 <p>
mark@chromium.org8190c132013-03-21 16:03:26 +00001096 If you’re editing code, take a few minutes to look at the code
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +00001097 around you and determine its style. If they use spaces around
1098 all their arithmetic operators, you should too. If their
1099 comments have little boxes of hash marks around them, make your
1100 comments have little boxes of hash marks around them too.
1101 </p>
1102 <p>
1103 The point of having style guidelines is to have a common vocabulary
mark@chromium.org8190c132013-03-21 16:03:26 +00001104 of coding so people can concentrate on what you’re saying rather
1105 than on how you’re saying it. We present global style rules here so
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +00001106 people know the vocabulary, but local style is also important. If
1107 code you add to a file looks drastically different from the existing
1108 code around it, it throws readers out of their rhythm when they go to
1109 read it. Avoid this.
1110 </p>
1111 </PARTING_WORDS>
1112
1113 <p align="right">
mark@chromium.org5684bbc2013-07-12 18:53:13 +00001114 Revision 2.23
jensmeiert@google.comdc19d7e2012-04-24 22:21:00 +00001115 </p>
1116
1117</GUIDE>