120

I have a page with a row of about 10 imgs. For readability of the HTML, I want to put a linebreak in between each img tag, but doing so renders whitespace between the images, which I do not want. Is there anything I can do other than break in the middle of the tags rather than between them?

Edit: Here is a screenshot of what I have so far. I would like the book spine images to display in random combinations, using PHP. This is why I need separate img tags.

Screenshot

Pang
  • 9,564
  • 146
  • 81
  • 122
Skilldrick
  • 69,215
  • 34
  • 177
  • 229
  • 1
    If you're using [Smarty](http://en.wikipedia.org/wiki/Smarty), you can use [`{strip}`](http://www.smarty.net/docs/en/language.function.strip.tpl). [Other template engines](http://en.wikipedia.org/wiki/Comparison_of_web_template_engines) should have similar tags. – user Mar 03 '14 at 23:02

17 Answers17

171

Sorry if this is old but I just found a solution.

Try setting the font-size to 0. Thus the white-spaces in between the images will be 0 in width, and the images won't be affected.

Don't know if this works in all browsers, but I tried it with Chromium and some <li> elements with display: inline-block;.

opatut
  • 6,708
  • 5
  • 32
  • 37
  • 10
    I can confirm this works in Firefox and Safari on Mac OSX, as well as Chrome. I can't believe this isn't the top answer. What a great idea, the only one I think truly answers the question/gives the asker what they're looking for. – Doug May 17 '12 at 19:49
  • 17
    Except that this will break layouts that are using `em` units. – devius May 10 '14 at 15:48
  • 7
    Setting `font-size` to 0 means you cannot use the `em` unit for scalable design after that point. For some people, this answer is useless. – LB-- Apr 08 '15 at 02:24
  • 3
    I'd also check out Chris Coyier's analysis on his page, under the section "Set the font size to zero", for some details on other instances when this might not work: https://css-tricks.com/fighting-the-space-between-inline-block-elements/ – Chris Kempen Jul 30 '15 at 10:46
  • 1
    And now that we have flexbox, all of this isn't required anymore :) Finally good layouting: https://css-tricks.com/snippets/css/a-guide-to-flexbox/ – opatut Jul 30 '15 at 11:30
  • Apart from using Flexbox, this is a smart trick that will solve it pretty well. However, personally I prefer actually removing the whitespace from the markup itself. Yes it's ugly that you have to break inside tags instead of between them but alas. Once you have done this you have a piece of HTML that works as expected out-of-the-box instead of having to hack it. Basically we have to change our understanding of HTML: Whitespace matters! A lot! – Stijn de Witt Nov 09 '15 at 20:37
81

You could use comments.

 <img src="..." alt="..."><!--
 --><img src="..." alt="..."><!--
 --><img src="..." alt="..."><!--
 --><img src="..." alt="...">

