Ignore whitespace in HTML [duplicate]
Asked Answered
D

12

256

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!

Delores answered 13/4, 2010 at 8:30 Comment(7)
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).Bergen
See my answer in this question for a full set of options relevant now: #14630561Acquaint
display: table-cell works great in all the browsers I've tested.Eileen
All options are covered here: css-tricks.com/fighting-the-space-between-inline-block-elementsCulosio
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.Arlo
Use letter-spacing: -0.31em; to remove the whitespaces.Chamois
For people experiencing this issue with Angular 5: See preserveWhitespaces: softwarearchitekt.at/post/2017/08/31/…Airliah
C
230

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>
Conley answered 13/4, 2010 at 12:27 Comment(15)
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" =PVocalise
Apparently that property has been renamed a lot; as of now, the page says "Major Changes...February 2011...Renamed ‘white-space-collapsing’ to ‘bikeshedding’."Isle
And later css working group minutes say it will be text-space-collapse.Isle
CSS would be text-space-collapse:trim-inner with latest changes in specificationStitch
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.Speculator
@yunzen, it looks like even that property has been removed from the spec.Speculator
It has moved to level 4, dev.w3.org/csswg/css4-text/#white-space-collapsing, which means far future for us :-(Conley
Setting white-space: nowrap; on the parent container worked for me recently.Beekman
@RichB how that? Did you have white space between your tags?Conley
@Conley 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.Beekman
margin-right: -4px; this would've solved it in a nicer wayImmaterial
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.Conley
font-family:monospaced; margin-right:-1ch; img:last-child{margin-right:0;} if I had do to it that way.Conduction
drafts.csswg.org/css-text-4/#propdef-text-space-trim is the current property I believe.Tupiguarani
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.Conley
R
129

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

Rocher answered 13/4, 2011 at 10:22 Comment(6)
+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)Ence
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)Berryberryhill
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.Anthe
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 neededGimp
You can restore the font-size for child elements of the container using something like #container > * { font-size: initial; }.Poacher
I have downvoted because there are much better solutions now.Decagon
F
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.

Faltboat answered 13/4, 2010 at 8:45 Comment(7)
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.Several
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.Sst
@Lee: Sorry, you got it wrong. (See IP's answer to Matts comment to your answer.)Faltboat
@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.Faltboat
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.Sst
@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.Faltboat
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.Ehlers
T
51

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)

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.

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

span {
  display: inline-block;
  width: 30px;
  height: 30px;
  background-color: #fcf;
  border: 2px solid #f9f;
}
<div class="box">
  <span></span>
  <span></span>
  <span></span>
</div>
Toil answered 16/5, 2014 at 15:17 Comment(6)
Flexbox FTW- See here, here, here, and here,Equality
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.Sharrisharron
@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.Toil
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.Sharrisharron
Great solution. If you have to support pre-flexbox, my heart goes out to you.Decagon
Not to forget display: inline-flex;, for situations where you have multiple containers on a line.Fahland
S
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 :)

Sst answered 13/4, 2010 at 8:53 Comment(4)
I've also used this, although it does cause some weaker HTML tools to barf horribly. (Not so much XHTML.)Gallicize
+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.Burdett
Rolled back to the original answer because this weird formatting was the actual solution.Mononucleosis
I've downvoted because there are better solutions now. Stackoverflow is meant to evolve :)Decagon
D
19

.no-whitespace {
  line-height: 0;
  font-size: 0;
}
<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>
Disenable answered 9/7, 2012 at 12:50 Comment(4)
While this has the potential to "cancel" out nested font sizes, this is my favorite solution.Pelvis
not good. Those properties are inherited...Procurator
@Procurator Yes, the only caveat of this technique is that you have to explicitly reset the font-size on child elements.Carrot
1) This does not work with Safari. 2) If you are not using px to define your site which now days is more likely than not), this can really mess up the content.Sharrisharron
R
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)

Reveille answered 2/10, 2012 at 15:28 Comment(3)
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.Carrot
Best option for legitimacy. Not supported in IE<7. Any way, you can use style conditionals for IE.Kovno
According to caniuse.com/#search=table-cell it can be used in all browsers except IE 6+7. So it should work in IE8 as well.Chunky
L
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.

Leucopoiesis answered 13/4, 2010 at 8:42 Comment(3)
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?Procrustes
By listening in JAWS and browsing without images.Leucopoiesis
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.Marche
G
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;?>
Geyserite answered 16/4, 2013 at 14:57 Comment(0)
S
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 */
}
Stitch answered 21/12, 2010 at 8:8 Comment(0)
C
1

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.

Cracked answered 13/4, 2010 at 8:33 Comment(9)
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 workDelores
that seems especially scary as it requires re-rendering the entire wrapper.Procrustes
Actually, maybe you're right about minifying the HTML. +1. (I can't understand what @Evan is talking about)Triennial
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.Kazmirci
I agree that it should not make semantic changes. Yes.Cracked
A smart minifier should not remove the spaces in this case because they might be desirable in some cases when using inline-block.Carrot
But it should remove newline characters because they are not rendered faithfully.Audy
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...".Outmost
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.Transmutation
V
1

Try this CSS:

img { display: table-cell; }
Vanderbilt answered 14/1, 2015 at 15:48 Comment(1)
This did nothing in my case, but using display: table on the parent element worked in Chrome 44.Euphemia

© 2022 - 2024 — McMap. All rights reserved.