254

Is there anything in HTML/CSS that tells the browser to ignore whitespace completely?

So many times when you want to put, say, two images next to each other - you try desperately to keep the HTML readable, but the browser puts a space between them.

So instead of something like this:

<img src="images/minithing.jpg" alt="my mini thing" />
<img src="images/minithing.jpg" alt="my mini thing" />
<img src="images/minithing.jpg" alt="my mini thing" />
<img src="images/minithing.jpg" alt="my mini thing" />

you end up with this

<img src="images/minithing.jpg" alt="my mini thing" /><img src="images/minithing.jpg" alt="my mini thing" /><img src="images/minithing.jpg" alt="my mini thing" /><img src="images/minithing.jpg" alt="my mini thing" />

Which is just so horrible!

Jon Grant
  • 11,369
  • 2
  • 37
  • 58
Paul
  • 9,409
  • 13
  • 64
  • 113
  • 2
    Unrelated to the problem: there's a subtle difference between HTML and XHTML. You're talking about HTML, but posting XHTML code (in HTML the `img` tag is a shorttag). – BalusC Apr 13 '10 at 16:09
  • 2
    See my answer in this question for a full set of options relevant now: http://stackoverflow.com/questions/14630061/correct-html-mark-up-syntax-without-rendering-unwanted-whitespace-characters/14630227#14630227 – ktamlyn Jan 31 '13 at 20:57
  • 1
    display: table-cell works great in all the browsers I've tested. – Jasmine May 07 '13 at 17:46
  • 1
    All options are covered here: http://css-tricks.com/fighting-the-space-between-inline-block-elements/ – Lee Goddard Aug 22 '14 at 10:37
  • 1
    This has got to be one of the most annoying issues us web developers/designers come across. I can't believe it hasn't been fixed yet, for real. – Josh M. Jun 25 '15 at 15:51
  • Use `letter-spacing: -0.31em;` to remove the whitespaces. – Dan Bray Jan 09 '18 at 21:03
  • For people experiencing this issue with Angular 5: See `preserveWhitespaces`: https://www.softwarearchitekt.at/post/2017/08/31/clever-white-space-handling-for-better-performance-in-angular-5.aspx – Tom Doodler Mar 14 '18 at 14:35

12 Answers12

229

Oh, you can really easy accomplish that with a single line of CSS:

#parent_of_imgs { white-space-collapse: discard; }

