
Google HTML/CSS Style Guide – Omit Optional Tags - franze
https://google.github.io/styleguide/htmlcssguide.xml?showone=Optional_Tags#Optional_Tags
======
kgtm
Maybe it will make more sense once it fully sinks in, but I think in general
it is a mistake to make developers think about when and where certain things
can be omitted. It's more straightforward to simply do one thing,
consistently, following the "explicit is better than implicit" mantra.

What happened to optimizing for mental overhead instead of file size? This
simply should be a build step, part of your minification and concatenation
dance, not having to consider all of _these_ when trying to decide if I should
close my <p> tag or not:

 _A p element 's end tag may be omitted if the p element is immediately
followed by an address, article, aside, blockquote, details, div, dl,
fieldset, figcaption, figure, footer, form, h1, h2, h3, h4, h5, h6, header,
hgroup, hr, main, menu, nav, ol, p, pre, section, table, or ul element, or if
there is no more content in the parent element and the parent element is an
HTML element that is not an a, audio, del, ins, map, noscript, or video
element, or an autonomous custom element._

~~~
Arnavion
This reasoning is why I write all the web pages for my personal projects using
XHTML. I can't be bothered to remember which tags are self-closing, which tags
need explicit closing tags which can't be combined into the opening tag, etc.
Everything's consistent in XHTML.

~~~
BurningFrog
You shouldn't have to remember it, but you editor could and should.

~~~
Arnavion
XML validators are much more common in editors than HTML validators, probably
because XML is both easier to parse and used for a lot more than XHTML.

~~~
DonHopkins
I write and edit all my Genshi [1] templates as xhtml, so I can validate and
process them as crisp clean hi-fidelity xml, and then pump them out to
browsers with the html serializer [2].

If I were inclined to follow Google's guidelines on omitting optional tags, it
would be easy to write a stream filter that removed them [3].

But I prefer source templates to have all the explicit properly indented
structure, so they're easier to validate and process with XML tools (and by
eye), and unintentional mistakes don't sneak through as easily.

For the same reason, I also prefer not to write minified JavaScript source
code: that should be done by post-processors, no humans. ;)

