Is there any way to remove the extra space displayed at the bottom of an HTML List Item tag without setting a fixed height on the list item? I.e. I would like the list item to wrap to its content.
The following code shows 3 images in a horizontal list but the height of each li tag is 4px more than the image. I would like it to wrap around the image i.e. to have the same width and height. The width is currently the same but I just can't get the height to match.
HTML:
<ul>
<li><img alt="img1" src="img1.jpg" /></li>
<li><img alt="img2" src="img2.jpg" /></li>
<li><img alt="img3" src="img3.jpg" /></li>
</ul>
CSS:
li
{
display:block;
float:left;
margin:0;
padding:0;
background-color:Yellow;
}
This is your code: http://jsfiddle.net/23LcK/
The gap is nothing to do with the lis. It's the space reserved for descenders in letters like g and p (because the imgs are inline elements).
You can remove it with any of these applied to li img:
display: block: http://jsfiddle.net/23LcK/1/
vertical-align with top or bottom: http://jsfiddle.net/23LcK/2/
Set line-height:0; on the LI
li {
line-height: 0;
}
Here's a jsfiddle to prove that it works - http://jsfiddle.net/jm9Tj/
This should do it for you.
ul{margin-bottom:0}
li is wrapped in ul, which by default has some padding. Therefore as #Michael said, you have to zero out the padding of the ul element.
To avoid these problems, always try to use reset.css.
FYI: Browsers apply a default CSS on web pages. That's why you see h1 elements that big when there is no CSS in your site. Because browsers have a default CSS. And since browsers come from different companies, they have different default CSS. For example, a browser may use 10px of margin for paragraphs, while another browser user 12px. This means that you have always inconsistencies in your design. But a CSS reset is made of some general rules that removes these default CSS styles.
li img {
vertical-align: bottom;
}
There is probably a default margin or padding on the img element in the browser you are using. You can remove this using something like this:
li img {
margin: 0;
padding: 0;
}
As different web browsers use different default styles it's recommended that you use a reset stylesheet. This sets a whole load of stuff to sensible defaults so you get more consistent styling across browsers. Because it resets everything to sensible defaults you should always load the reset stylesheet before any other stylesheets.
As #Saeed mentioned there is a good reset stylesheet as well as more information on why you should use them here.
Related
I have a problem with very simple HTML markup, which is rendered different in Chrome and Firefox. I'm wondering whether it is a bug in one of them.
The code is as simple as:
<ul>
<li>
<img />
</li>
</ul>
The problem is that in Chrome the <li /> element has some padding at the top, but only if its content is an image. There is no problem with e.g. text.
Example fiddle: https://jsfiddle.net/8c4rujvu/1/
img {
display: block;
width: 500px;
}
li {
border: 1px solid #f00;
}
<ul>
<li>
<img src="http://www.w3schools.com/css/trolltunga.jpg">
</li>
<li>
<img src="http://www.w3schools.com/css/trolltunga.jpg">
</li>
<li>Some text</li>
</ul>
This is how it displays in Firefox (50.0.2):
And in Chrome (55.0.2883.75 m):
What seems to be a problem here?
This is due the default browser / user agent styling difference for display: list-item.
As a fix, you can use inline-block and vertical-align:top (or even just vertical-align: top) for the img to get common behaviour - see demo below:
img {
display: inline-block;
vertical-align: top;
width: 500px;
}
li {
border: 1px solid #f00;
}
<ul>
<li>
<img src="http://www.w3schools.com/css/trolltunga.jpg">
</li>
<li>
<img src="http://www.w3schools.com/css/trolltunga.jpg">
</li>
<li>
Some text
</li>
</ul>
A related question you may want to look at: Why alignment mark list is different on WebKit when using :before height?
Why this happens?
Given that other browsers do not agree with chrome on this, this clearly looks like a bug and it is. See this open bug documented in Chromium Bug Tracker:
Table inside list item rendered at wrong position(Example URL: http://jsfiddle.net/P8Ua7/)
See excerpts from one of the comments in the bug:
Not limited to tables. Putting a flexbox inside a list-item gives the
same result. It also happens if you have replaced content displayed as
block.
The OP has an image (which is an inline replaced element) displayed as block!
Here is another bug you may want to check out.
This issue can simply fix float:left property too , check this fiddle
https://jsfiddle.net/9wp619xz/
check with the bug details Fixing Google Chrome compatibility bugs in websites - FAQ
https://www.chromium.org/Home/chromecompatfaq
img {
float:left;
width: 500px;
}
li {
border: 1px solid #f00;
float:left;
width:100%;
}
<ul>
<li>
<img src="http://www.w3schools.com/css/trolltunga.jpg">
</li>
<li>
<img src="http://www.w3schools.com/css/trolltunga.jpg">
</li>
<li>Some text</li>
</ul>
It is usually due to browsers default styling. In order to fix this issue, i recommend using a normalize css stylesheet or by adding your own css for the element.
The solution is two-fold.
Setting the image to display: inline solves the empty line above the image. This empty line is a nasty bug in Chrome. This bug makes it effectively impossible to use/start with a non-inline element in a default list item. A very big deal if you ask me.
Adding vertical-align: top places the list marker on the top (which is where you probably want it to go). This also removes the unwanted space below the inline image. The list marker placement and the white space below the inline element are not bugs. This is expected behaviour.
This would result into the following (simple) work-around for the OP:
img {
width: 500px;
vertical-align: top;
/* display: inline; *//* This is default, thus can be omitted */
}
li {
border: 1px solid #f00;
}
https://jsfiddle.net/8c4rujvu/3/
This is caused by the two different approaches these two browsers take while rendering a UL / LI element. I think that is clear from the start :)
The issue here is not how inline elements behave!
The issue here is how list-style properties behave in these two browsers!
If you notice that, the size of gap is 18px, which is default line height in chrome! If you increase the font-size for the li then size of dot marker will also increase so as the distance of image from top edge of div.
If Firefox, that dot marker, or list-style-type component act as the absolute positioned element, thus any element after simply begin from the li top-left edge as expected.
But in Chrome, that dot marker, or list-style-type component act as the inline element, and like any other inline element will allow an inline/floating element to get in same line as itself. Thus text which is inline by nature began next to the dot! This applies also for image, button, link, span or any such elements!
Now what you feel as an issue is perfectly normal behaviour for those elements. Even If two elements are floating or inline, if they can not get in horizontal width of parent, the latter element fall down to next line! Similar is the case with display:block elements as they by default start on a new line!
In your example images have display:block, thus they will always begin on new line! But even if you remove that property, still image are quite big to fit in parent, thus it'll fall down & show a gap. (This is for smaller screens only, on larger screen this won't be an issue for inline-block image)
Again, weird part is that, div acts a inline element in this case, even if you give the width above 100%! From this I concluded that, if wrapping of content is possible then that element begin on new line but if content can not wrapped then it starts on a new line!
Note:
This is based on my observations & past experience! If anybody have links to official documentation for this case please paste if here. Also any suggestion to improve this answer are welcome.
I've updated your JSFiddle with more examples: https://jsfiddle.net/8c4rujvu/5/
Try this code for you HTML
ul li {
display:block;
}
img {
display: block;
width: 500px;
}
li {
border: 1px solid #f00;
display:block;
}
<ul>
<li><img src="http://www.w3schools.com/css/trolltunga.jpg"></li>
<li>
<img src="http://www.w3schools.com/css/trolltunga.jpg">
</li>
<li>
Some text
</li>
</ul>
I write the next jsfiddle:
http://jsfiddle.net/alonshmiel/Ht6Ym/2409/
I try to put the ul in the left side:
I tried to do:
margin-left:0px;
float: left;
but it doesn't work.
any help appreciated!
You can add:
ul#advancedTargeting {
padding-left: 0;
}
Updated Fiddle
It's because some browsers has some default styles for HTML elements.
You can reset your padding-left value of your ul to default 0 using above code.
It's a good habit to use a css reset script to reset all the default styles applied by browsers to make your css compatible with various of browsers. You can find it from cssreset.com
You should set:
padding-left:0px;
http://www.w3schools.com/css/css_boxmodel.asp - check this to get a clear picture.
here is the solution, just use padding-left:0;
Your <ul> element is positioned as fixed and has a left: 55px; inline style.
Change that to left: 0; at first. Or avoid using fixed positioning if you don't want to remove the element from document normal flow (to get the float property to work).
Also, web browsers apply a left padding on the HTML list elements, such as <ul> and <ol>. You need to reset the padding as padding-left: 0.
However, it's better to reset all the default user agent stylesheets by using a CSS reset.
Either a tiny one:
* { padding: 0; margin: 0;}
Or a well-known version.
UPDATED DEMO.
So I have a navigation menu that is generated by my CMS:
The menu's HTML is straightforward (edited for clarity):
<ul>
<li>Journal</li>
<li>Art</li>
<li>Work</li>
</ul>
I want the items to show up as hand-written text, in keeping with the general theme of the site, using separate PNG files for each menu item.
To do that, I used the CSS content property like so:
#headerNav .nav li a[href="/_site/en/journal/"]
{ content: url(/path/to/image.png); }
And it worked great! The HTML text of each item was replaced by the correct image:
However, alas, then I learned not every browser supports the content property on selectors other than :before and :after! Chrome and Safari do it, but Firefox doesn. However when I use :before, the HTML node isn't replaced, but the image is added:
How do I work around this?
What didn't work:
Making the <a> element display: none removed the :before part as well.
Making the <a> element position: absolute and moving it elsewhere won't work either.
Making the <a> element width: 0px screws up the layout because the images added through content aren't in the document flow.
What I don't want to do:
Of course I can output the images by hand but I want to work with the HTML the CMS is giving me, which is <li>s with text in them.
Any solution involving background-image would require me to specify each item's width and height in the style sheet, which I would like to avoid for the purposes of this question.
Turning the handwriting into a font is not an option.
Using JavaScript to replace the items on the fly is not an option. This needs to work using pure HTML and CSS.
Since you are doing this into a navigation bar you should have a fixed height making the next method possible to work:
First insert the image as content on the :before element and make it display:block to push the actual text of the a tag below.
li a:before {
content:url(http://design.jchar.com/font/h_1.gif);
display:block;
}
Then hide that text with a fixed height on your a tag:
li a{
height:50px;
overflow:hidden;
}
The Working Demo
Answer was answered before OP added the line
Any solution involving background-image would require me to specify
each item's width and height in the style sheet, which I would like to
avoid for the purposes of this question.
So if anyone interested in background-image solution can refer this, else can simply skip.
Am not sure how optimum solution I am suggesting is, but surely you can use background-image for each a element, using nth- pseudo, and set the fonts color to transparent, or use text-indent property with overflow: hidden;
So it will be something like
nav ul li {
display: inline-block;
}
nav ul li:nth-of-type(1) a {
background-image: url(#);
display: block;
width: /* Whatever */ ;
color: transparent;
text-indent: -9999px; /* Optional */
overflow: hidden;
font-size: 0; /* Optional, some people are really sarcastic for this */
/* Below properties will be applicable if you are going for sprite methods */
background-position: /* Depends */ ;
background-size: /* If required */ ;
}
The reason why I would suggest you is :-
Advantages :
Cross browser compatible
Can you sprite methods to cut down http requests to request image for each tab
Also, you are not losing the text which is between the a tags, which is really good as far as screen readers are concerned.
Disadvantages :
Set custom width for each
Note: If you are going for a sprite solution, than background-position is anyways a must property to be used, so be sure you check out the support table first, before opting the sprite method.
Credits - For support table
I would put PNG images into img tag and then set alt attribute.
<ul>
<li><img src="journal.png" alt="Journal"/></li>
<li><img src="art.png" alt="Art"/></li>
<li><img src="work.png" alt="Work"/></li>
</ul>
This question already has answers here:
How to remove the space between inline/inline-block elements?
(41 answers)
Closed 7 years ago.
How to you get rid of the white space between list items? I am trying to make it so that the images are right next to each other. Even though I have set the styling to margins: 0;, they are still separated.
CSS
ul.frames{
margin: 20px;
width: 410px;
height: 320px;
background-color: grey;
float: left;
list-style-type: none;
}
ul.frames li {
display:inline;
margin: 0;
display: inline;
list-style: none;
}
ul.frames li img {
margin: 0 0 0 0;
}
HTML
<li>
<img id="myImg" src="img.jpg" width="102.5px" height="80px"/>
</li>
<li>
<img id="myImg2" src="img.jpg" width="102.5px" height="80px"/>
</li>
<li>
<img id="myImg3" src="img.jpg" width="102.5px" height="80px"/>
</li>
<li>
<img id="myImg4" src="img.jpg" width="102.5px" height="80px"/>
</li>
Updated Sept. 1st, 2014
In modern browsers, flex-box is the preferred method of doing this. It's as simple as:
ul {
display: flex;
}
See a JSFiddle here.
For legacy browser support refer to the other options below, which are still just fine, albeit slightly more complex.
Though each of the other answers gives at least one good solution, none seem to provide all of the possibilities. And that's what I'll try to do here.
Firstly, to answer your implicit question of why there's spacing, it's there because you've set your LIs to display as inline elements.
inline is the default display value for text and images in all of the browsers that I know of. Inline elements are rendered with spacing between them whenever there's whitespace in your code. This is a good thing when it comes to text: these words that I've typed are spaced apart because of the space I've included in the code. And there's also space between each line. It's this very behavior of inline elements is what makes text on the web readable at all.
But sometimes we want non-text elements to be inline to take advantage of other properties of this display style. And this typically includes a desire for our elements to fit snugly together, quite unlike text. And that seems to be your problem here.
Without further ado, here are all the ways I know of to get rid of the spacing:
Keeping them inline
(Not recommended) Apply negative margin to the LIs to move them over.
li { margin: -4px; }
Note that you'll need to 'guess' the size of a space. This isn't recommended because, as Arthur excellently points out in the comments below, users can change the Zoom of their browser, which would more than likely mess up the rendering of your code. Further, this code requires too much guesswork and calculation. There are better solutions that work under all conditions.
Get rid of the whitespace
<li>One</li><li>Two</li>
Use comments to make the whitespace a comment JSFiddle
<li>One</li><!--
--><li>Two</li>
Skip the closing tag (HTML4 valid / HTML5 Valid) JSFiddle
<li>One
<li>Two
Put the whitespace in the tag itself (Note: Early Internet Explorers will not like this)
<li>One</li
><li>Two</li
>
Take advantage of the fact that the spacing between the elements is calculated as a percentage of the font size of the parent. Consequently, setting the parent's font size to 0 results in no space. Just remember to set a non-zero font-size on the li so that the text itself has a nonzero font size. View on JSFiddle.
Floating them
Float them instead. You'll probably want to clearfix the parent if you do this.
li { float: left; display: block; }
Incredible but no one here has provided the proper solution for this problem.
Just do this:
ul.frames {
font-size: 0;
}
ul.frames li {
font-size: 14px; font-size:1.4rem;
display: inline;
}
Keep in mind that we won't always have access to modify the markup. And trying to remove the spaces from the <li>s with JavaScript would be totally unnecessary when the solution is simply two font-size properties.
Also, floating the <li>s introduces another potential problem: You wouldn't be able center and right align the list items.
If you try to do float:right; on the <li>s then their order will be swapped, meaning: the first item in the list would be last, the second item is the one before the last, and so on.
Check out this other post here in SO: A Space between Inline-Block List Items
You should just remove all the spaces in the ul tags just like this: http://jsfiddle.net/dFRYL/3/
Since the <li> elements are inline, in you write spaces in or between them you will have spaces displayed.
The reason you get the spaces is because you have spaces between the elements (line break)
<ul>
<li>One</li><li>
Two</li><li>
Three</li>
</ul>
You can use negative margins like this:
margin-right: -4px;
margin-bottom: -4px;
Take a look here.
It also works up and down, I added another one to show that here.
Using display:inline; causes whitespace in your HTML to create whitespace when displaying the HTML.
There are two solutions to this:
1) Change how you make them appear inline, I would recommend using floats on all of the list items, then using a clearfix of sorts.
2) Remove all whitespace between your list items, e.g.
<li><img id="myImg" src="http://stephboreldesign.com/wp-content/uploads/2012/03/lorem-ipsum-logo.jpg" width="102.5px" height="80px"/></li><li><img id="myImg2" src="http://stephboreldesign.com/wp-content/uploads/2012/03/lorem-ipsum-logo.jpg" width="102.5px" height="80px"/></li><li><img id="myImg3" src="http://stephboreldesign.com/wp-content/uploads/2012/03/lorem-ipsum-logo.jpg" width="102.5px" height="80px"/></li><li><img id="myImg4" src="http://stephboreldesign.com/wp-content/uploads/2012/03/lorem-ipsum-logo.jpg" width="102.5px" height="80px"/></li>
Personally I would recommend option 1 (I hate display: inline)
here is my attempt at it. Hope it helps. As Sean Dunwoody mentioned, white space in your html can be a cause of the space, but I've floated the li and made the image to display:block;. Left comment on where I made changes. Hope it helps: http://jsfiddle.net/FJ3nV/
Here my small but main changes:
/*
* Added float left
*/
ul.frames li {
margin: 0;
list-style: none;
float:left;
}
/*
* Moved inline sizing here just to clear up obtrusive html.
* Added display block.
*/
ul.frames li img{width:102px; height:80px; display:block;}
I would change your li elements to inline-block.
One person did not recommend
li { margin: -4px; }
But making a slight change to it will cause it to work even when the font size changes or when the browser zooms in
li{ margin-right: -0.25em; }
That should fix that white space problem completely. However, if you are using a poorly designed font-face that doesn't follow correct letter-height standards then it may cause a problem. However those are harder to find and most of the fonts google hosts don't have that issue.
I've been trying to get this horizontal navigation sorted for the past few hours now and nothing is working. I've tried reset.css stylesheets, *{padding: 0; margin: 0) etc. and I still have gaps inbetween my image links.
You see, the navigation is made up of an unordered list of image links displayed inline, but there are gaps in between each image, left, right, top and bottom and I can't see why. It's the same in all browsers.
Here is a link to the page, and so source: Beansheaf Temporary
Link to css: http://pentathlongb-yorkshire.co.uk/tomsmith/Beansheaf/styles/fund2.css
The rest of the site is obviously still not done, it's just the navigation I'm worried about right now.
To avoid floating the navigation lis, you've got -at least- two options to remove the spaces between inline elements.
<ul>
<li><img src="../hotel.jpg" /></li
><li><img src="../foodDrink.jpg" /></li
><li><img src="../meetingsConferences.jpg" /></li>
</ul>
Note that the closing </li> tag is closed on the subsequent line (except for the last one), which is valid and maintains readability (for me, at least).
The other option is slightly messier
<ul>
<li><img src="../hotel.jpg" /></li><!--
--><li><img src="../foodDrink.jpg" /></li><!--
--><li><img src="../meetingsConferences.jpg" /></li>
</ul>
And just uses html comments <!-- ... --> to comment-out the spaces that would otherwise be collapsed into a single space.
I do wish there was some way of specifying (for example):
ul li img {whitespace: none-between; }
Another approach, avoiding floats, is to set the font-size on the container to 0, and then re-set it back up for the LIs, like this:
#mainNav
{ font-size: 0}
#mainNav li
{
display: inline;
list-style-type: none;
font-size: 1em
}
the gap below images links is due to the image being aligned with base text line by default, you can solve it simply declaring
li img {
vertical-align:bottom;
}
magic!
Try removing all spaces and line-breaks between the li elements.
Because you are displaying them inline, spaces in the HTML will act as if they were a space in inline text and cause a gap to be left when rendering.
Add
#mainNav li {
float:left;
}
to your CSS.
It is because a new line in an HTML document will be interpreted as a space in the printed content. Since all of your 'li' elements are on new lines, it is adding a space between each of them. Make sure you display them as block elements and float them to the left so they run evenly together.
You can float the list elements, then the white space doesn't interfer:
#mainNav li
{
float: left;
list-style-type: none;
}
I use the line-height attribute on the li tag to fix this.
ul li { line-height:0; }
Best solution to this comes from http://www.cssplay.co.uk/menus/centered.html. And quoting:
All we need to do is enclose the ul tag in an outer container that has a width of 100% and overflow set to hidden.
The <ul> tag is then styled with a relative position and floated left with a left position of 50%.
Finally the <li> tag is also styled with a relative position, floated left but this time with a right position of 50%.
...and that as they say is all that is needed.
if you are using xslt to show these element, you should make the following:
<xsl:template match=".//text()">
<xsl:value-of select="normalize-space(.)" />
</xsl:template>