A few HTML tips

A while ago I wrote an article with some CSS tips, now it’s time to give some polish to our HTML! In this article I’ll share some tips and advice about HTML code. Some of this guidance will be best suited for beginners – how to properly build paragraphs, use headings, or improve forms, but we will also discuss SVG sprites for icons, a somewhat more advanced topic.

Text

Paragraphs

Most of our writing is structured in paragraphs, and there is an HTML element for that: <p>. Do not use the line break tag <br> to separate blocks of texts into pseudo-paragraphs, since line breaks are not meant for that.

Avoid:

Cupcake ipsum dolor sit. Amet chupa chups chupa chups sesame snaps. Ice cream pie jelly
beans muffin donut marzipan oat cake.

<br>

Gummi bears tart cotton candy icing. Muffin bear claw carrot cake jelly jujubes pudding
chocolate cake cheesecake toffee.

Recommended:

<p>Cupcake ipsum dolor sit. Amet chupa chups chupa chups sesame snaps. Ice cream
pie jelly beans muffin donut marzipan oat cake.</p>

<p>Gummi bears tart cotton candy icing. Muffin bear claw carrot cake jelly jujubes
pudding chocolate cake cheesecake toffee.</p>

A legit use for line breaks would be, for instance, to break verses of a poem or song:

<p>So close, no matter how far<br>
Couldn’t be much more from the hearth<br>
Forever trusting who we are<br>
And nothing else matters</p>

Headings

Headings tags, from <h1> to <h6>, have an implicit rank assigned to them, from 1 (most important) to 6 (less important).

To handle semantics properly, pick your heading rank in sequential order, not just because of the size that the browser will use to render the heading. You can – and should!– use CSS for this, and pick a suitable rank instead.

Avoid:

<article>
    <h1>Monkey Island</h1>
    <h4>Look behind you! A three-headed monkey!</h4>
    <!-- ... -->
</article>

Recommended:

<article>
    <h1>Monkey Island</h1>
    <h2>Look behind you! A three-headed monkey!</h2>
    <!-- ... -->
</article>

Another thing to take into account is how to create subheadings or tag lines to accompany headings. The W3C recommendation is to use regular text markup rather than a lower-rank heading.

Avoid:

<header>
    <h1>Star Wars VII</h1>
    <h2>The Force Awakens</h2>
</header>

Recommended:

<header>
    <h1>Star Wars VII</h1>
    <p>The Force Awakens</p>
</header>

Forms

Placeholders

The placeholder attribute in <input> form elements will let you show an example value to the user that is automatically erased once the user types anything in the field. Placeholders are meant to show examples of formatting valid for a field.

Unfortunately, in the wild there are a lot of placeholders acting as <label> elements, informing of what the field is instead of serving as an example of a valid input value. This practice is not accessible, and you should avoid it.

Avoid:

<input type="email" placeholder="Your e-mail" name="mail">

Recommended:

<label>
    Your e-mail:
    <input type="email" placeholder="darth.vader@empire.gov" name="mail">
</label>

Keyboards in mobile devices

It is crucial to provide typing hints for people browsing from a mobile device, like a phone or a tablet. We can easily achieve this by picking the correct type for our <input> elements.

For instance, type="number" will make a mobile phone display the numeric keypad instead of the regular alphanumeric keyboard. The same goes for type="email", type="tel", etc.

Avoid:

<label>Phone number: <input type="text" name="mobile"></label>

Recommended:

<label>Phone number: <input type="tel" name="mobile"></label>

Here is a comparison: on the left, the keyboard that shows up when using type="text"; on the right, the keyboard for type="tel".

keyboard comparison

Images

Say hi to SVG files! Not only can you use vector graphics in <img> tags like this:

<img src="acolyte_cartoon.svg" alt="acolyte">

You can also use SVG sprites to implement vector icons in your website, instead of using a Web Font – which is a hack, and might not yield perfect results. This is because browsers treat Web Font icons as text, and not as images. And there are other potential problems, like content/ad blockers disabling the download of Web Fonts. If you would like to learn more about this, watch this talk by Sarah Semark about why using SVG for icons is better than using a Web Font. You can also read more about this technique on CSS-Tricks.