I'd worry about the semantics of having a series of images side by side though.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 1
    Good idea. The images are for decoration - does it matter semantically? – Skilldrick Jul 08 '09 at 09:54
  • 13
    Decorational pictures belong into the CSS, not into the HTML! – Konrad Rudolph Jul 08 '09 at 10:10
  • 12
    It depends how decorative the images are. A pretty border? That should be in CSS. A series of small photos of aeroplanes on a site about flying? Possibly content with no text equilivent needed. – Quentin Jul 08 '09 at 10:16
  • Please see the edit. I'm not sure of the best approach in this case. – Skilldrick Jul 08 '09 at 10:28
  • While this gets the job done, it doesn't keep code "beautiful". The other two solutions (font-size-0 and floating) are much better. – Mihai Alexandru Bîrsan May 22 '13 at 15:31
  • 1
    @MihaiAlexandruBîrsan - `font-size:0` is horrible in many cases because you loose inheritance. yes, you could use `rem` units, but still, your media queries will stop function for that element, and you will have to modify them all – vsync Sep 16 '14 at 08:34
  • 1
    I just discovered this little trick then saw your answer. Little bit of cruft but goes a long way to keep the HTML not all bunched up in one long line. – Nick Bedford Apr 08 '15 at 23:23
  • No need to use comments though (and comments bring their own bugs/problems in some browsers). You can just press ENTER with the cursor just before the closing tag. Can't show it in comments but basically just move the closing angular bracket `>` to the next line is all. Basically [Paul de Vrieze's answer](http://stackoverflow.com/a/2600295/286685) – Stijn de Witt Nov 09 '15 at 20:40
  • 1
    This was a nice trick to remove white space between two text elements. – mjoyce91 May 23 '17 at 18:52
72

You could use CSS. Setting display:block, or float:left on the images will let you have define your own spacing and format the HTML however you want but will affect the layout in ways that might or might not be appropriate.

Otherwise you are dealing with inline content so the HTML formatting is important - as the images will effectively act like words.

edeverett
  • 8,012
  • 33
  • 28
  • This is my favourite approach. Although, it can lead to sometimes wondering why text isn't showing up if I subsequently forget to define a font size for child elements. – Astrotim Jun 24 '13 at 09:12
39

Flexbox can easily fix this old problem:

.image-wrapper {
  display: flex;
}

More information about flexbox: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

William Grasel
  • 1,181
  • 1
  • 10
  • 11
  • 4
    Nowadays Flexbox is the cleanest and easiest solution. I think this should be the top answer here. `{ flex-direction: row; flex-wrap: nowrap; }` could be added for more readability. – Robert Kusznier Jan 16 '18 at 11:31
  • 1
    @RobertKusznier I disagree with specifying `flex-direction: row` and `flex-wrap: nowrap`, they are the default anyway. Keep it simple is usually best! Also, most of the times the user will in fact want `flex-wrap: wrap`. – Marc.2377 Dec 15 '19 at 10:37
31

You have two options without doing approximate stuff with CSS. The first option is to use javascript to remove whitespace-only children from tags. A nicer option though is to use the fact that whitespace can exist inside tags without it having a meaning. Like so:

<div id="[divContainer_Id]"
    ><img src="[image1_url]" alt="img1"
    /><img src="[image2_url]" alt="img2"
    /><img src="[image3_url]" alt="img3"
    /><img src="[image4_url]" alt="img4"
    /><img src="[image5_url]" alt="img5"
    /><img src="[image6_url]" alt="img6"
/></div>
Paul de Vrieze
  • 4,888
  • 1
  • 24
  • 29
13

After way too much research, trial and error I found a way that seems to works fine and doesn't require to manually re-set the font size manually on the children elements, allowing me to have a standardized em font size across the whole doc.

In Firefox this is fairly simple, just set word-spacing: -1em on the parent element. For some reason, Chrome ignore this (and as far as I tested, it ignores the word spacing regardless of the value). So besides this I add letter-spacing: -.31em to the parent and letter-spacing: normal to the children. This fraction of an em is the size of the space ONLY IF your em size is standardized. Firefox, in turn, ignores negative values for letter-spacing, so it won't add it to the word spacing.

I tested this on Firefox 13 (win/ubuntu, 14 on android), Google Chrome 20 (win/ubuntu), Android Browser on ICS 4.0.4 and IE 9. And I'm tempted to say this may also work on Safari, but I don't really know...

Here's a demo http://jsbin.com/acucam

Flatline
  • 1,036
  • 1
  • 10
  • 17
  • 1
    This is, in my professional opinion, the best solution. I tested it in Safari 5 and 6 on the desktop as well as Mobile Safari on a second gen iPad. It does work, however, when resetting letter-spacing in a child you also need to include word-spacing:normal; as Safari honors it. Great job, Flatline! – hndcrftd Feb 19 '13 at 19:19
  • 2
    The `word-spacing: -1em` style seems to make words overlap in the current version of Chrome. – Sam May 28 '13 at 04:16
  • @Sam sorry for the incredibly long delay :P I changed the word-spacing to 0.05, seems that new versions of firefox couldn't care less about that attribute, with letter-spacing is enough. I'm on Ubuntu right now, so I haven't tested it on windows. Here's the updated version http://jsbin.com/acucam/14 – Flatline Feb 20 '14 at 18:12
  • 2
    Did you try this with different fonts? This seems incredibly unconventional and very, very likely to break. – dudewad May 23 '16 at 17:41
13

I'm too late (i just asked a question and find thin in related section) but i think display:table-cell; is a better solution

<style>
img {display:table-cell;}
</style>

<img src="img1.gif">
<img src="img2.gif">
<img src="img3.gif">

the only problem is it will not work on IE 7 and Earlier versions but thats fixable with a hack

Vladimir
  • 1,602
  • 2
  • 18
  • 40
  • This is good, but only flaw is that elements loose their ability to float center if they parent have text-align:center; – Mladen Janjetovic Mar 12 '14 at 13:33
  • Works out, but in case you may wish to align img's to right side simply with text-align: right (on parent and without float) – Solution doesn't fit sadly. – Herr_Hansen Jul 03 '14 at 15:37
  • 2
    Might work, but some screenreaders interpret `display: table-*` semantically and read out as though the user were navigating a table. – Tarka Jun 22 '16 at 20:06
  • Nice solution !!!! white space removed. you can set the parent element as `inline-block`. – towry Jan 13 '21 at 02:40
5

Use CSS stylesheet for solving this problem like the following code.

[divContainer_Id] img
{
    display:block;
    float:left;
    border:0;
}

alt text http://rabu4g.bay.livefilestore.com/y1pWoAOBMiLumd2iQTAreYjQCDIkHImh2g_b2g9k4AnxtDNrCjvzL6bK7skG8QKMRNWkMG7N8e5Xm7pgle3tdRJd2y08CnnoPLy/Capture.PNG

Testing on Firefox 3.5 Final!

PS. your html should like this.

<div id="[divContainer_Id]">
    <img src="[image1_url]" alt="img1" />
    <img src="[image2_url]" alt="img2" />
    <img src="[image3_url]" alt="img3" />
    <img src="[image4_url]" alt="img4" />
    <img src="[image5_url]" alt="img5" />
    <img src="[image6_url]" alt="img6" />
</div>
3

Is there anything I can do other than break in the middle of the tags rather than between them?

Not really. Since <img>s are inline elements, spaces between these elements are considered by the HTML renderer as true spaces in text – redundant spaces (and line breaks) will be truncated but single spaces will be inserted into the character data of the text element.

Positioning the <img> tags absolutely can prevent this but I'd advise against this since this would mean positioning each of the images manually to some pixel measure which can be a lot of work.

abyx
  • 69,862
  • 18
  • 95
  • 117
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
2

Another solution would be to use unconventional line breaks in places of spaces. This is similar to the first couple answers, and is an alternative way of lining up elements. It also is a super-edge-optimization technique because it replaces spaces in your markup with carriage returns.

<img
src="image1.jpg"><img
src="image2.jpg"><img
src="image3.jpg"><img
src="image4.jpg">

Note that there are no spaces in any of that code. Places where spaces are normally used in HTML are replaced with carriage returns. It's less verbose than both using comments and using whitespace like Paul de Vrieze recommended.

Credit to tech.co for this approach.

Khan
  • 423
  • 4
  • 9
2

white-space: initial; Works for me.

Artur
  • 268
  • 4
  • 8
1

Inspired by Quentin's answer, you can also place the closing > next to the start of the next tag.

 <img src="..." alt="..."
 /><img src="..." alt="..."
 /><img src="..." alt="..."
 /><img src="..." alt="..."/>
Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145
0

The whitespace between the elements is only put there by the HTML editor for visual formatting purposes. You can use jQuery to remove the whitespace:

$("div#MyImages").each(function () {

    var div = $(this);
    var children= div.children();
    children.detach();
    div.empty();
    div.append(children);

});

This detaches the child elements, clears any whitespace that remains before adding the child elements back again.

Unlike the other answers to this question, using this method ensures that the inherited css display and font-size values are maintained. There's also no need to use float and the cumbersome clear that is then required. Of course, you will need to be using jQuery.

Oundless
  • 5,425
  • 4
  • 31
  • 33
  • 12
    Although this solution works. I think it is overkill to remove whitespace with javascript. – Lashae Apr 21 '13 at 15:03
  • 1
    Sorry but uggghhhh... One should aim to code HTML properly in the first place, not mangle it with JS after the fact. The latter just encourages sloppy practices with the idea that the [cough] miracle of JS can fix it later. – underscore_d Sep 28 '15 at 18:19
0

Personally I like the accepted answer stating there is no exact way of doing this, not with out using a trick of some form.

To me, it is an annoying issue with at times can make you waste an hour wondering why a row of check boxes for example are not all aligned correctly.. Hence i had to have a quick google and myself check if there was a css rule that i have not remembered... but seems no :(

As for the next best answer, of using font-size... to me this is a nasty hack that will bite you later on wondering why your text is not showing.

I generally develop a lot with PHP and in the case of where i am generating a grid of check boxes, the PHP generated content removes this problem as it does not insert any spacing/breaks.

Simply, i would suggest either having to deal with the images all being on a single line together or using a server side script to generate the content/images.

Angry 84
  • 2,935
  • 1
  • 25
  • 24
0

Instead of using to remove a CR/LF between elements, 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.

0

Lots of creative solutions here... I think everyone would agree that flex is the way to go if you are comfortable using flex for layout.

I ran into an issue recently where there was extra white space added to a list and it's anchor elements...

no white space:

<ul>
<li><a>link</a><span>icon</span></li>
</ul>

white space:

<ul>
<li>

  <a>link</a>

  <span>icon</span>

</li>
</ul>

In the application, a pseudo selector adds a bullet to each list element, but the bullet spacing is inconsistent between each list that has extra white space versus no extra white space. This creates a problem when trying to style the list content and bullet especially during text wrapping.

To fix, I displayed each li as a flex object and the white space gets removed without needing to remove it from the actual HTML. Note, you can also try using display: table; but it only works in Chrome and not Firefox.

ul li {
display: flex;
}

See code demo. Hope this helps.

ul {
  border: 1px solid gray;
  list-style: none;
  margin: .5em 0;
  padding: 1em;
  width: 140px;
}

ul li {
  margin: 5px 0 5px 15px;
}

ul li::before {
  content:"\00BB" !important;
  margin-left: -12px;
}

ul li a {
  color: #006699;
  font-size: 1em;
  font-weight: 500;
  line-height: 1.4em;
  text-decoration: underline;
}

ul.removewhitespace li {
  display: flex;
  width: min-content;
}

ul.removewhitespace li span {
  display: flex;
  flex: 0 1 100%;
  align-self: end;
  margin-left: -.1em;
}

.icon-check {
  content: "";
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-check-circle-fill' viewBox='0 0 16 16'%3E%3Cpath d='M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z'/%3E%3C/svg%3E") no-repeat center 0;
  background-size: auto;
  background-size: 15px;
  display: inline-block;
  width: 17px;
  height: 17px;
  vertical-align: middle;
}
<ul class="removewhitespace">
<li>
&nbsp;
<a href="#">Remove whitespace in this list with flex.</a><span class="icon-check"></span></li>
</ul>

<ul>
<li>
&nbsp;
<a href="#">Leave the whitespace in this list as is.</a><span class="icon-check"></span></li>
</ul>
jottin
  • 241
  • 1
  • 9
-1

Semantically speaking, wouldn't it be best to use an ordered or unordered list and then style it appropriately using CSS?

<ul id="[UL_ID]">
    <li><img src="[image1_url]" alt="img1" /></li>
    <li><img src="[image2_url]" alt="img2" /></li>
    <li><img src="[image3_url]" alt="img3" /></li>
    <li><img src="[image4_url]" alt="img4" /></li>
    <li><img src="[image5_url]" alt="img5" /></li>
    <li><img src="[image6_url]" alt="img6" /></li>
</ul>

Using CSS, you'll be able to style this whatever way you want and remove the whitespace imbetween the books.

Cyfer13
  • 369
  • 7
  • 17