Remove Whitespace Between Inline-Block Elements

By  on  

I remember being a young developer during the Internet Explorer 6 days and desperately wanting IE to adopt display: inline-block.  The inline-block value is incredibly useful when wanting to control margin and padding on "inline" elements without the need to `block and float` them.  One problem that arrises when you use inline-block is that whitespace in HTML becomes visual space on screen.  Gross.  There are a few ways to remove that space;  some of them are just as gross, one is reasonably nicer.

Solution 0: No Space Between Elements

The only 100% solution to this issue is to not put whitespace between those elements in the HTML source code:

<ul><li>Item content</li><li>Item content</li><li>Item content</li></ul>

Of course this is a mess to maintain but it's practical, logical, and most importantly...reliable.

Solution 1:  font-size: 0 on Parent

The best white-space solution is to set a font-size of 0 on the parent to the inline block elements.  So if you had a <UL> with inline-block <LI>'s, you'd do this:

.inline-block-list { /* ul or ol with this class */
	font-size: 0;
}

.inline-block-list li {
	font-size: 14px; /* put the font-size back */
}

To counteract the parent font-size setting, you must set a font-size for the list items, but that's usually fairly simple.   The only time it wouldn't be simple is if you're in a wicked cascade of relative units you can't easily calculate.  In most cases, however, this will be exactly what you need. Update: unless you care to support Android WebKit.

Solution 2:  HTML Comments

This solution is a bit gangsta but also works.  Using HTML comments as spacers between the elements works just as placing no space between elements would:

<ul>
	<li>Item content</li><!--
 --><li>Item content</li><!--
 --><li>Item content</li>
</ul>

In a word...gross.  In two words...really gross.  In three words...well, you get it.  But it works!

Solution 3:  Negative Margin

Much like solution two, this is regrettable.  You can take advantage of inline-block's flexibility to use a negative margin to negate the space:

.inline-block-list li {
	margin-left: -4px;
}

This is the worst solution because you have to account for variable, sometimes unpredictable spacing.  Avoid at all costs.

Solution 4:  Dropping Closing Angle

Another HTML-based hack solution is to simply place the closing > next to the start of the next tag:

<ul>
	<li>Item content</li
 ><li>Item content</li
 ><li>Item content</li>
</ul>

Not as ugly as the HTML comment hack but I know I'd probably remove that whitespace and not think about why it was there originally.

None of these solutions are ideal but the only alternative is not spacing/indenting your HTML which is also a crap solution.  This isn't a "be careful what you wish for scenario" because inline-block is still incredibly useful, but it is important that developers know how to deal with the space that comes with using it.

Recent Features

Incredible Demos

  • By
    Retrieve Your Gmail Emails Using PHP and IMAP

    Grabbing emails from your Gmail account using PHP is probably easier than you think. Armed with PHP and its IMAP extension, you can retrieve emails from your Gmail account in no time! Just for fun, I'll be using the MooTools Fx.Accordion plugin...

  • By
    Parallax Sound Waves Animating on Scroll

    Scrolling animations are fun. They are fun to create and fun to use. If you are tired of bootstrapping you might find playing with scrolling animations as a nice juicy refreshment in your dry front-end development career. Let's have a look how to create animating...