The idea of SVG sprites is very similar to CSS sprites. The implementation consists of merging all your SVG assets in a single image file. In the case of SVG, every asset is wrapped in a <symbol> tag, like this:

<svg>
    <symbol id="social-twitter" viewBox="...">
        <!-- actual image data here -->
    </symbol>
</svg>

Then, the icon can be used in your HTML with a <svg> tag like this, so we point to the symbol ID in the SVG file:

<svg class="social-icon">
    <use xlink:href="icons.svg#social-twitter" />
</svg>

Does creating an SVG spritesheet seem tedious? Well, that’s why there are tools like gulp-svgstore to automate the process and generate a spritesheet from your individual asset files.

And remember, since we are using a <svg> tag instead of an <img> to include the picture, we can then use CSS to apply styles. So all the cool things you can do with Web Font icons, can be done with these SVG icons as well!

.social-icon {
    fill: #000;
    transition: all 0.2s;
}

.social-icon:hover {
    fill: #00f;
}

There are some CSS limitations though: when using SVG this way, with <use> linking to a <symbol>, the image gets injected in Shadow DOM and we lose some CSS capabilities. In this case, we can’t cherry-pick which elements of the SVG to apply the styling to, and some properties (e.g., fill) will only be applied to those elements that have them undefined. But hey, you can’t do this with Web Font icons either!

In the demo below, you can see an example of a SVG sprite in action. When you mouse over the image, the torch’s fire will change its color via CSS.

See the Pen SVG acolyte demo by ladybenko (@ladybenko) on CodePen.


I hope that these tips are helpful. If you have any questions, or would like to share your own tip, please leave a comment!

About Belén Albeza

Belén is an engineer and game developer working at Mozilla Developer Relations. She cares about web standards, high-quality code, accesibility and game development.

More articles by Belén Albeza…