Disadvantage, you ask? No browser has implemented this extremely useful feature (think of inline blocks in general) yet. :-(

What I did from time to time, although it's ugly as the night is dark, is to use comments:

<p><!--
  --><img src="." alt="" /><!--
  --><img src="." alt="" /><!--
  --><img src="." alt="" /><!--
  --><img src="." alt="" /><!--
--></p>
Bryan Legend
  • 6,790
  • 1
  • 59
  • 60
Boldewyn
  • 81,211
  • 44
  • 156
  • 212
  • 3
    Although I find the commenting way horrifyingly ugly, I use it. Just make it so your IDE displays the comments in a light color so its not "in your face" =P – Warty Apr 13 '10 at 19:41
  • 6
    Apparently that property has been renamed a lot; as of now, the page says "Major Changes...February 2011...Renamed ‘white-space-collapsing’ to ‘bikeshedding’." – ysth Jun 28 '11 at 19:08
  • 4
    And later css working group minutes say it will be text-space-collapse. – ysth Jun 28 '11 at 19:58
  • 27
    CSS would be `text-space-collapse:trim-inner` with latest changes in specification – yunzen Jan 11 '12 at 11:42
  • Way to get my hopes up for doing this in CSS! BTW it seems that the anchor in the doc you're linking too has gone. Perhaps it's been removed from the CSS3 standard. – Drew Noakes Sep 05 '12 at 16:37
  • @yunzen, it looks like even that property has been removed from the spec. – Drew Noakes Sep 05 '12 at 16:46
  • 21
    It has moved to level 4, http://dev.w3.org/csswg/css4-text/#white-space-collapsing, which means far future for us :-( – Boldewyn Sep 06 '12 at 06:38
  • 6
    Setting `white-space: nowrap;` on the parent container worked for me recently. – Rich B Apr 15 '15 at 16:17
  • @RichB how that? Did you have white space between your tags? – Boldewyn Apr 15 '15 at 16:59
  • 1
    @Boldewyn Yes, in the editor I was using I had new lines and tabs between tags in order to prettify my html and make it more readadble. – Rich B May 22 '15 at 15:26
  • margin-right: -4px; this would've solved it in a nicer way – Dunnow Oct 13 '16 at 10:40
  • 1
    If the user's font in the current font size happens to feature a space exactly 4px wide, yes. If not, you'll get funny notices from your customer. – Boldewyn Oct 13 '16 at 12:59
  • `font-family:monospaced; margin-right:-1ch; img:last-child{margin-right:0;}` if I had do to it that way. – Nilloc May 16 '17 at 01:22
  • 2
    https://drafts.csswg.org/css-text-4/#propdef-text-space-trim is the current property I believe. – Victor Zamanian Nov 20 '19 at 08:58
  • Thanks! If I understand the spec correctly, we’d need more than a single line, though. Especially we’d need to `text-space-trim: discard-before` all images. *Sigh.* – Boldewyn Nov 21 '19 at 14:18
128

you can set the font-size of the container to 0 and the white-space disappears!

atiquratik
  • 1,296
  • 3
  • 27
  • 34
Umesh
  • 1,329
  • 1
  • 8
  • 2
  • 13
    +1. It's a horrible hack, but it works, and seems like the best solution in the absence of support for the `white-space-collapse` style. (but note: if you have text in the child elements, you also need to set the font size back to normal again for them, or all your content will vanish) – Spudley May 27 '11 at 09:43
  • 3
    You also lose the ability to use percentages for font sizes as they are calculated as a percentage of the parent container (which will be 0) – gsteinert Aug 19 '11 at 14:32
  • 2
    Interestingly, this works in Chrome but not Safari (tested Chrome 22, Safari 5.1.7). It works in Safari if you specify a height of 1px. – mhenry1384 Oct 24 '12 at 19:31
  • 1
    when you're using em unit this solution doesn't work either. But you can use rem unit (widely implemented) instead. I think rem unit is more practical. then you could use font-size 0 as far as you needed – jairhumberto Jun 15 '15 at 12:03
  • 2
    You can restore the font-size for child elements of the container using something like `#container > * { font-size: initial; }`. – c24w Dec 09 '16 at 17:23
  • I have downvoted because there are much better solutions now. – Matt Montag Nov 23 '21 at 20:14
55

The browsers does ignore whitespace in most cases when it's next to a block element.

The problem with images (in this case) is that they are inline elements, so while you write them on separate lines, they are actually elements on the same line with a space between them (as the line break counts as a space). It would be incorrect for the browser to remove the spaces between the images, writing the image tags with line breaks between them should be handled the same way as writing the image tags on the same line with spaces between them.

You can use CSS to make the images block elements and float them next to each other, that solves a lot of problems with spacing, both the space between the images and the spacing on the text line below images.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • I don't think the question has anything to do about block/inline elements. I think the asker is wonder why his HTML looks like that when viewing the page source, not how they appear on the page. – Lee Theobald Apr 13 '10 at 08:57
  • 2
    I think using CSS to hack around something that can be very easily fixed in the HTML source is overkill and likely to cause you problems in any complex layout. It also doesn't degrade well. – Jon Grant Apr 13 '10 at 08:59
  • 3
    @Lee: Sorry, you got it wrong. (See IP's answer to Matts comment to your answer.) – Guffa Apr 13 '10 at 10:52
  • 10
    @Jon: It's not about "hacking around" something. The layout should preferrably be controlled by the CSS, so specifying how the images are displayed should actually rather be in the CSS than in the HTML. – Guffa Apr 13 '10 at 10:56
  • 4
    It is hacking if you have to float the images (what if they are inline with something else? now you have to float everything. what if there is already something else floated? now you have to break the semantic layout of your page to deal with it) or use relative positioning that relies on the size a space character is rendered. – Jon Grant Apr 14 '10 at 11:57
  • 1
    @Jon: What's with you and "hacking"? Floating the images is one way of solving the problem that works in some situations. I have neither said that it's the only solution nor that it is always applicable. – Guffa Apr 14 '10 at 13:11
  • This is the 'correct' answer, its just bit big. The browser shows spaces because the images are displayed `in line with the text`. If you dont want that, say `display:block` or something else, like table-cell, in css. – commonpike Mar 10 '15 at 15:33
49

The newest solution for this is using display: flex on outside container, you can try this with following example:

Codepen →

(And yes, Flexbox is becoming widely supported: http://caniuse.com/#search=flexbox)

HTML:

<!-- Disregard spaces between inline-block elements? -->
<div class="box">
  <span></span>
  <span></span>
  <span></span>
</div>

CSS

.box {
  display: flex;
  display: -webkit-flex;    
}

span {
  display: inline-block;
  width: 30px;
  height: 30px;
  background-color: #fcf;
  border: 2px solid #f9f;
}

Update: Also, if you want your items to wrap (as standard inline-block elements do), don't forget to add flex-wrap: wrap to your flexbox container.

ted451
  • 503
  • 4
  • 5
  • 5
    Flexbox FTW- See [here](http://www.sitepoint.com/are-we-ready-to-use-flexbox/), [here](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes), [here](http://css-tricks.com/snippets/css/a-guide-to-flexbox/), and [here](http://the-echoplex.net/flexyboxes), – Yarin Dec 13 '14 at 13:50
  • Flex is not widely supported. You are fooled by the amount of green on the caniuse page. It is not supported by Safari Versions before Safari 9 nor on older iPads or older iPhones. – Crystal Miller Jun 06 '16 at 22:02
  • 1
    @CrystalMiller this depends on your definition of 'widely' of course. I consider 94%+ to be 'wide enough'. Your case may be different. I did not say it is supported by 100% of browsers. – ted451 Jun 06 '16 at 23:51
  • While I agree it does depend on what you need to support, I wouldn't say the support for flex is quite 94%, as it is not supported by any of the old Safari versions (Mobile or Desktop) nor IE (until 11 & virtually no IE user is using IE11) & only certain versions of Firefox. I use flex in some portions of my site & I found that a large portion of my users are not seeing the site flex. – Crystal Miller Jun 14 '16 at 18:43
  • Great solution. If you have to support pre-flexbox, my heart goes out to you. – Matt Montag Nov 23 '21 at 20:12
  • Not to forget `display: inline-flex;`, for situations where you have multiple containers on a line. – Tomalak Nov 29 '21 at 17:20
45

Unfortunately, newlines count as space characters.

The best solution I have come up with is to use the whitespace inside the tags themselves, instead of outside:

  <img src="images/minithing.jpg" alt="my mini thing" 
/><img src="images/minithing.jpg" alt="my mini thing"
/><img src="images/minithing.jpg" alt="my mini thing"
/><img src="images/minithing.jpg" alt="my mini thing" />

It's not ideal, either, I know. But at least it's not some bizarre CSS hack that relies on the size a space character is rendered or resorting to relative positioning, or JavaScript :)

Dariusz Walczak
  • 4,848
  • 5
  • 36
  • 39
Jon Grant
  • 11,369
  • 2
  • 37
  • 58
  • I've also used this, although it does cause some weaker HTML tools to barf horribly. (Not so much XHTML.) – system PAUSE Feb 14 '11 at 18:48
  • 1
    +1 for a style that I invented in the nineties. ;) I'm sure I wasn't the first one to do it (and I didn't use the slashes because there was no XHTML back then) but it was a routine way of writing HTML in days when I had **a lot** of images that had to be perfectly aligned with no gaps. :) I still sometimes do it because I don't like having text nodes where there shouldn't be any and I don't think CSS is good for removing things from the DOM that shouldn't be there in the first place. Having whitespace written in a 0px font is not the same - it's like 1px transparent GIFs - but backwords. – rsp Jul 29 '14 at 12:40
  • Rolled back to the original answer because this weird formatting was the actual solution. – Dariusz Walczak Oct 20 '16 at 07:47
  • I've downvoted because there are better solutions now. Stackoverflow is meant to evolve :) – Matt Montag Nov 23 '21 at 20:15
19

What was so difficult about this solution?

css

.no-whitespace {
    line-height: 0;
    font-size: 0;
}

html

<span class="no-whitespace">

    <a href=# title='image 1'>
       <img src='/img/img1.jpg' alt='img1'/>
    </a>

    <a href=# title='image 2'>
       <img src='/img/img2.jpg' alt='img2'/>
    </a>

    <a href=# title='image 3'>
       <img src='/img/img3.jpg' alt='img3'/>
    </a>

</span>
Ozzy
  • 8,244
  • 7
  • 55
  • 95
18
<style>
  img {
     display: table-cell
  }
</style>
<img src="images/minithing.jpg" alt="my mini thing" />...

OK, I might be lucky in that I only have to worry right now about getting this to work in webkit (specifically the one embedded in QT) so it works in Chrome and Safari too. Seems display: table-cell has all the benefits of display: inline-block, but without the whitespace drawback (think indented td's)

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
A2D
  • 308
  • 2
  • 7
  • 4
    One thing you can do with `inline-block` that you can't do with `table-cell`: align all the elements to the right or center by setting `text-align` on the parent. – Blazemonger Jun 16 '14 at 19:01
  • Best option for legitimacy. Not supported in IE<7. Any way, you can use style conditionals for IE. – Justo Jul 11 '14 at 01:21
  • According to http://caniuse.com/#search=table-cell it can be used in all browsers except IE 6+7. So it should work in IE8 as well. – Philip Helger Aug 10 '16 at 13:23
7

Images are per default inline elements, that’s why you see whitespace between them. If you listen to your example in a screen reader, you immediately know why: without whitespace, you’d hear:

my mini thingmy mini thingmy mini thingmy mini thing

So, use my mini thing. (dot plus whitespace at the end) as alt text or push the images with CSS together. Do not just remove the whitespace in the code.

fuxia
  • 62,923
  • 6
  • 54
  • 62
  • Where did you get the idea that `image` is some sort of blank, and `alt` is the method of filling it in to make a grammatically and punctually correct sentence, rather than `alt` being a short description of the image? – Evan Carroll Aug 25 '10 at 19:07
  • 1
    By listening in [JAWS](http://www.freedomscientific.com/products/fs/jaws-product-page.asp) and browsing without images. – fuxia Aug 25 '10 at 22:39
  • 1
    Interesting insight. I think this underlines the true cause to this problem: Images are default inline. If you don't use images as inline elements, make sure to declare them as something blocky. – Robert Siemer Jul 01 '14 at 12:13
3

If you're using php, this works wonderfully. I found the solution here.

I was originally looking for something to remove text nodes consisting of only whitespace after parsing html with something like simplexml, but this is much cheaper.

<?ob_start(function($html) {return preg_replace('/>\s+</','><',$html);});?>
    <img src='./mlp.png'/>
    <img src='./dbz.png'/>
    <img src='./b10af.png'/>
    <img src='./fma.png'/>
<?ob_end_flush;?>
Community
  • 1
  • 1
Chinoto Vokro
  • 928
  • 8
  • 17
2

Minify your HTML!

It is good practice to minify the response before it is rendered to the browser.

So unless you need the space (and you hard coded it using &nbsp;), you always remove the spaces in the minification process.

Ozzy
  • 8,244
  • 7
  • 55
  • 95
Fitzchak Yitzchaki
  • 9,095
  • 12
  • 56
  • 96
  • Hm, I was afraid of this. I really hope this isn't going to be another case of some javascript hackery to make HTML actually work – Paul Apr 13 '10 at 08:42
  • that seems especially scary as it requires re-rendering the entire wrapper. – Evan Carroll Aug 25 '10 at 19:05
  • 1
    Actually, maybe you're right about minifying the HTML. +1. (I can't understand what @Evan is talking about) – Camilo Martin Aug 23 '12 at 00:17
  • 4
    I think that good minifier should (by definition) not introduce semantic changes to the document through the process of minification. So if your minifier currently removes whitespace, watch out when they "fix" that bug. – hasen May 21 '13 at 06:28
  • 1
    I agree that it should not make semantic changes. Yes. – Fitzchak Yitzchaki May 21 '13 at 07:09
  • 4
    A smart minifier should *not* remove the spaces in this case because they might be desirable in some cases when using `inline-block`. – Blazemonger Jun 16 '14 at 19:03
  • 1
    But it _should_ remove newline characters because they are not rendered faithfully. – Cool Blue Sep 13 '14 at 11:27
  • I nearly answered this the same way, but thought to check - and lo! - it's right at the bottom :-( Voted up of course, although, suggestion: "...before it's SENT to the browser...". – Fred Gandt May 24 '15 at 07:16
  • This doesn't work if you display:none then later display:block your element. It will add the carriage return when it is displayed again. – Brain2000 Oct 16 '15 at 22:47
2

This is a simple question and the answer is not so simple.

One can try to avoid the spaces in the source code which is not always achievable in CMS, because there they are automatically inserted by the system. If you want to change this you have to dig deep inte the CMS's core code.

Then you can try to use left floated images. But this is dangerous. At first you don't really have a control over vertical-alignment by definition. And secondly, you run into total chaos if you have so many floated elements, that they stretch over more than one line. And if you have a layout that relies on left floated elements (most of them do so today) you can even break some outer floating styles, if you clear floating after the images. This can be overridden, if you float any surrounding element. Rather not to be recommended.

So the only solution would be a CSS declaration that handles the process of whitespace handling. This is not part of any standard (as CSS 3 is not yet finished).

I prefer the no whitespace in HTML variant. With using drupal as CMS this can be achieved rather easy in your template.php and theming files. Then I choose inline-block.

P.S.: inline-block is rather complicated to get in the different browsers. For FF 2 you need display: -moz-inline-box. The rest and IE8 can have display: inline-block right after. And for lte IE 7 you need display: inline in a following separate declaration (preferrably via conditional comments).

edit

What I use for making a element inline-block

elem.inline {
  display: -moz-inline-box; /* FF2 */ 
  display: inline-block; /* gives hasLayout in IE 6+7*/
}
/* * html hack for IE 6 */
* html elem.inline {
  display: inline; /* elements with hasLayout and display inline behave like inline-block */
}
/* * +  html hack for IE 7 */
* + html elem.inline {
  display: inline; /* elements with hasLayout and display inline behave like inline-block */
}
yunzen
  • 32,854
  • 11
  • 73
  • 106
1

Try this CSS:

img { display: table-cell; }
Code Maverick
  • 20,171
  • 12
  • 62
  • 114
Djidel
  • 347
  • 4
  • 9