[1] [https://genshi.edgewall.org/](https://genshi.edgewall.org/)

[2]
[https://genshi.edgewall.org/wiki/ApiDocs/genshi.output](https://genshi.edgewall.org/wiki/ApiDocs/genshi.output)

[3]
[https://genshi.edgewall.org/wiki/Documentation/streams.html#...](https://genshi.edgewall.org/wiki/Documentation/streams.html#serialization)

------
Animats
This is one Google ad. Any questions?

    
    
        <h3><a style="display:none" href="http://www.googleadservices.com/pagead/aclk?sa=L&amp;ai=DChcSEwi36oSzi5fPAhWBh34KHQO2A0YYABAF&amp;ohost=www.google.com&amp;cid=CAASJORo9LOCMjoibKPv7gF6cak7OxiE3TtM_tpkLykYWNps5wdfUw&amp;sig=AOD64_3sHUU366i6dStUuQ_sGYCNCCiv9A&amp;q=&amp;ved=0ahUKEwiswYGzi5fPAhVSVWMKHYoQDjQQ0QwIJQ&amp;adurl=" id="s0p2c0"></a><a href="https://www.capitalone.com/credit-cards/compare/?external_id=WWW_VI194_ZZZ_ONL-SE_ZZZGO_T_SEM2_ZZZZ_c_Zg_" id="vs0p2c0" onmousedown="return google.arwt(this)" data-preconnect-urls="http://www.capitalone.com/,http://5138.xg4ken.com/" jsl="$t t-zxXzjt1d4B0;$x 0;" class="r-ifxiYWNp1hrU">Capital One® Card Offers - Apply for Credit Card Offers Now‎</a></h3>
        <div class="ads-visurl">
           <span class="_mB">Ad</span><cite class="_WGk">www.capitalone.com/ApplyFor<b>Card</b>Offers</cite>‎
           <g-bubble class="action-menu ab_ctl r-iS1b0Exw3vQ8" jsl="$t t-R7dwiTmE0C4;$x 0;">
              <a href="javascript:void(0)" data-theme="0" data-width="230" class="g-bbll" aria-haspopup="true" role="button" jsaction="r.saTe4DDW138" data-rtid="iS1b0Exw3vQ8" jsl="$x 1;" data-ved="0ahUKEwiswYGzi5fPAhVSVWMKHYoQDjQQJwgm"><span class="mn-dwn-arw"></span></a>
              <div class="g-bblc" data-ved="0ahUKEwiswYGzi5fPAhVSVWMKHYoQDjQQKAgn">
                 <div class="_lBb">
                    <div>This ad is based on your current search terms.</div>
                    <div class="_zFc r-ivNjifPqiifI" jsl="$t t-h6cwAtrxkFI$t-wWNthJIwnKo;$x 0;">Visit Google’s <a href="javascript:void();" jsaction="r.8Na6VOGeTa8" data-rtid="ivNjifPqiifI" jsl="$x 7;" data-ved="0ahUKEwiswYGzi5fPAhVSVWMKHYoQDjQQKQgo">Why This Ad page</a> to learn more or opt out.</div>
                 </div>
              </div>
           </g-bubble>
        </div>
        <div class="ellip ads-creative">Find Great Rates &amp; Rewards—Apply.</div>
        <div class="ellip">Autopay&nbsp;·&nbsp;Online Banking&nbsp;·&nbsp;Account Alerts&nbsp;·&nbsp;Travel Benefits&nbsp;·&nbsp;Security Alerts</div>
        <div class="ellip">Services: Apple Pay™, Chip Technology, Second Look®, Image Card℠, Wallet App</div>
        <ul class="_MEc">
           <li><a style="display:none" href="http://www.googleadservices.com/pagead/aclk?sa=L&amp;ai=DChcSEwi36oSzi5fPAhWBh34KHQO2A0YYABAG&amp;ohost=www.google.com&amp;cid=CAASJORo9LOCMjoibKPv7gF6cak7OxiE3TtM_tpkLykYWNps5wdfUw&amp;sig=AOD64_0_5WQ5HIxnRdQEOpUEmdSkkiWV4w&amp;ctype=4&amp;q=&amp;ved=0ahUKEwiswYGzi5fPAhVSVWMKHYoQDjQQpigILCgA&amp;adurl=" id="ads-0-0-2-1-0"></a><a href="https://findmycard.capitalone.com/?external_id=%7B_externalid%7D" id="vads-0-0-2-1-0" onmousedown="return google.arwt(this)">Find the Right Card</a></li>
           <li><a style="display:none" href="http://www.googleadservices.com/pagead/aclk?sa=L&amp;ai=DChcSEwi36oSzi5fPAhWBh34KHQO2A0YYABAH&amp;ohost=www.google.com&amp;cid=CAASJORo9LOCMjoibKPv7gF6cak7OxiE3TtM_tpkLykYWNps5wdfUw&amp;sig=AOD64_2iwTNF-VPyK96RTweJ4TAggXM4pw&amp;ctype=4&amp;q=&amp;ved=0ahUKEwiswYGzi5fPAhVSVWMKHYoQDjQQpigILSgB&amp;adurl=" id="ads-0-0-2-1-1"></a><a href="http://www.capitalone.com/credit-cards/compare/?filter=nofee&amp;external_id=%7B_externalid%7D" id="vads-0-0-2-1-1" onmousedown="return google.arwt(this)">Cards with $0 AMF</a></li>
           <li><a style="display:none" href="http://www.googleadservices.com/pagead/aclk?sa=L&amp;ai=DChcSEwi36oSzi5fPAhWBh34KHQO2A0YYABAI&amp;ohost=www.google.com&amp;cid=CAASJORo9LOCMjoibKPv7gF6cak7OxiE3TtM_tpkLykYWNps5wdfUw&amp;sig=AOD64_1AOh7CWEmBWXjNLs4Oondpyt-JAg&amp;ctype=4&amp;q=&amp;ved=0ahUKEwiswYGzi5fPAhVSVWMKHYoQDjQQpigILigC&amp;adurl=" id="ads-0-0-2-1-2"></a><a href="http://www.capitalone.com/credit-cards/compare/?filter=popular&amp;external_id=%7B_externalid%7D" id="vads-0-0-2-1-2" onmousedown="return google.arwt(this)">See Popular Cards</a></li>
        </ul>

~~~
scrollaway
Well, yes, it's hypocritical. But that's from a different team. You don't need
to look further than the styleguide to find contradictions: it's advising to
omit optional tags in order to "save bytes", then it's advising to indent with
spaces instead of tabs.

 _shrugs_ should just let minifiers do the job.

~~~
ahochhaus
Google's standard template language (soy / closure-templates) does mininfy
whitespace by default [1]. However, it does not omit optional tags. I think
this is why the style guide is written as it is.

Still, I agree that both types of optimization / minification should be done
by the tooling layer.

[1]
[https://developers.google.com/closure/templates/docs/concept...](https://developers.google.com/closure/templates/docs/concepts#linejoining)

------
tedmiston
Just to put the code sample here...

    
    
        <!-- Not recommended -->
        <!DOCTYPE html>
        <html>
          <head>
            <title>Spending money, spending bytes</title>
          </head>
          <body>
            <p>Sic.</p>
          </body>
        </html>
    
        <!-- Recommended -->
        <!DOCTYPE html>
        <title>Saving money, saving bytes</title>
        <p>Qed.
    

Does the <head> tag really not matter anymore?

~~~
Klathmon
I never really thought about it much, but there's no reason it needs to.

There is not really any ambiguity that the head tag solves ever. Script tags
don't act differently in or out of the head tag, and things like <title> are
always going to do the same thing, so having the <head> block is at best a
"comment" to the user that these elements are "head related".

~~~
Sidnicious
One difference: when a script executes in the <head>, the <body> doesn't exist
yet — document.body is null.

A <script src="…" defer> always runs with a body, which is nice in any case
since it keeps scripts together, lets the browser start loading every script
right away, and is explicit about which ones need to run before the body.
Sadly, defer is only allowed for script elements with a src attribute.

~~~
tedmiston
I've been sleeping on best practices here... is it preferred to do a script
with defer in the <head> over putting it at the bottom of the <body> now?

~~~
angry-hacker
Doesn't matter much with defer or async. If you but the at the bottom, they
start loading in parallel slightly later.

~~~
ec109685
Which could be a good thing or bad thing depending on its importance to the
experience.

------
spdustin
The non-normative HTML 5 spec declares those words, ostensibly because <p>
elements cannot contain other block-level elements, and so the user agent
should infer a </p> tag when a block level open tag is seen within a <p>
element.

I've always been of the school of thought that it's a bad practice to depend
on non-obvious behaviors that, when taken in the context of so many other
rules that _are_ explicitly defined, seem like a bug that's been codified into
a de-facto rule.

Granted, <p> elements are _special snowflakes_ in the specification (not seen
as precisely a block element — because it's more limited in allowed content, a
phrasing element, an inline element, etc.), but most online docs refer to it
as a block level element, and in block level elements, you don't omit the
closing tag.

Say what you will about XHTML (such things, I'll add, I'd likely join you in
saying) but at least it had one thing going for it: a well-formed document was
easy to test for. Note, I didn't say valid, I said _well-formed_. For that
reason, I still write HTML as well-formed XML for easy linting, and then a
_tidy_ step later to turn it into plain-vanilla HTML (though, generally
speaking, that last step isn't necessary).

~~~
emn13
It's a real shame HTML5 ever became a thing. We would have been a hell of a
lot better off with a simpler spec - perhaps not xhtml as is, but certainly
one that keeps the simplicity of well-formedness around.

Such a mess nowadays - and it's not just `<p>`, similar special snowflake
rules exist for `<a>` and `<button>` too, and indeed lots of elements have
special quirks that make composability a pain.

------
yladiz
Like many other commenters have said, it makes a lot more sense to have this
in a build step rather than doing by hand -- there's a lot of somewhat
arbitrary rules (see when you can omit a "p" closing tag for example) that can
be explicitly handled during building.

However, what does this really accomplish? Does it really save that much space
and bandwidth? GZIP compresses text extremely well, so I don't see the
usefulness in most cases. Sure, for really slow networks, e.g. in developing
countries, it might matter, but the people that this guideline are targeting
are likely not going to worry about that. Maybe at Google scale it makes a
difference.

Beyond that, it really feels weird to omit the html tag and the head tags and
I'd like to see how much more readable this optional tag omission is when
you're dealing with a complex page with many meta tags and a ton of body
content.

~~~
mbrock
I've been omitting needless tags since HTML5 became a thing and I'm totally
over any residual "weird feelings" from the XHTML days.

------
Pxtl
As somebody who does a lot of xml, I'm weirded out by the idea that the root
tags are optional. I mean, get certain child elements and attributes being
optional, but the parent ones? That's.... hard.

~~~
throwanem
It reminds me, and not favorably, of all the old laziness that made browsers'
DOM parsers such nightmares of special cases upon special cases, and all the
extra effort to deal with that which was so much the norm last decade. Perhaps
this isn't a regression, but it certainly feels like one.

~~~
Sharlin
That's a big part of what HTML 5 is about, to codify existing practice when it
was realized that trying to push strict standards was fighting against
windmills. Nobody would ever push their web pages to the browser as
application/xhtml because the user getting a validation error instead of a
working page due to any slight infraction would have been catastrophically
poor UX. Thus, even "XHTML" pages were sent as text/html and parsed by
browsers as tag soup - pretty much defeating the purpose of XHTML.

Browsers accepting tag soup is just a manifestation of the Robustness
Principle [1]:

"Be conservative in what you send, be liberal in what you accept"

[1]
[https://en.wikipedia.org/wiki/Robustness_principle](https://en.wikipedia.org/wiki/Robustness_principle)

~~~
bonoboTP
But this style guide wants you to be liberal in what you send.

~~~
luchs
Not really liberal - leaving out those tags is perfectly fine according to the
specification and all compliant browsers will create the same DOM from it.

------
the_mitsuhiko
That's the styleguide that Flask and other pallets docs always had for many
years already. People keep opening pull requests to change it and are always
surprised when I point ou that it's not only not wrong but also by the spec.

If you consider how the parser for HTML5 actually works many of the closing
tags you would encounter don't actually add any value _unless_ you have some
trailing text that should be attached to the parent node.

~~~
tedmiston
Do you have a linter or some such automated style guide that you use to
enforce this style?

~~~
the_mitsuhiko
Not really but pretty sure that's the default serialization of html5lib.

~~~
gsnedders
For now. It's likely to change however, as it makes the tree less likely to
round-trip. (html5lib essentially follows what the Writing HTML Documents
section non-normatively states, but this is only actually true provided the
document matches the schema. There are plenty of invalid cases where it causes
it to not round-trip.)

FWIW, there's also some trees which are impossible to serialise in HTML-
without-parse-errors which I don't expect to ever round-trip, though all such
trees also fail to match the schema. A trivial example of this is
`<a><table><a>`, which ends up with an a element as a child of an a element
(and is, far as I'm aware, the only way except for scripting to create such a
tree).

------
niftich
I know that HTML5 deliberately throws out the SGML heritage (to say nothing of
XHTML) and makes all of this valid, but this just _feels_ like another micro-
optimization that Google promotes because at their scale, every little bit
helps.

Besides, isn't this "visual redundancy" (not to be confused with semantic
redundancy) is what compression is supposed to solve, and has been solving
since, effectively forever? So that we can code to reduce our (and the 'view
source'-reader's) cognitive load, and let gzip or brotli or whatever new
scheme work its compressive magic before it squirts our payload across a
newfangled binary HTTP/2 protocol?

~~~
dunham
But the SGML heritage is what makes this valid, and it is common in other SGML
doctypes. (e.g. if you download OFX data from your bank, the closing tags will
be omitted from certain elements.)

Both the optional closing tags for P and the optional opening tags for stuff
like HTML, BODY, TBODY, etc. are present in the HTML 4.0 DTD too. (A TR
element cannot go in a TABLE element, there is an implicit TBODY.) And SGML,
HTML, and optional tags go back to before XML existed.

------
moron4hire
In the grand scheme of things, this feels like throwing the baby out with the
bath-water. The example shows a huge savings in file size, percentage-wise,
because it's an extremely contrived one, being optimized for making sure these
sort of optional things are a large proportion of the total document.

Real documents don't look anything like this example. They have lots of meta
tags and they have footers and they are expected to be read by a wider variety
of user agents than "Google Chrome on Windows" and "Google Chrome on
Android".[0]

Part of the problem is that we treat HTML as a canonical data format, when it
should be a rendered data format. That's not to say that you shouldn't hand-
write HTML for your small site[1], but if you're deploying more pages than can
be managed by hand, then you should be A) use a data format for your content
that is as rich as absolutely possible, and B) statically rendering that data
down to a transmission format.

[0] I shudder to think what screen readers might think of this sort of markup.
I mean, I make VR applications in the browser, but I still make sure the data
is semantic. It's our duty to do so.

[1] AKA "the vast majority of cases". I whole-heartedly believe that new
ventures--before it is known how large they will be--should be hand-written.

~~~
ommunist
[3] Popular web frameworks will suffer.

------
johndoe4589
Interestingly they don't seem to have a rule against one line declarations.

I alwats use this style, which imho is very handy, because of the tree
structure _and_ admittedly because I have a super cool macro in Vim that
copies the characters from the line above, word by word so create rules that
afect children of the rule above it requires just a few keystrokes:

    
    
      #some-div { margin:1em 0; }
      #some-div .inner { padding:5px 10px; }
      #some-div .inner p { font-size:90%; }
    

This makes the structure of the declarations more obvious imho, and I tend to
have a nicely organized series of structures like that that are logically
grouped together.

Obviously this applies more to components/widgets than the basic rules and
layout.

If a declaration is long then I use newlines.. but even then I tend to group
things together eg.

    
    
      #some-div {
        display:inline; margin: ...; padding: ...;
        border-radius: ...; border-color: ...; 
        font-size:90%; text-align:center;
      }
    

Basically within a css rule I'll group together the layout properties, the
text properties, etc.

~~~
ebbv
The first example is fine, if you're only setting one property then doing it
in a single line isn't a big deal.

Your second CSS example is no bueno. Don't put multiple properties on a single
line. It might make sense to you to put display and margin and padding on a
single line but it might not make sense to me. These should all be on separate
lines, it's not worth "saving lines" to make your CSS harder to parse for
someone who doesn't already know that you like to group X, Y and Z properties.

~~~
johndoe4589
Well that is the whole point, I wish I made the example better.

How is it harder to parse? Putting everything in separate lines make the CSS
file 10 times longer, and it's more difficult to see groups of rules that fit
together along with their common structure.

Nowadays unless you edit on a tablet your text editor probably handles 120
columns or more.

But I really can't see the argument for readability. When I navigate a
stylesheet for a website I'm working on, I want to see the larger structure. I
don't need to see clearly the properties within a single rule. I want to see
from top down.

Still, this could be argued forever. Apples and bananas :) I guess it's the
same discussion as space vs tabs, or 2 space vs 4 spaces.

Here's a better example from one project which used YUI2 (it's old, but I
think it shows my point of view, that the dtk-skin-dlg structure is very
obvious along with the hd/bd/ft structure YUI 2 uses and the styles applied to
them, that's the structure I want to see readily when I work in a stylesheet
without having to scroll to understand it's all connected together):

    
    
      /* dialog body */
      .dtk-skin-dlg .yui-panel { outline:none; }
      .dtk-skin-dlg .yui-panel .hd { font:16px/1em Verdana, sans-serif; color:#ddd; padding:10px 10px 0; background:none; }
      .dtk-skin-dlg .yui-panel .bd { padding:10px 10px 10px; background:none; font-size:12px; line-height:19px; color:#000; }
      .dtk-skin-dlg .yui-panel .ft { padding:5px 10px 10px; background:none; font-size:12px; line-height:1.2em; color:#000; }
      
      /* dialog footers, right aligned */
      .dtk-skin-dlg .ft-right { clear:both; width:100%; padding:5px 0 0; text-align:right; }
      
      /* left align buttons INSIDE ft-right */
      .dtk-skin-dlg .ft-left  { float:left; text-align:left; /*padding from ft-right*/ }
      
      /* dialog body wrapper for extra css styling  */
      .dtk-skin-dlg .body { background:#fff; padding:10px; border-radius:3px; box-shadow:0 1px 3px rgba(0,0,0,0.2) inset; }
      .dtk-mobl-dlg .body { background:#fff; padding:10px; }

~~~
ebbv
> Putting everything in separate lines make the CSS file 10 times longer, and
> it's more difficult to see groups of rules that fit together along with
> their common structure.

You block them together just like we do with code. Good code doesn't put
multiple statements on a line, good CSS doesn't either. File length means
nothing, if someone's looking for a specific class there are tools to do that,
saving a few lines and making the CSS harder to read and edit isn't worth it.

The examples above are much more readable like this (margin added for
illustration of grouping related properties):

    
    
        .dtk-skin-dlg .yui-panel .hd {
            font: 16px/1em Verdana, sans serif;
            color: #ddd;
            
            background: none;
            
            padding: 10px 10px 0;
            margin: auto;
        }
    

Written that way, when someone finds that rule in the file they can easily
parse the relevant property without having to scan a 200 character long line.

------
jap
I've been omitting optional tags for a while.

One thing I've noticed is that bing webmaster tools will report "The title is
missing in the head section of the page" when there is a title, but no <head>.
Maybe bing can't properly crawl pages without a <head>. Another service I've
used had the same problem, but can't remember which.

So it might be worth being careful with omitting <head> \- and maybe other
tags, I'm reconsidering whether it's a good idea.

------
dubcanada
The only reason you would do this is to save space (ie minify). Out of
everything you have in your entire stack is the 1kb you save by removing the
optional tags really gonna matter? I mean wouldn't it make more sense to spend
time reducing javascript, or css styles, or making your database faster?

I mean if you are Google, yes that 1kb matters a ton. But they've already
optimized to the point where minifying their HTML makes sense.

~~~
progx
Year 2016: 4.5 G Networks rising, Smartphones with 1440P Screens are normal
and many pictures and videos distributed in 4K resolution.

And you really think about minification of html, js, or css to save some
bytes?

~~~
idreyn
Well Google might, if they serve those bytes a trillion times per year.

~~~
progx
google did not serve them (ok from cache), google must read them and process
the content, that cost google time and money.

------
LethargicStud
One thing I don't quite understand is omitting protocol. If you don't know the
protocol, fine it makes sense to omit it. However if you know a resource can
always be loaded via HTTPS (eg from CDN), isn't it safer to force HTTPS?

~~~
superchink
I think you're right.

[http://www.paulirish.com/2010/the-protocol-relative-
url/](http://www.paulirish.com/2010/the-protocol-relative-url/)

This page outlines the original argument, as well as the updated reasoning
that you suggest: always use HTTPS if it is available, even if requesting from
a page served over HTTP.

------
franze
here is an edge case: the <head>-tag might be optional, but HTML elements do
have a different behavior when placed in the <head> section or the <body>
section.

namely, the always beloved <noscript> tag
[https://developer.mozilla.org/en/docs/Web/HTML/Element/noscr...](https://developer.mozilla.org/en/docs/Web/HTML/Element/noscript)

which is a flow content element in the body section

but if used in the <head> it might include links, style and meta-tags and then
it should not be treated as content element.

as the <head> element therefore changes the behavior of its child-elements,
does this make it non optional?

p.s.: i think DOMParser.parseFromString() in Chrome gets this <noscript>
behaviour wrong in some cases (closes the <head>-section as it treats the
<noscript>-tag as content-element, even though it is in the <head> with just
links & style children, so it shoudn't close the <head>...)

~~~
franze
replying to myself like a pro: after reading the spec
[https://www.w3.org/TR/html5/scripting-1.html#the-noscript-
el...](https://www.w3.org/TR/html5/scripting-1.html#the-noscript-element), the
<noscript> element is even trickier, it has at least 4 parsing modes:

in the head with scripting disabled (no text, only link, style, meta)

in the head, with scripting enabled (can include text (like whitespaces) but
parsed elements must result in link,style,meta DOM only)

in the body with scripting disabled (text, but no other noscript)

in the body with scripting enabled (text, but no other noscript and script
tags)

so basically

    
    
      <html><noscript><link href="e.css"></noscript><title>hi</title><h1>ho</h1>
    

would be find, as the <head> would close just before the <h1> (in scripting
enabled and disabled case)

but:

    
    
      <html><noscript> <link href="e.css"></noscript><title>hi</title><h1>ho</h1>
    

would close the <head> in a scripting disabled case just before the
<noscript>-tag

and closes the <head> just before the <h1> in a scripting enabled case.

this would explain the DOMParser.parseFromString() behaviour, as it's a
scripting disabled case....

~~~
zcorpan
[http://software.hixie.ch/utilities/js/live-dom-
viewer/saved/...](http://software.hixie.ch/utilities/js/live-dom-
viewer/saved/4486)

In Chrome Canary 55.0.2866.0 the noscript element contains a text node and a
link element. This matches the spec as far as I can tell; whitespace is
allowed in noscript in head.

------
tangue
Ok, I've juste discovered that in the html5 specification you can omit tags.
I've always been reluctant to push Jade to my coworker but it makes much more
sense now.

~~~
rimantas
This was legal for ages. Why do people think this is HTML5 feature? This
[http://rimantas.com/bits/minimal_html.html](http://rimantas.com/bits/minimal_html.html)
dates back to 2005, but of course it was possible well before that.

------
zwetan
To me this just prove that wether a spec or standard is in place. it does not
really matter.

In this case we have the weight of Google that says "oh it's in the spec so we
can do it".

In other case we have a standard like E4X, that everyone happily not
implemented (Chrome) or removed (Firefox).

They could as well say "If we don't like it we will not do it, if we like it
we will do it", that would be exactly the same.

~~~
TheRealPomax
almost. It would be exactly the same if it was "If we don't like it we will
not do it, if we like it we will do it, and in both cases we set up a w3
working group for writing the formal declaration that this is what we now
agree on".

Welcome to HTML5: a document that comes out of the work of tens of thousands
of people across decades of historically-encumbered practices. It's done
remarkably well, and if you actually read the spec, is way more sensible than
you would think that development track would give us.

------
kazinator
You won't see _this_ in too many C style guides:

 _Emit all optional parentheses in expressions, unnecessary "break;"
statements at the end of a switch, the type specifier keyword "int" when
"unsigned" is already present in the declaration and other such fluff._

I've done plenty of web scraping in which it was helpful to look for the
<body> element.

------
sheriffderek
While we're at it, how about we lose the unnecessary uppercase for the
doctype: <!DOCTYPE html> vs. <!doctype html>

Leaving out optional tags makes sense. These days, at least with web-apps,
It's not like we are writing a <head> for every page. It's just a partial you
rarely ever interact with anyway. Either leave them in or take them out. The
only negative I could see is that some people may not know what's
optional–think you're a dummy–and put them back in. Probably best to just
follow the conventions of whatever framework you use. Save your fighting
energy for trailing commas in JSON! :)

~~~
scrollaway
Yes, think about all those bytes we could save by not sending doctype as
uppercase!

In XML, it's required uppercase. Unlike HTML being lax on tag structure, there
is no reason to advise DOCTYPE to be lowercase. It's not "better".

~~~
sheriffderek
I'm not actually fighting for it... or talking about bytes. I care more about
keystrokes. My fingers seem to prefer lowercase. OTHERWISE I can just
SOMETIMES write THINGS in weiRD cASEe FOR no REASON.. but I have to hold shift
or use caps-lock and "I'd prefer not to."
[https://www.youtube.com/watch?v=U-9tAqdd_4Y](https://www.youtube.com/watch?v=U-9tAqdd_4Y)

------
keeganjw
However weird it feels, this makes sense. Why did we ever have do things like
use an HTML tag immediately after declaring the DOCTYPE as HTML anyway?

~~~
Sharlin
Well, the HTML tag is older than DOCTYPE. Andin SGML and, later, XML, the
document must contain a single root element.

~~~
gsnedders
The html element's tags have been possible to omit under all SGML-based HTML
standards. This has no bearing on the document having a single root element.
(And the document still does have a single root element in current HTML.)

------
bryanph_
For the love of god, can we please move on to more pressing matters.

~~~
franze
The Google JS Style Guide maybe?
[https://google.github.io/styleguide/javascriptguide.xml](https://google.github.io/styleguide/javascriptguide.xml)

------
parr0t
I'm a part time developer that is still at uni but learning the ways of how
maintaining code is doing in a professional environment.

Just curious, how often are practices like these where the company you work
for gives you a detailed overview of all the coding conventions you should
follow? Is this absolutely expected to be followed strictly when you start any
job as a developer? Is this something a lot of workplaces follow or mainly the
big boys(Google, Facebook, Twitter, etc). If you miss maybe one or two coding
conventions in a huge commit for instance, do you hear about it or does the
reviewer just fix it and you can see what's changed?

Just curious as I'm still new to transitioning into the workplace when it
comes to source control. I work with one other developer (my boss) who wrote
for more or less the entire system himself and there is no such document - I
just have to observe the patterns used and follow suit.

~~~
__derek__
It's unusual to have style guides, in particular as extensive as this, except
at places that have their act together.[1] Where some sort of style is
enforced, though, it's typical to have an automated tool that validates your
code. This can happen locally (as a pre-commit hook), remotely when you push a
branch (as a CI check), or when merging to master (same). If people are going
through and noting style guide violations in a code review, that's generally a
bad sign.[2]

[1]: This is my opinion. Anecdotally, places with style guides tend to have
better engineering cultures.

[2]: Again, opinion. This tends to indicate a weak culture (dictatorial lead
or a lack of awareness/ability when it comes to tools) and can produce a
negative atmosphere (nit-picking isn't fun).

~~~
parr0t
That's really interesting, first I have heard about automated tools to
validate code.

Are there public tools out there you can use prior to commits for this purpose
or are they generally done in-house?

~~~
__derek__
The big one for Git is Overcommit[1]. The tools that it runs depend on the
language, though. Some are community-driven[2], while others are baked into
the language.[3]

[1]:
[https://github.com/brigade/overcommit](https://github.com/brigade/overcommit)

[2]: E.g., flake8 for Python:
[https://pypi.python.org/pypi/flake8](https://pypi.python.org/pypi/flake8)

[3]: E.g., gofmt for Go:
[https://golang.org/cmd/gofmt/](https://golang.org/cmd/gofmt/)

------
sanketsaurav
It looks counter-intuitive, though -- even if it is the spec. Especially for
beginners, who might feel completely out of place. As other people have
pointed out here, it's better to be implemented as a step of the build process
if you really want to save on those bytes. Counter-intuitive patterns are
nightmares for devs.

~~~
mbrock
I don't think it's obviously more counterintuitive than the strict XHTML
insistence on exact explicit hierarchy.

Like, when you start a new paragraph it doesn't become a new "subparagraph",
it just ends the current one and starts a new one. I really don't think it's
hard.

I do think omitting needless stuff creates more compact documents with less
redundant boilerplate that distracts the eyes.

------
nathan_long
This is bad advice for the vast majority of sites. It's like, "morbidly obese?
Lose weight by not licking stamps!"

Omitting `<head></head>` saves 13 bytes, _assuming_ gzip didn't help in the
first place. The average page weighs thousands of bytes, according to
[https://www.sitepoint.com/average-page-weight-increased-
anot...](https://www.sitepoint.com/average-page-weight-increased-
another-16-2015/)).

If your pages are like the average, you've already wasted too much time
thinking about this. Go optimize your images, use less JS, and make 200 other
size optimizations first. You'll probably never get around to this one.

------
innatepirate
In-spec or not, I don't like it

~~~
city41
This should be an optimization step performed by a tool anyway.

~~~
stonogo
It isn't?

I'd have assumed someone with Google's resources would have produced at least
a linter, if not a fmt tool to enforce these rules. Have they not?

------
sootzoo
It's worth pointing out that this style rule itself is optional, which is to
say they're not making a recommendation here, just providing an example of
what applying the rule would look like. It carries the same weight as, say,
the optional rule about grouping CSS sections and including a section
comment[1].

[1]
[https://google.github.io/styleguide/htmlcssguide.xml?showone...](https://google.github.io/styleguide/htmlcssguide.xml?showone=Section_Comments#Section_Comments)

------
johndoe4589
[https://google.github.io/styleguide/htmlcssguide.xml?showone...](https://google.github.io/styleguide/htmlcssguide.xml?showone=Property_Name_Stops#Property_Name_Stops)

How is adding a space after ":" any more consistent than having none? No space
between property and value is more unique and searchable should you need to
find something or do search/replace.

~~~
detaro
They are not saying that the space is more consistent than having none, just
says that you always should use one style consistently (and that this specific
style guide has chosen to add one space as the thing to do).

------
paradite
I can imagine many html crawlers and parsers breaking for these pages,
searching for <head> or <body> but nothing to be found...

~~~
emn13
Well, it took several decades, but standardized html parsing is now actually
fairly robust. So you may not be wrong, but anything that breaks is probably
heavily outdated and probably not worth much to anybody (because it's parsing
html different from browsers today, and it's not like optional tags are a new
thing...).

I wouldn't get too worried about crawlers and parsers.

------
zbjornson
I'm surprised no one has compared this to omitting semicolons in js. In both
cases it's a rather lengthy list of conditions the writer needs to know about
in order to be absolutely sure you're coding correctly, and in both cases the
benefits are debatable. (The list of conditions when js semis can't be omitted
are obscure at least.)

------
n-gauge
This to me is like:

if (x) { ... ... } someMethod()

Changed to :

if (x) { ... ... someMethod()

It's not as readable. Maybe as others have suggested, leave it to a compiler.

~~~
anjbe
The difference is that your example is ambiguous. “<p>Paragraph 1<p>Paragraph
2” is not ambigous, and never has been.

------
imdsm
Perhaps the option here is to write in explicitly verbose HTML as we do now,
and then as you minify assets, so too do you minify HTML. If the last thing
the output html went through was this reduction, then you wouldn't need to
worry about developer overhead.

------
fresheyeball
The Google HTML Styleguide people, really should inform google.com that they
are bloated.

------
EdSharkey
Here's my page loading pattern, please tell me if this is good:

In the head tag, I intentionally load a small bootstrap javascript bundle
(~50K) non-deferred. This bundle contains a subset of my CSS that styles all
of the static tags the body below will first render with. This bootstrap
bundle also starts an AJAX call for polyfills, if needed, and the main page
script (which also contains the rest of my CSS.)

My goal is to have no unstyled tags in the body as it first renders and to
kickoff loading the main body scripts ASAP before any other 3rd party scripts
have a chance to get started loading.

------
kalleboo
Web technologies are totally not piles of hacks on top of other hacks

------
masswerk
Slightly amusing:

HTML4, XHTML: Make sure to include all optional tags, because scannability.

Now: For (...) scannability purposes, consider omitting optional tags.

~~~
anjbe
HTML 4 didn’t require optional tags either. That culture was limited to XHTML.

------
isaac739
Google's parent company is still using <head> and <body> tags.
[https://abc.xyz](https://abc.xyz)

------
huntermeyer
This is really going to bother me:

    
    
      Use double ("") rather than single quotation marks ('') around attribute values

------
SZJX
With so many exceptions and corner cases, doesn't it goes exactly against the
aim of a code standard, that is to make the code rigorous and less prone to
errors? The prevention of weird behaviors and corner cases is exactly the
reason why almost all Javascript styleguides recommend semicolons.

------
hooph00p
I can get behind this.

~~~
joekrie
This blows my mind. Can't wait to bring this up in a code review.

------
dom96
Hrm, is anybody else's browser not navigating to the "Optional Tags" anchor?

~~~
Spone
Yes. Firefox on Android

~~~
dom96
Firefox on macOS here.

------
chriscareycode
A good video from Paul Irish on the subject
[http://www.paulirish.com/2011/primitives-
html5-video/](http://www.paulirish.com/2011/primitives-html5-video/)

------
PaulHoule
Is solid html 5. Html 5 fills all the ambiguous parts of the code to DOM
translation so you should give up on regexes, handlebars and such and instead
run it through JSoup (or equivalent) and just work on the parse tree.

------
ben_jones
Honest question: Why doesn't everyone use Jade markup if you already have a
build step for your front-end code? It's much faster to write and much clearer
to read.

------
SimeVidas
Websites are bloated with excessive amounts of JavaScript and non-optimized
images, and _this_ is what’s on top of Hacker News? Frickin’ optional tags?
_facepalm_

------
z3t4
cant read the article because my browser thinks its a rss feed. But i want to
stress the importance of semantics and clean html. Think alternative output
devices like html to speach and future tech like direct to brain io and
artificial intelligence. Also if u keep it simple, writing and editing also
becoms easier and more available. dont mangle or minify your html. Also keep
style out of it (in css).

------
aclsid
This all good and nice for Google saving a few bytes, but how on earth are you
supposed to specify page language with this scheme for instance.

------
ilaksh
Very cool. I did not know that stuff was optional.

If its less code to type and send over the network then that's great. HTML 5
is not XML. Which is fine.

------
reimertz
scripts in <head> tag works perfectly as well as long as you position scripts
above elements you would put in the <body> . I will start doing this!

demo:
[http://jsbin.com/duqonahiyi/1/edit?html,console,output](http://jsbin.com/duqonahiyi/1/edit?html,console,output)

~~~
nchelluri
Yes, but some places tell you not to do scripts there when possible and load
them instead at the bottom of the page because the page loading pauses while
the script is downloaded (if not inline) and executed. See
[https://developers.google.com/speed/docs/insights/BlockingJS](https://developers.google.com/speed/docs/insights/BlockingJS)

~~~
reimertz
yep, so just position the script at the bottom then. :)

~~~
mbrock
It depends on whether you want to run the script before or after the body!

~~~
reimertz
exactly, that is what I am saying.

------
phil248
Hell, I'mm still convincing people to use <br> instead of <br/>!

------
ishener
what's this style guide even mean when google.com doesn't adhere to it?

------
simple10
Here's the direct github link if you want to fork or star:

[https://github.com/google/styleguide/blob/gh-
pages/htmlcssgu...](https://github.com/google/styleguide/blob/gh-
pages/htmlcssguide.xml)

------
snarfy
>Indentation

>Indent by 2 spaces at a time.

>Don’t use tabs or mix tabs and spaces for indentation.

Let the wars begin.

------
original_idea
This is going to wreck havoc on XPATH selectors across the world.

~~~
mbrock
XPath can't run on HTML5, you have to parse it into DOM first, so there's no
problem.

~~~
j4_james
HTML5 does actually support an XHTML serialisation[1] if you need your content
to be easily parsed with XML tools.

[1] [https://www.w3.org/TR/html5/the-xhtml-
syntax.html](https://www.w3.org/TR/html5/the-xhtml-syntax.html)

~~~
mbrock
Ah, yeah, indeed, thanks for the clarification.

------
themartorana
Grammar nerd, apologies, but "Google's" with an apostrophe (unless I'm
_totally_ missing something). There should maybe be a better way to report
this kind of stuff without cluttering the comment stream.

------
danjoc
Why doesn't Google produce an html formatter instead of a style guide, like
gofmt for html? Applying style guidelines correctly and consistently is much
easier to do in software than meatware.

~~~
h1d
I thought we already got haml, jade, sass, stylus etc... Many points become
moot using these.

~~~
CoryG89
Things like Jade do not make this advice moot. You can still apply this advice
after transpile step.

~~~
h1d
I didn't say every advice becomes moot with them. Besides, shouldn't
transpilers do the process then wherever possible instead of manually... which
would be, not our job.

------
andrewclunn
This just feels wrong. It's like only using one space after a sentence.
Somewhere along the way it became technically correct, but there's just this
visceral feeling that it's not right.

------
ClayFerguson
Omitting tags that 'unbalance' a document or stop it from being valid XML is a
very dumb thing to do, even if it shaves a fraction of a millisecond off load
time. We're talking about a few bytes of transfer here. Come on Google, you
should have better judgement than that.

------
draw_down
Not the first time I've seen this suggestion but I just don't understand it.
Removing <head>, omitting quotes in attribute values... why? File size,
really?!

------
ommunist
I hope Google will not punish websites by downranking those of us who still
uses head tag. After all, why not take the bold move and tell everyone that
<pre> is enough, so the whole html monstrosity could be deprecated and Google
could save millions in serving his afs to asketic plain text websites,
designed in the mood of the Berkshire Hathaway web presense.

------
Kenji
Uhh... I wonder how large the percentage of users is that see a broken site if
you strictly adhere to that principle.

~~~
TheRealPomax
A conservative guess would be "about 100%", since every browser (even the
shitty ones built over the weekend these days) rely on HTML5-compliant DOM
parsers.

Since this code follows the official HTML5 spec to the letter (optional
_means_ optional - a parser will do the same whether an optional thing is
written our or left off), HTML5-compliant parsers just see "correct data" and
convert it into the only DOM it can be turned into.

~~~
Kenji
I think you mean "about 0%" see a broken site in response to my comment.
Anyway, I get your point.

However, I am a big fan of the robustness principle: Be conservative in what
you do, be liberal in what you accept from others.

So for me personally, the issue is clear-cut. I will keep my codebase as clean
as possible/affordable, be it HTML or C++, not relying on quirks that have
been introduced to tolerate faults of careless designers and programmers.

------
mozumder
The rules are really complicated here. It's best to do this using a minifier
instead of through hand-coding.

~~~
TheRealPomax
Sounds like a case of mistaking "a thing" for "the only thing": yes, of course
this is a thing you make your build tasks take care of, but then you _also_
make sure that any HTML code that is still coded by hand code (because why
would you even still have that anywhere, in real projects these days?) follows
your project/club/company/organization/whatever's style guide.

------
ebbv
Boo. Maybe it's over the top but for me the fact that something this awful
made it into Google's official style guide tells me the nuts are really
running the asylum over there. Was nobody in charge doing web development in
the 90s or even the early 2000s? Has nobody there ever been put in charge of a
legacy site that was written this way? There's a reason we all agreed to stick
to standards and make our HTML verbose in the mid-2000s.

~~~
detaro
What they recommend conforms to standards and should parse identically in all
HTML5 parsers.

~~~
ebbv
Oh my god talk about nitpicking. Yes I realize it's allowed, it's still sloppy
and gross.

Technically I could put all my HTML into base64 encoded strings in javascript
and then write them to the document, that doesn't mean that I should.

~~~
detaro
Sorry, I seem to have misinterpreted the background of your initial comment
(less human aspect, more browser parsing issues).

It's certainly something you should either do automatically or in a consistent
style, not as an excuse to leave out random things if you feel like it.

------
mschuster91
It's a screenscraping protection, too.

Documents malformed this way cannot be parsed e.g. with PHP's DOM functions
without significant headache.

~~~
TheRealPomax
You seem to misunderstand what's going on here. HTML5 explicitly lists which
tags are optional in what context, and the document style presented in the
link takes that fact and recommends thus removing any optional tag to save
data over the wire. There is nothing "malformed" about this, this is literally
doing what the spec says is explicitly valid. Any proper HTML5 parser
regardless, of which language its written in or for, should be able to parse
HTML5 with optional tags omitted perfectly fine.

If PHP's DOM functions don't work for it, then PHP's DOM functions aren't
HTML5 spec compliant, and that should be filed as issues against PHP and fixed
by its developers.