36 comments

  1. Gerd Neumann

    What about browser support? Am I correct that IE 11 does not support “ https://developer.mozilla.org/de/docs/Web/SVG/Element/use#Browser_compatibility | http://caniuse.com/#feat=svg

    August 24th, 2016 at 01:54

    1. Belén Albeza

      There is partial support for SVG in IE11. And there is also a polyfill if what you need to do is not supported in IE11 (or older browsers): https://github.com/jonathantneal/svg4everybody

      August 24th, 2016 at 02:13

  2. Pablo Carballeda

    Nice article Belén.

    I think that xlink:href is deprecated for SVG 2, you should use href instead xlink:href now.

    Please correct me if I’m wrong

    August 24th, 2016 at 03:15

  3. Mike Swanson

    For the paragraph example, closing </p> tags are not required in regular HTML5 (they are in XHTML5, however, due to being a strict XML variant). Removing them might make them seem a bit more appealing, and in-line with the <br> examples.

    August 24th, 2016 at 05:05

  4. Derek johnston

    Clean, simple tips for a better web experience. Thanks for sharing!

    August 24th, 2016 at 06:05

  5. Francute

    Maybe i’m missing something.
    In Images Section with svgs, how do you change fill only on fire and not in dark-clothes?
    I saw you defined a figure “chara” which references the entire symbol called “acolyte”. It includes fire, dark-clothes and everything else. But when you call chara:hover pseudoelement through css it only change fire fill and not the entire acolyte fill… Why? Why not for example dark clothes only? How do you do that?
    Thanks for your time! :)

    August 24th, 2016 at 06:49

    1. Belén Albeza

      Hi Francute. The key is this bit in the article:

      we can’t cherry-pick which elements of the SVG to apply the styling to, and some properties (e.g., fill) will only be applied to those elements that have them undefined.

      When you apply CSS to an SVG included via <use>, some of the properties (including fill) will only be applied to the elements that have them unset / undefined. That’s why the CSS coloring is only applied to .fire, because only those elements have fill unset in the original asset.

      If you include a SVG as usual, you would get the behaviour you were mentioning –as we all would intuitively expect.

      I hope that helps! :)

      August 24th, 2016 at 07:02

      1. Francute

        Oh… Thanks! I missed that!

        Really thanks for the article and for that beautifull answer! :D

        August 24th, 2016 at 07:57

      2. Christian Wilkie

        Thank you for the great explanation! I was wondering the same thing at first when I was reading that section. Love the embedded codepen BTW, it was fun to try messing around with the code and being able to easily change the values/see the result.

        August 24th, 2016 at 10:47

  6. Arjun

    In your placeholder text for an email field you use “@empire.gov”. While it’s unlikely that that specific domain will ever be registered and used, I would still always recommend using “@example.com” since it’s a reserved domain by IANA for that exact purpose.

    August 24th, 2016 at 07:20

    1. Belén Albeza

      I’m aware that some domains, including .gov, are restricted. However, darth.vader@empire.gov is a syntactically valid e-mail address. Not all e-mail addresses use a .com domain, and the point of the example was to make a joke in a post that could be a bit dry, while showcasing the use of the placeholder attribute.

      August 25th, 2016 at 01:54

  7. Cornelis

    The xlink:href quote is not closed.

    August 24th, 2016 at 08:01

    1. Havi Hoffman [Editor]

      Editor’s note: Fixed! Thanks for noting @Cornelis. Thanks to vogonsPoetry and Yousef who also pointed out the missing close-quote.

      August 24th, 2016 at 16:02

  8. Salva

    Excellent article. I’m marking some of the tips as favs. One doubt anyway:

    What do you think about two h1 in the same document but each of them in a separated article?

    article#art_1 > h1
    article#art_2 > h1

    I though this was valid but, what does the spec say here and what is your personal opinion?

    August 24th, 2016 at 09:02

    1. Jens Andersen

      You should still use H1-H6 by rank like in xHTML, according to the html5 standard recomended by W3C. You should also still use an unordered list in the nav for your main navigation links.

      August 25th, 2016 at 15:07

    2. Belén Albeza

      There are actually two HTML5 spec: the WHATWG spec, and the W3C spec.

      The WHATWG one was originated first, and you will find that the W3C is very similar.

      Until some months, ago, both specs had this example that shows what you are commenting:

      <body> <h1>Let's call it a draw(ing surface)</h1> <section> <h1>Diving in</h1> </section> <section> <h1>Simple shapes</h1> </section> <!-- ... --> </body>

      However, the W3C decided to remove it from their spec this last May, since they don’t consider that the actual user agents implementation is correct –specially screen reader’s implementation.

      However, the WHATWG spec still considers that example valid and a recommended alternative.

      IMHO the advantages of this style are great. It is a way to “sandbox” content you are not generating yourself –like in a blog theme, you don’t know which headings the writer is going to choose, and to design an UI based on components –you could have an aside with a heading, and that heading could be perfectly an h1. If you are creating an app, this behaviour is almost a must, because you might not know in advance what will be the outer content.

      If you try the above code in a validator, it does validate, but you will get warnings telling you that some screen readers will not read it properly.

      Whereas 99% of the time I’m in favor of always benefiting accessible code, this is a tricky one, because theoretically it is accessible, but screen readers need to/should catch up and provide a correct implementation.

      August 26th, 2016 at 01:42

      1. Jens Andersen

        You are right, but since W3C is the consortium who is in charge of making the standards and have been for a very long time, we should follow their spec in order to use correct markup for our HTML webpages.

        I know that in HTML5 the example you just showed is legit, but as you know, some browsers or screenreaders can’t read it in it’s correct outline, if you aren’t using H1-H6 by rank in every document.

        SEO is also important in this case, and I believe that we stille need to use Headings by rank in order to present our content as SEO friendly as we can.

        August 26th, 2016 at 02:12

        1. Belén Albeza

          IMO this is a very gray area and I wouldn’t want to make a strong recommendation either way.

          This was part of the spec, and it was “revoked”, which is not a nice thing to do. And it was revoked not because they considered that it was a bad idea, but because of screen readers not implementing it correctly.

          Maybe when they do –and screen readers will have to, because this style is common–, the W3C will bring it back.

          Now, on a specific use case: you are the developer of a blog theme, and you can’t control the heading ranks of what users will use. Of course, authors shouldn’t need to care about the actual theme, or the outside structure of the document.

          What would you do?

          In this case, for me, the most sensible solution is to wrap the post in an article tag and let them use any headings (because they will anwyays).

          There are situations in which you are 100% responsible for the HTML rendered. In this case, following your suggestion might be the best choice.

          But it’s almost impossible to comply with it if you are developing an app or any kind of UI/widget-based site. Because in this case, you need to create your UI chunks in isolated blocks, and you don’t know which heading hierarchy will a block be put into.

          Use your best judgement.

          August 26th, 2016 at 02:33

          1. Adrian Roselli

            Belén, this (the Document Outline Algorithm) was not “revoked” by the W3C, the recommendation was changed to reflect reality. WHATWG has not caught up yet, but it is moot since after 7 years it does not reflect reality.

            You say it was “not a nice thing to do,” which has no bearing in a standards discussion. However, since you attach a value judgment I can confidently say it *was* a nice thing to do so that the W3C spec is not lying to developers.

            You also say it was due to “screen readers not implementing it correctly.” That is wrong. Screen readers can only use what the browser provides, and the browser makers had no interest in implementing the Document Outline Algorithm.

            You go on to say “Maybe when they do –and screen readers will have to, because this style is common–, the W3C will bring it back.” This statement suggests you do not use screen readers nor work with people who use screen readers (nor the W3C). Regardless, if the browsers suddenly decide to implement the Document Outline Algorithm, then the W3C spec will be updated to reflect that. I cannot speak to the WHATWG spec (as it is currently inaccurate).

            If you want to assign blame, then blame the browsers. Not screen readers and not W3C.

            Read more from HTML Doctor (people who work on the spec, on browsers, and/or in accessibility): http://html5doctor.com/computer-says-no-to-html5-document-outline/

            So if you want to make accessible code, as your prior comment claims, then ignore the Document Outline Algorithm and use good heading structure. Users do not care if it is inconvenient for you.

            As for chunked content, I dealt with this years and years ago (before HTML5, before HTML4), and it is not a huge lift to track where in your template a chunk of content goes and then adjust the heading level accordingly. Not learning how to do that is no excuse for using incorrect headings.

            As for your scenario of a blog post, wrap it in a main element, not an article. If it is a blog index, wrap the overall index in a main element and then you *could* wrap each abstract in an article (provided you also give it a heading), but those article elements may not be necessary if you just use good heading structure and simple abstracts.

            August 26th, 2016 at 07:36

          2. Belén Albeza

            Adrian,

            Belén, this (the Document Outline Algorithm) was not “revoked” by the W3C, the recommendation was changed to reflect reality. WHATWG has not caught up yet, but it is moot since after 7 years it does not reflect reality.

            Changed to reflect reality sounds pretty much like revoking to me. But barring that, what we have is that some months ago this was actually a recommendation from the W3C –i.e. people using it were not doing something wrong according to the spec.

            I have found nothing in the spec that forbids you to use it, and right now the W3C validator gives you a warning –not an error–, and mentions the screen readers situation.

            You also say it was due to “screen readers not implementing it correctly.” That is wrong. Screen readers can only use what the browser provides, and the browser makers had no interest in implementing the Document Outline Algorithm.

            You are right that the Document Outline Algorithm implemented by browsers is faulty.

            You go on to say “Maybe when they do –and screen readers will have to, because this style is common–, the W3C will bring it back.” This statement suggests you do not use screen readers nor work with people who use screen readers (nor the W3C). Regardless, if the browsers suddenly decide to implement the Document Outline Algorithm, then the W3C spec will be updated to reflect that. I cannot speak to the WHATWG spec (as it is currently inaccurate).

            You are assuming many things here. I have used screen readers, mainly for testing, but I don’t have a visual impairment now and thus I’m not a “real” user –like most developers. You say that the WHATWG is inaccurate, but that’s your appreciation. It is a spec, it’s just not the W3C’s one. Specs “reflecting reality” have the side-effect of code that was valid before being obsolete now, specially when now we can just use <!doctype html> and don’t indicate version there.

            So if you want to make accessible code, as your prior comment claims, then ignore the Document Outline Algorithm and use good heading structure. Users do not care if it is inconvenient for you.

            As I said in the previous reply, you can only do that when you are 100% in control of the HTML generated on the page. Even if you later run some kind of script that checks what rank the headings of an article should start and rewrites them, you might run out of heading levels, since there are only 6. One might argue that 6 levels should be enough, but, again, you are not in control of which HTML other people will input.

            As for chunked content, I dealt with this years and years ago (before HTML5, before HTML4), and it is not a huge lift to track where in your template a chunk of content goes and then adjust the heading level accordingly. Not learning how to do that is no excuse for using incorrect headings.

            We are in a world where today’s app frameworks generate loads of nested of div’s and horrible markup. Realistically, almost nobody is doing it. And again, we have the problem of possibly running out of heading levels. A solution could be then use a p instead of a heading, but…

            As for your scenario of a blog post, wrap it in a main element, not an article. If it is a blog index, wrap the overall index in a main element and then you *could* wrap each abstract in an article (provided you also give it a heading), but those article elements may not be necessary if you just use good heading structure and simple abstracts.

            There’s nothing wrong in wrapping a post in an article tag, and it’s not incompatible to wrap it with a main. If you don’t like section or article and prefer not to use them, that’s your personal choice. But other developers might think differently, and they are legit tags present in the spec.

            Like I said before, in my opinion this is a gray area, and I don’t want to advocate on one sense or the other. I might be wrong, of course, so that’s why I said “use your best judgement”. If you are completely in control of your HTML, having a strict heading structure is probably the right choice. But if you dont…

            Lastly, let’s try to keep this civilised. I found your writing quite aggressive and I’m not comfortable discussing code in these circumstances.

            August 26th, 2016 at 08:16

  9. sun

    When I’m entering in credit card details (card number, expiration MMDD, CVV) on a mobile phone, I’d prefer a number keypad as well. So, perhaps input type=tel would be appropriate for those fields as well? Not a big fan of the spinning wheel to select years

    August 24th, 2016 at 11:29

    1. Belén Albeza

      Not really, semantically type="tel" refers to a phone number, not a different kind of number.

      There is an attribute in the spec, inputmode that allows you to pick which keyboard to show regardless of the type of the input. So you could have:

      <input type="text" inputmode="numeric">

      You can take a look at the MDN to find out about all the possible values for that attribute. The problem is that there is no browser support for that attribute yet :(

      August 25th, 2016 at 01:34

      1. sun

        range attribute might be useful for number validation since credit card numbers are sixteen digits start with a 3 for AmEx, 4 for Visa, 5 for MasterCard, and 6 for Discover.

        August 26th, 2016 at 02:58

  10. vogonsPoetry

    Missing double quote in SVG example!

    ^

    August 24th, 2016 at 11:41

  11. Michał

    Acolyte is the best ;D

    August 24th, 2016 at 13:01

    1. Belén Albeza

      The Faithful Acolyte thanks you for your appreciation.

      August 25th, 2016 at 01:26

  12. Saa

    I hope support for date inputs in Firefox arrives soon.

    August 24th, 2016 at 13:25

  13. Yousef Shanawany

    FYI, there’s a typo. See here: http://i.imgur.com/xNacBOI.png

    August 24th, 2016 at 15:45

  14. Christian

    In your Force Awakens example the SUBHEAD element might be better than a P element: http://codepen.io/WebDevCA/pen/wzyIH

    August 24th, 2016 at 20:54

    1. Belén Albeza

      Unfortunately, <subhead> is not part of the HTML5 spec.

      August 25th, 2016 at 01:44

  15. David

    I like this. Except two things:

    You’re not even using a place holder in the text inputs of this comment box :)

    Sprites are hacks that should never have existed. Hopefully http/2 will remove the need for such ugly things.

    August 24th, 2016 at 22:54

  16. Luke

    It’d be great to mention that using to capture user input is a great way to get free input validation and button/keypress handling!

    August 25th, 2016 at 22:08

  17. Chris Hills

    In the last example, why does it end with “” and not “”?

    August 25th, 2016 at 23:37

    1. Belén Albeza

      Hi, could you clarify? I fear that the comment filter might have stripped some characters.

      August 26th, 2016 at 02:02

  18. Wim Mostmans

    Really like the SVG sprite tip. Didn’t know about that one yet.

    August 26th, 2016 at 00:54

  19. jotarun

    love the monkey island example :)

    September 5th, 2016 at 23:18

Comments are closed for this article.