Discussion

  1. Pavel Linhart

    Solution 4: Don’t close LI tags + put opening UL and first LI on the same line
    Solution 5: Use a templating engine that collapses the whitespaces/linebreaks for you (eg. Smarty has a modifier for that)

    The 5th one is IMHO the best if you can use it, which is not always :)

    • I started with 4 but it’s a mess to maintain.

    • #5 is certainly the most elegant solution, but #1 is most accessible.

  2. The font-size:0 hack doesn’t work cross browser. It’s as unreliable as the negative margin hack. Many mobile browsers override the font-size value with a minimum one to improve readability.

    There is no reliable and cross browser pure CSS solution. The only hacks that work are the ones involving the HTML itself (comments, leaving LI open, removing white space manually or at build time).

    • Thanks for the insight!

    • Clyde

      Unfortunately the comment hack didn’t work for me. The cross-browser solution that did work was setting line-height: 0 (I tried font-size: 0 but it broke my design because of the use of ems).

  3. For me Solution 1 is only valid if you don’t size your fonts with ems – which I do.

    And solution 2 could be troublesome when used in an agency setting. If another co-developer didn’t know that there must be html comments between list-items, things could go tits up.

    Even though Solution 3 is your least favourite (and I agree the spacing is sometimes inconsistent – usually 3 or 4 pixels) – this is the solution that I found my using in my work. If I pass my code onto another developer, there’s very little that could go wrong.

    • Clyde

      When using ems for sizing, try setting line-height to 0 instead of the font-size.

  4. agree with Pavel Linhart.
    And i used:

    Solution 6:
    put everything in one line.

  5. Note that the font-size:0 approach doesn’t work on Android browser according to Matt Stow.”>http://codepen.io/stowball/details/LsICH” rel=”nofollow”>Matt Stow.

    Matt Stow." data-user="stowball">

    Also worth a look, the YUI3 grids, where they chose for this mess:

    .yui3-g {
        letter-spacing: -0.31em; /* Webkit: collapse white-space between units */
        *letter-spacing: normal; /* reset IE < 8 */
        *word-spacing: -0.43em; /* IE < 8: collapse white-space between units */
        text-rendering: optimizespeed; /* Webkit: fixes text-rendering: optimizeLegibility */
    }
    
    /* Opera as of 12 on Windows needs word-spacing.
       The ".opera-only" selector is used to prevent actual prefocus styling
       and is not required in markup.
    */
    .opera-only :-o-prefocus,
    .yui3-g {
        word-spacing: -0.43em;
    }
    
    .yui3-u {
        display: inline-block;
        zoom: 1; *display: inline; /* IE < 8: fake inline-block */
        letter-spacing: normal;
        word-spacing: normal;
        vertical-align: top;
        text-rendering: auto;
    }
    • Thank you for this code sample — incredibly useful! Cheers Geert!

  6. Pavel Linhart

    Once there was this in the spec draft:
    http://www.w3.org/TR/2007/WD-css3-text-20070306/#white-space-collapse

    …and it got moved to CSS4 text :)
    http://dev.w3.org/csswg/css-text-4/#white-space-collapsing

    Sadly it looks like it has still a long way to go before getting implemented (or even finalized).

  7. Solution 2 is the only one that could stand up. It may be ugly but it works. Problem is that if you just take out the spaces like solution 0 then someone may put them back in. Using comments may look gross but they can mean something. Just write something in the comments so people know not to read them like:

    <ul>
    <li>Item content</li><!-- INLINE WHITESPACE DO NOT REMOVE
    --><li>Item content</li><!-- INLINE WHITESPACE DO NOT REMOVE
    --><li>Item content</li>
    </ul>

    • Rumcajs

      You can try cobnination “Solution 1” and “Solution 2” like this:

       <ul><li>Item content</li><div style="display: inline; font-size: 0;"></div><li>Item content</li><div style="display: inline; font-size: 0;"></div><li>Item content</li></ul>
  8. I can’t wait to start using inline-block more boldly. I still have that awkward feeling whenever i use it, like it’s not really a legit property lol.

    I think Geert De Deckere’s answer is most suitable.

    • Inline-block is a close-enough representation of the self-contained “replaced element” like images, objects, videos, form controls, etc. that I would not feel bad for using it, or feel that it was not legit. There only time I would call into question whether it is legitimate to use inline-block is if the element to which you apply it is not some self-contained structure.

      As to the topic of the article, I think using the margin with an em unit matching the parent font size is best. Perhaps a :before pseudo-element can be used to pull the item into line? Hmm.

  9. Tom

    Wouldn’t flexbox help? (in case you could use it for your project of course)

  10. I’m seeing this working for default 16px = 1em font size without gaps at all standard text zoom levels (ctrl + and ctrl -):

          .ib-parent {
            display: block;
            background-color: white;
            color: black;
          }
          .ib-child {
            display: inline-block;
            background-color: green;
            color: white;
            margin-left: -.33em;
          }
          .not-ib {
            display: inline;
            background-color: red;
            color: black;
          }
    
  11. PM5544

    We switched to using Haml for exactly this.
    It has an elegant way of keeping a clear structure and remove whitespace with the > and < characters.
    Highly recommend it.

  12. I prefer this solution:

    Item content
    Item content
    Item content

  13. I prefer this solution:

    Item content
    Item content
    Item content

    (sorry don’t understand how to put coude in a comment…)

  14. Great post David!

    Personnaly I really hate #0, #2, #3, #4, mostly because I hate ugly code.
    We use #1 but we set the font-size to 1rem on child elements and work our way from there…

    Rem Unit support: http://caniuse.com/#search=rem

    Thanks.

  15. Hamid

    Thanks, i think #1 is best, too
    i used float, something like this:
    ul>li {
    float: left;
    display: block;
    }
    ul {
    height: 30px;
    }
    now i will use your solution

    • Mathsquirrel

      You also use display as block. I think that with inline it’d not have worked.

  16. This is what I usually do: http://cdpn.io/rjbBo

    In short margin-left/right: -0.25em and then some nice styles to compensate, if needed. I don’t usually work with “fancy” fonts so I don’t know if it’s always compatible.
    Give me feedbacks if you want!

    • I’ll rectify my comment: I use this technique usually yes, but just in my HTML demos! For most of the “production” code I still rely on a good use of floats and clearfixes (sadly).

    • test

    • semma …………

  17. I saw on one project we maintain, html was in php string and then it was preg_replace’d, lol.

  18. Sam

    Should solution 4 be this instead?

    Item contentItem contentItem content

  19. Sam

    Damn formatting. pre tag not working :(

    I was saying that “–” before closing “>” is probably wrong.

    • Mathsquirrel

      I heard about this problem in postprocessors. I haven’t understood, explain to me.

  20. David, I’m surprised you didn’t mention a JavaScript solution:

    var n = document.getElementById('nodeWithWhiteSpace').firstChild;
    while(n){
        console.log('N', n.nodeType, n);
    	next = n.nextSibling;
    	if(n.nodeType === 3 && !n.nodeValue.trim()){
    		console.log('remove');
    		n.parentNode.removeChild(n);
    	}
    	n = next;
    }
    
    • David

      not very strong on Js, a little confused on some of this, like console, nodetype 3, what the console(‘remove’) and removeChild are actually removing, etc…

      I tried to run this script at the end of the html files and id the tags to remove whitespace betweeen but it didn’t seem to work, so i’m obviously doing something wrong. Could you explain it a little?

    • Mathsquirrel

      Why without the script all works the same? And what is the error in the end of the console-output? http://next.plnkr.co/edit/w8RD2eKlf8p5uFZO

  21. Sik

    I use a variant of #4 that looks somewhat more consistent:
    <ul
    ><li>…</li
    ><li>…</li
    ><li>…</li
    ></ul>
    At least every li looks the same!

  22. Thanks for the tip, font-size: 0 on Parent seems to be work just fine

  23. float: left or margin-(left|right): -4px

    • Jacob

      I’m sorry to say that, but you totally missed the point.

      inline-block has many advantages over float, and the negative 4px is too arbitrary bceuase it depends on the font used and how it’s rendered by the browser.

  24. Tobias Aberg

    Yahoo recently updated their letter-spacing solution. Apparently it relied on the good old web safe fonts that is installed on every single computer world wide, except for some weird linux hipster distro in beta that only has the monospaced powerline fonts.

    Their solution:
    “The solution that we ended up shipping is two-fold — it takes advantage of CSS3 Flexbox in modern browsers that support the spec, and sets a specific font stack on pure-g and pure-g-r for older browsers that don’t.” – http://blog.purecss.io/post/60789414532/how-we-improved-grids-in-pure-0-3-0

    The comments in the CSS makes it a bit unclear though.
    “The following font stack makes Pure Grids work on all known environments.

    Use flexbox when possible to avoid letter-spacing side-effects.”
    Sounds promising until then they mention side-effects, no details.

    I like this solution, it’s pretty simple to understand. So if someone thinks this is a really bad idea to use, speak now or I will spam the interwebs with cat sites using this from top to bottom!

  25. Simon

    How about ‘white-space: nowrap;’ on the container. Seems to work on FF, Chrome and Safari.

  26. Adrian Harris

    You better to use block element for such purposes, here is the difference between them: http://basicuse.net/articles/pl/textile/html_css/how_to_display_inline_elements_as_block_elements_and_visa_versa

  27. Jason P. Cochrane

    There’s actually a really clean way to remove whitespace that’s both easy and semantic. It’s called a custom font with zero-width spaces. You just change the font on the container to the linked font, the children back again, and voila. Here’s a download to the font I just cooked up in font-forge with the css @font-face declaration included. Suit to taste. (This link is to Google Drive; click File > Download to save to your computer)

    https://drive.google.com/file/d/0B8W6UmdG-DTVbThfWkI5M1NYRVE/edit?usp=sharing

  28. I remember a solution involving a rarely-used CSS property, something like white-space-collapse:collapse; but I might be tripping…

  29. I tried Jason P. Cochrane’s solution, seems to be working fine but it would be good to know if anyone has found any draw backs, apart from the need to download a small font.

  30. Rick Finster

    After floating doesn’t serve the ability to avoid auto-wrapping the content (even with defined overflow-behaviour), I nearly got to use #1 with the font-size. But then I thought of a more attractive method, which isn’t mentioned here yet but works perfectly: using a table.

    Just a instead of the inline-block, wrapped by

    and setting margin / padding / border of the td to 0. When CSS doesn’t serve enough, I think it’s ok to go back to the root and use tables for layout.

    Comments or shifte linebreaks were no possibility for me, because I had no 100% controll of the markup which was rendered serverside in last instance.

  31. Rick Finster

    Important note:
    Table-Element must be set as inline-block for this solution.

  32. Thanks a lot David!

  33. Ralph

    Here’s a nice example of how to use negative word-spacing to remove the inline-block spaces. It works back to IE6: http://cdpn.io/BfIun

    • Gitlost

      Thanks Ralph, that works really well, gets my vote! Explicitly:

      parent: { display: table; word-spacing: -1em; }
      child: { display: inline-block; word-spacing: 0; }
      
  34. HTML5 doesn’t specify a closing tag as necessary for list elements, so inline block with list items is free of hacks!

  35. Alexander

    In a nutshell: It’s amazing how incredibly inept CSS2 is at creating the most obvious thing in the world – grid-based layouts.

  36. Philippe

    I’m using twig templates which has a function that removes whitespaces.

    {% spaceless %}
        
            foo bar
        
    {% endspaceless %}
    {# output will be foo bar #}
    

    Making solution 0 cross-browser and maintainable.

  37. jason weng
    ul{
        padding: 0;
        border: solid 1px #000;
        letter-spacing  :-4px; /*Remove the letter spacing*/
    }
    li{
        display:inline-block;
        padding: 10px;
        width: 114px;
        border: solid 1px #f00;
        margin: 0;
        letter-spacing  :0px; /*Put back the letter spacing*/ 
    
    }
    

    This works fine for me

  38. I prefer using a zero-width webfont for this.

    Demo : http://jsfiddle.net/johnslegers/bczxxp6r/

    Zero width webfont : https://github.com/patrickkunka/zero-width
    Adobe Blank OpenType Font : http://blog.typekit.com/2013/03/28/introducing-adobe-blank/

  39. Chandra Nakka

    Solution 1 is awesome…

  40. kevin-smets

    The only way I like it, is just processing the html. Either by using a preprocessor / templating language like Jade and have it generate html sans white-spaces.

    PRO:

    – Nobody can mess this up (unless they mess with the build), write html however you want to (as it should be).
    – inline-block just works as would expect it to
    – no need for the client to load in any zero-width space fonts
    – you don’t need to target the parent using ugly (imho) css

    CON:

    – whitespace get stripped in pre tags, maybe there are postprocessors who respect this ?(research needed ;) )
    – tight coupling between your style definitions and your build process

    I found this solution to work most consistenly, especially since I have to manage this while we work with 100+ devs on the current project.

  41. olivvv

    – font-size: 0 should really be avoided, since it may accidentally result in hidden content and no automated test will catch that.

    – “gangsta” comments is my choice for my team, but it requires to explain often whats going on here to other non-FE team members.

    – not closing tags makes me scream, but it is perfectly valid html5, and reliable.

    – flexbox is the really zen solution, but support for all properties (tablet browser…) isn’t perfect, so inline-block is going to be the fallback for a few more years….

  42. Hi, Is there any online tools for removing white space? Thanks

  43. So, I used to build emails at my old job (no more thankfully) and the simplest solution seems to me be to use tables… except you don’t actually need to use a table..

    ul {
      display: table;
    }
    li {
    display:table-cell;
    }
    

    So this should make all your Li’s sit next to each other horizontally and has the added benefit that you can apply v-align: center; to the li as well if you don’t want to use padding on your contents.

    Enjoy.

  44. John Freeman

    Instead of using <!-- -->, I use the SGML processing instruction because minifiers often remove the comments, but not the XML PI. When the PHP PI is processed by PHP, it has the additional benefit of removing the PI completely along with the CR/LF in between, thus saving at least 8 bytes. You can use any arbitrary valid instruction name such as and save two bytes in X(HT)ML.

  45. John

    “Not as ugly as the HTML comment hack” WTF ARE YOU TALKING ABOUT!?!? That one is MUCH uglier than the html comment hack! The comment hack is the ONLY one that works ACROSS THE BOARDER and does not visually muck up the code. My god…what is wrong with you. I seriously can’t believe you tried to compare the html comment hack to NEGATIVE MARGINS!! Seriously?! And then to say dropping the closing bracket is BETTER?! It looks terrible that way! le sigh…

  46. Brett Brewer

    The easiest way I’ve found is simply to run an HTML minfier on your webserver which strips out all whitespace between tags. It can be a little annoying in your dev environment if you don’t have a minifier enabled, but at least it doesn’t require any modifications to your css, assuming you didn’t create any of your layout to depend on spaces between tags, which you’ll quickly find out as soon as you enable html minification. You may find yourself needing to add padding or   to certain elements…breadcrumbs are a typical place where spacing often disappears when you strip out all inter-tag whitespace. Also, if you have some mechanism to render pages w/o minification for debugging purposes (such as a querystring param added to a url), then you may occasionally find yourself wondering why some extra spaces suddenly appeared in your layout when you disabled the minifier until you remember it’s showing the inter-tag whitespaces that your minifier has been stripping out. This happened to me today with some icon fonts that use :before and :after pseudoclasses…I disabled my minifier and my review rating icons suddenly had too much space between them even though there was no difference in how any of the css was being applied….it was due to the spaces between the containing tags.

  47. In solution 3, is the margin number a random one or is calculated based on other measurements?

  48. Gee, took me quite a while to figure out what was messing up my blocks… This ghostly margin is kinda creepy.

  49. Patrick

    I just attempted to describe the way white space is processed in HTML/CSS here: https://medium.com/@patrickbrosset/when-does-white-space-matter-in-html-b90e8a7cdd33#.7ru5bvqsl
    I thought this was relevant to this article.
    The solutions proposed here are very useful, but I thought it would be useful for people to also understand why we have that problem in the first place.

  50. I use an enterprise level CMS on a daily basis that makes things a little tricky when it comes to things like this. We can’t add a parent container to some content or target the first and last items in a group. So using the HTML comment hack as mentioned elsewhere isn’t an option.

    But this seems to work in all my browser tests, all the way back to IE8:

    
    
    
    

    It’s better to look at than the original comment hack (marginally) and works if you’re having to deal with repeatable chunks of content with no way to add a parent or target the first and last items.

    Am I missing something?

    • Apologies, it appears the CMS I’m using automatically removes white space if there is no empty line at the end of a block of repeatable content. That’s why the approach I posted above was working.

  51. Thanks Solution 3: Negative Margin works for me fine , but in responsive it create crate some issue. you have any solution for that

  52. Is there any tool for deleting white space ?

  53. rolson

    2018 and I’m using the HTML comment fix on an Angular 5 template. FML.

  54. Mathsquirrel

    I collect supplement for the article. You may not read all 68 comments.

    Note, that from font-size depends on em-unit, that won’t work if the first is equal to zero. It also won’t work in mobile browsers, that anyway override the font-size.

    Easier solutions:
    Usewhite-space: nowrap;orwhite-space-collapse:collapse;orline-height: 0;

    Solution 6: through table-display
    for parent

    display: table;

    for children
    <pre>display: table-cell;</pre>
    for benefit text in children will automatically align to center.

    Solution 7:
    Use Javascript like this

    Solution 8:
    Use the “Zero-width” webfont.
    https://davidwalsh.name/remove-whitespace-inline-block#comment-500543

    Solution 9:
    Use HTML-postprocessors. Obviously.

    Solution 10:
    Wait CSS4:
    http://dev.w3.org/csswg/css-text-4/#white-space-collapsing
    In CSS3 doesn’t support, proof:
    http://www.w3.org/TR/2007/WD-css3-text-20070306/#white-space-collapse

    ——
    And extra-article:
    https://medium.com/@patrickbrosset/when-does-white-space-matter-in-html-b90e8a7cdd33#.7ru5bvqsl
    ——
    That I haven’t understood:
    https://davidwalsh.name/remove-whitespace-inline-block#comment-501756
    https://davidwalsh.name/remove-whitespace-inline-block#comment-61052

  55. Thank you. font-size: 0; helped me!

  56. rashmika mishra

    thank you so much

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!