Problem stating
If you try to create a navigation element ('nav') with menu created via not ordered list items, you will find yourself facing a problem of approximately 4px spacing between 'li' elements.
It's not a margin. HTML code looks like this:
Cause
Let me start by saying that the cause of this issue lies in html markup. Every time when we insert new 'li' element on a separate line in code editor, we are inserting a line break at the end of previous 'li' element. This line break is interpreted as a white-space by our agent (browser). The default behavior of the browser to render a white-space - is to generate space of 4px. Actually, it's not 4px exactly. It depends on font-family (serif, sans-serif), font-size and scale. But these are minor issues and could be omitted. We'll assume, that this spacing is always 4px. Which is true in most cases.
Solutions
There are several ways to avoid annoying 4px spacing. Each one has its cons and pros. It's up to you to decide, which one to use. They can be grouped by 'HTML' and 'CSS' methods.
All the below will produce the same result like:
All the below will have basically the same pro/con:
Pro: No hassle with css.
Con: Not regular html markup, which is usually hard to read.
1) [HTML method] Write all li elements in one line without line breaks
2) [HTML method] No line breaks between closing and opening 'li' tags. The rest of code can sit on separate lines.
3) [HTML method] Insert html comment instead of line breaks.
4) [HTML method] Break closing 'li' tag btween lines.
5) [HTML method] Skip closing 'li' tag, its HTML5 valid.
6) [CSS method] Assign negative margin for contents of 'li' elements.
Though, in my case, 4px were not enough to kill the spacing. See a screen:
So I should set margin-right for -5px.
7) [CSS method] Set font-size to zero for parent element and set correct font-size for 'li' elements.
Though, in this case, you can't use 'em' or '%' font-size for child elements. All children of this parent will have font-size zero, so only 'rem' or 'px' font-sizes can be used.
8) [CSS method] Set float 'left' for 'li' elements.
But in this case, extra positioning is needed.
9) [CSS method] Set letter-spacing to '-1em' for parent and to 'normal' for 'li' elements.
10) [CSS method] Display as 'table' for parent and as 'table-cell' for 'li' elements.
11) [CSS method] Display as 'flex' for parent.
Thank you, Cris Coyier post and Kyle stackoverflow answer, I got my inspiration from your knowledge.
Top comments (9)
have you tried using tabs to indent instead of spaces?
spaces have layout in inline rendering, tabs are completely ignored by the browser.
since the days of IE* (hasLayout property) this has been my argument for indenting browser code (html) with tabs instead of spaces.
Hi Mike,
That's a great idea.
My code editor settings are set up so that even if I use tabs, it inserts 4 spaces instead. I'm not ready to switch to pure tabs, because coding rules of different companies require using spaces instead of tabs. I try to stick to this practice.
Moreover, it seems to me, that 4px space is generated not because of spaces in indentation, but due to line feed.
i'm telling stories from long ago; back before we had (good) CSS layout we had to recognize what characters the browsers regarded as having layout and which they don't. things have have changed on me :)
hmm okay the RFC proves me wrong.
w3.org/TR/REC-html40/struct/text.h...
apparently i relied on this for years when browsers would ignore them.
i stand corrected. thanks for your workarounds. :)
Whoa, that settles the incessant debate (no it won't)
nothing will ever settle the tabs/spaces debate :) and packaging/minifying tools will take care of problems like this, but also introduce aberrations where what we see in our development environment may not exactly match what ends up in production.
My typical answer to this problem is using flexbox.
From the CSS Tricks article, with the css
if you turn the CSS into the following you get the same result :D
Thank you, Sean. I've added this method into my post.
This is an issue I've seen even experienced developers struggle with. Personally, I use a similar approach to the 4th HTML method, which looks clean enough for my team. Thanks for writing this article.