DEV Community

Andrei Navumau
Andrei Navumau

Posted on • Updated on

Default 4px spacing between inline elements

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.

screen of default 4px spacing between inline elements

It's not a margin. HTML code looks like this:

screen of html code snippet with 'ul' and 'li' items

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.

screen of html code showing li elements

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:

webpage without spacing between li elements.

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

html code with li elements on one line

2) [HTML method] No line breaks between closing and opening 'li' tags. The rest of code can sit on separate lines.

html code with open and close li tags on one line

3) [HTML method] Insert html comment instead of line breaks.

html code with comments

4) [HTML method] Break closing 'li' tag btween lines.

html code with split tag

5) [HTML method] Skip closing 'li' tag, its HTML5 valid.

html code with split tag

6) [CSS method] Assign negative margin for contents of 'li' elements.

css code with margin -4px

Though, in my case, 4px were not enough to kill the spacing. See a screen:

spacing between inline elements still exist

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.

css code with font-szie prperty

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.

css code with float prperty

But in this case, extra positioning is needed.

9) [CSS method] Set letter-spacing to '-1em' for parent and to 'normal' for 'li' elements.

css code with letter-spacing prperty

10) [CSS method] Display as 'table' for parent and as 'table-cell' for 'li' elements.

css code with display table prperty

11) [CSS method] Display as 'flex' for parent.

css code with display flex

Thank you, Cris Coyier post and Kyle stackoverflow answer, I got my inspiration from your knowledge.

Top comments (9)

Collapse
 
mikesusz profile image
Mike Susz

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.

Collapse
 
tyzia profile image
Andrei Navumau

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.

Collapse
 
mikesusz profile image
Mike Susz

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. :)

Collapse
 
mikesusz profile image
Mike Susz

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 :)

Collapse
 
redmer profile image
Redmer

Whoa, that settles the incessant debate (no it won't)

Collapse
 
mikesusz profile image
Mike Susz

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.

Collapse
 
nektro profile image
Meghan (she/her) • Edited

My typical answer to this problem is using flexbox.

From the CSS Tricks article, with the css

nav a {
  display: inline-block;
  padding: 5px;
  background: red;
}

if you turn the CSS into the following you get the same result :D

nav {
  display: flex;
}
nav a {
  padding: 5px;
  background: red;
}

Collapse
 
tyzia profile image
Andrei Navumau

Thank you, Sean. I've added this method into my post.

Collapse
 
crongm profile image
Carlos Garcia ★

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.