Why do my list item bullets overlap floating elements
Asked Answered
F

23

172

I have an (XHTML Strict) page where I float an image alongside regular paragraphs of text. All goes well, except when a list is used instead of paragraphs. The bullets of the list overlap the floated image.

Changing the margin of the list or the list items does not help. The margin is calculated from the left of the page, but the float pushes the list items to the right inside the li itself. So the margin only helps if I make it wider than the image.

Floating the list next to the image also works, but I don't know when the list is next to a float. I don't want to float every list in my content just to fix this. Also, floating left messes up the layout when an image is floated to the right instead of left of the list.

Setting li { list-style-position: inside } does move the bullets along with the content, but it also causes lines that wrap to start aligned with the bullet, instead of aligned with the line above.

The problem is obviously caused by the bullet being rendered outside the box, the float pushing the contents of the box to the right (not the box itself). This is how IE and FF handle the situation, and as far as I know, not wrong according to the spec. The question is, how can I prevent it?

Farmland answered 2/4, 2009 at 15:17 Comment(0)
F
292

I have found a solution to this problem. Applying an ul { overflow: hidden; } to the ul ensures that the box itself is pushed aside by the float, instead of the contents of the box.

Only IE6 needs an ul { zoom: 1; } in our conditional comments to make sure the ul has layout.

Farmland answered 2/4, 2009 at 15:37 Comment(11)
+1: Great CSS, I searched like a crazy for a GOOD VERSATILE soltuion and here it is on SO. The only small draw back is that zoom property does not validate CSS, but I tested and on IE7, IE8 is not necessary, so it's probably just for IE6.Bovid
Perfect, i've been looking for a solution for this problem for ages really and it's soooooo ridiculously simple to fix ... thanks Kamiel, if I owe you a beer, several actually :)Middle
In order to get this to really work I had to also apply: ul, ol { overflow: hidden; padding-left: 40px; margin-left: 0; } ol li, ul li { list-style-position: outside; padding-left: 0; } This forced consistent rendering across browsers and forced IE6 to show the bullets. The bullets were hidden otherwise. The ul { zoom: 1; } was still required in the ie6 specific settings as well.Aoudad
Adding list-style-position:inside; per @annakata's answer + this worked for me!Downthrow
So ridiculously simple solution to such ridiculous BUG in MSIE.Mikaela
It isn't a perfect solution. As Blazemonger mentioned blow, if the image is small and the list is very long, the list won't flow around the floating image. The list will has a huge margin from top to the end if the image is very wide.Tsai
Nice! I can't see how this makes any sense, though, when reading the W3C doc on overflow: w3schools.com/cssref/pr_pos_overflow.aspRecoil
Another strange issue is that if you're in a contenteditable in IE, this makes the OL/UL have resizers on it when you click it. Ugh.England
Note, this also breaks Bootstrap drop downs!Decolonize
It worked 🤦, I can't believe it. That Edge still has this bug, after another ten years!Sporran
Thank you @Kamiel Wanrooij. It works in Drupal perfectly dl, ol, ul { overflow: hidden;}Poul
V
71

Adding an improvement to Glen E. Ivey's solution:

ul {
    list-style: outside disc;
    margin-left: 1em;
}
ul li {
    position: relative;
    left: 1em;
    padding-right: 1em;    
}​

http://jsfiddle.net/mblase75/TJELt/

I prefer this technique, since it works when the list needs to flow around the floating image, while the overflow: hidden technique will not. However, it's also necessary to add padding-right: 1em to the li to keep them from overflowing their container.

Vulva answered 10/8, 2012 at 14:48 Comment(7)
I prefer this fix too as the top one broke my Twitter Bootstrap drop downs and it took me forever to figure out that the above method was the culprit.Nipha
Thanks for this. Applying overflow: hidden; to the container UL prevented the text in the individual line items from properly running around the floated block. This solution did the trick!Cao
I ran into a minor but critical issue with this solution, and I'd like to suggest an addition to your improvement. I'm not sure why, but when you add position: relative; to the line item, it creates a stacking problem with the floated content. I found (in Chrome and Firefox) that it was hard to hover and click on links in the floated content. The fix for me was to add position: relative; z-index: 1; to the floated element, which seemed to resolve the stacking issue.Cao
Unfortunately, on IE 10, the bullets overlap with the floating element.Hubbub
If there is a floating box containing links at right side of this list, the links won't be clickable. How can I fix it? Thanks.Tsai
See the above z-index fix, I think.Vulva
Whereas ul {overflow: hidden;} solved this issue in all browsers, above solution was the only working remedy for this issue with Prince XML, a XHTML+CSS3 to PDF converter.Stress
E
39

This is where the "display" property comes into its own. Set the CSS below to make the list work alongside the floated content.

display: table; works alongside floated content (filling the gap) but without hiding content behind it. Much like a table does :-)

.img {
  float: left;
}

.table {
  display: table;
}
<img class="img" src="https://via.placeholder.com/350x350" alt="">
<ul>
  <li>Test content</li>
  <li>Test content</li>
  <li>Test content</li>
</ul>
<ul class="table">
  <li>Test content</li>
  <li>Test content</li>
  <li>Test content</li>
</ul>

EDIT: Remember to add a class to isolate which lists you wish to do this for. E.g. "ul.in-content" or more generally ".content ul"

Erg answered 2/7, 2012 at 11:56 Comment(0)
D
30

Try list-style-position: inside to change the layout of the bullets.

Delores answered 2/4, 2009 at 15:26 Comment(5)
list-style-position:inside would be a great solution, but causes lines that wrap to start aligned with the bullet, instead of aligned with the line above.Bovid
overflow: hidden; dont work for my left float image, but list-style-position:inside did it ! thanksLamartine
This was the only solution that still wrapped content in IE for me. Thanks!Civics
This is a great solution for when content is floating between your bullets and the bullet content.Racism
This should be the chosen answer.Leguminous
S
21

Why overflow: hidden works

The solution is as easy as:

ul {overflow: hidden;}

A block box with overflow: other than visible establishes a new block formatting context for its contents. W3C recommendation: http://www.w3.org/TR/CSS2/visuren.html#block-formatting

Example

The buttons on my website, which are <li> in disguise, are made like this. Make the viewport (window) of your browser smaller to see the indenting in action.

My website as an example

Related answers

Article with examples

Stress answered 6/8, 2014 at 14:14 Comment(1)
thanks for explaining why this works (isn't mentioned in the accepted solution)Forcier
M
19

At http://archivist.incutio.com/viewlist/css-discuss/106382 I found a suggestion that worked for me: style the 'li' elements with:

position: relative;
left: 1em;

Where you replace "1em" with the width of the left padding/margin that your list items would have if the float weren't present. This works great in my application, even handling the case where the bottom of the float occurs in the middle of the lists--the bullets shift back over to the (local) left margin just right.

Motherinlaw answered 26/2, 2010 at 20:57 Comment(3)
Fantastic solution, works like a charm! Though I had to get my hands dirty with IE7 as it failed to show list item numbers on lists that were not next to a floated element.Balanchine
@Balanchine What is your solution for IE7?Cleavage
IE7 needed an extra margin-left on the list items. See this fiddle jsfiddle.net/maryisdead/wu6ew/5 and take note of the two IE7 hacks. Sorry for not adding this earlier on.Balanchine
E
19

By adding overflow: auto; to your ul works for me at least.

Update

I've updated my jsfiddle to visualize what's going on. When having the ul beside the floating img, the content of the ul will be pushed by the float, but not the actual container. By adding overflow: auto the whole ul-box will be pushed by the float instead of only the content.

Elderly answered 30/4, 2012 at 8:10 Comment(0)
M
13

You could assign position: relative; left: 10px; to the li. (You may additionally want to give it a margin-right: 10px;, otherwise it might become too wide on the right side.)

Or, if you want to use float for the ul -- as suggested by others -- you can probably stop the rest from floating right of the ul by using clear: left on the element that follows the ul.

Marionmarionette answered 3/5, 2010 at 17:13 Comment(1)
thanks chris, that position: relative worked. the problem that would arise from clearing the element after the ul is that the element would also clear the left floated div.Warbler
E
9

Disclaimer

Lists next to floated elements cause issues. In my opinion, the best way to prevent these sorts of floating issues is to avoid floating images that intersect with content. It'll also help when you have to support responsive design.

A simple design of having centered images between paragraphs will look very attractive and be much easier to support than trying to get too fancy. It's also one step away from a <figure>.

But I really want floated images!

Ok, so if you're crazy persistent enough to continue down this path, there are a couple techniques that can be used.

The simplest is to make the list use overflow: hidden or overflow: scroll so that the list is essentially shrink wrapped which pulls the padding back to where it's useful:

img {
  float: left;
}
.wrapping-list {
  overflow: hidden;
  padding-left: 40px;
}
<img src="http://placehold.it/100x100"/>
<ul class="wrapping-list">
  <li>lorem</li>
  <li>ipsum</li>
  <li>dolor</li>
  <li>sit</li>
  <li>amet</li>
</ul>

This technique has a few problems though. If the list gets long, it doesn't actually wrap around the image, which pretty much defeats the entire purpose of using float on the image.

img {
  float: left;
}
.wrapping-list {
  overflow: hidden;
  padding-left: 40px;
}
<img src="http://placehold.it/100x100"/>
<ul class="wrapping-list">
  <li>lorem</li>
  <li>ipsum</li>
  <li>dolor</li>
  <li>sit</li>
  <li>amet</li>
  <li>lorem</li>
  <li>ipsum</li>
  <li>dolor</li>
  <li>sit</li>
  <li>amet</li>
  <li>lorem</li>
  <li>ipsum</li>
  <li>dolor</li>
  <li>sit</li>
  <li>amet</li>
</ul>

But I really want wrapping lists!

Ok, so if you're even crazier more persistent and you absolutely must continue down this path, there's another technique that can be used to wrap the list items and maintain bullets.

Instead of padding the <ul> and trying to get it to behave nicely with bullets (which it never seems to want to do), take those bullets away from the <ul> and give them to the <li>s. Bullets are dangerous, and the <ul> just isn't responsible enough to handle them properly.

img {
  float: left;
}
.wrapping-list {
  padding: 0;
  list-style-position: inside;
}
.wrapping-list li {
  overflow: hidden;
  padding-left: 25px;
}
<img src="http://placehold.it/100x100"/>
<ul class="wrapping-list">
  <li>lorem</li>
  <li>ipsum</li>
  <li>dolor</li>
  <li>sit</li>
  <li>amet</li>
  <li>lorem</li>
  <li>ipsum</li>
  <li>dolor</li>
  <li>sit</li>
  <li>amet</li>
  <li>lorem</li>
  <li>ipsum</li>
  <li>dolor</li>
  <li>sit</li>
  <li>amet</li>
</ul>

This wrapping behavior can do weird things to complex content, so I don't recommend adding it by default. It's much easier to set it up as something that can be opted into rather than something that has to be overridden.

Each answered 26/2, 2015 at 20:20 Comment(1)
I like the second option, but the text actually starts with the bullet points on longer texts (2 rows) :-(Bayless
K
7

I am using this to solve this problem:

ul {
   display: table;
}
Kempis answered 2/9, 2013 at 11:51 Comment(0)
S
4

Try the following on your UL tag. This should take care of the bullets overlaying your image and you don't have to mess up your left allignment caused by list-position: inside.

overflow: hidden; 
padding-left: 2em; 
Separation answered 13/3, 2012 at 19:9 Comment(1)
I had to use this with Blazemonger's solution (#2 above). BLazemonger alone didn't work in IE 9-11 and Opera. With this, it works in all browsers. Kamiel's (#1) solution didn't work for me as it hid my bullets. Conflict with Bootstrap3 perhaps.Barghest
I
3

Struggled with this myself. Best I've managed is the following:

ul {
    list-style-position: inside;
    padding-left: 1em;
    text-indent: -1em;
}

The text is not actually indented but the bullet shows.

Intercolumniation answered 29/4, 2011 at 19:17 Comment(0)
C
3

After fighting with this interesting issue in several projects, and investigating why it happens, I finally believe I found both: a working and 'responsive' solution.

Here is the magic trick, live example: http://jsfiddle.net/superKalo/phabbtnx/

ul {
    list-style: none;
    position: relative;
    padding-left: 0; /* remove any left padding */
    margin-left: 0; /* remove any left margin */
    left: 35px;
}
li {
    padding-left: 0; /* remove any left padding */
    margin-left: 0; /* remove any left margin */
    text-indent: -19px; /* adjust as much as needed */
}
li:before {
    content: '•\00a0\00a0\00a0';
    color: #000; /* bonus: you can customize the bullet color */
}
Cruiser answered 4/2, 2015 at 10:52 Comment(1)
I added display: flex; to li, so that the bulletpoint is vertically centered, when i change the font-size of the :before part.Bayless
S
2

Edited to update based on OP's comment

ok, then just break it up into 2 divs nested together

ul  {background: blue; position:static;}
.therest {position:relative; width:100%}
.indent {float:left; }

<div class="therest">
<p>
Est tincidunt doming iis nobis nibh. Ullamcorper eorum elit lius me delenit. 
</p>
<hr />
<h3>Lorem</h3>
<div class="indent">
<ul>
<li>list element</li>
<li>list element</li>
<li>list element</li>
</ul> 
<div>
the rest now under the UL
</div>

try changing the ul li css to

ul {float:left; background: blue; }

Synectics answered 3/5, 2010 at 16:7 Comment(1)
thanks, that works, however, now the paragraphs below are floating up against the right side.Warbler
H
1

Working inside an LMS without access to head of doc, found it easier to go with margin-right: 20px as an inline style for the image. Which I owe to this site.

Herpes answered 7/9, 2011 at 22:10 Comment(0)
C
0

try this:

li{
    margin-left:5px;
}

If you want them to go left, just put in a -##px value.

Candis answered 3/5, 2010 at 16:11 Comment(0)
D
0

or you could do this:

 #content ul {
        background:none repeat scroll 0 0 #AACCDD;
        float:left;
        margin-right:10px;
        padding:10px;

and then remove all the styling from the li

Democracy answered 3/5, 2010 at 16:55 Comment(2)
floating the ul does indeed solve the problem, however, another problem arises... all paragraph elements that come after the ul get floated to the right of the ul.Warbler
gave you +1 for that...I was making an assumption here from looking at the link associated with this question that the <p> would be floating to the right of <ul>. Good catch.Democracy
E
0
width: 300px;
height: 30px;
margin-left: auto;
right: 10px;

margin-left: auto will cause the element itself to be right aligned. Set height and width of the element you want - in my it's a background image in a div inside

Etherize answered 11/2, 2011 at 20:20 Comment(0)
P
0

How about this?

ul{float:left; clear:right}
Pizarro answered 29/4, 2011 at 19:26 Comment(0)
R
0

You could try also floating the ul to the left, and define an appropriate width for it, so that it floats next to the image.

Something a little like this jsfiddle?

Rowlock answered 30/4, 2012 at 8:7 Comment(0)
F
0

I fixed it with

div.class-name ul {
  clear: both;
}
Foust answered 29/1, 2015 at 20:9 Comment(0)
A
0
width: auto; overflow: hidden;
Arriola answered 1/6, 2015 at 14:23 Comment(0)
A
-1

Add display:table; to ul:

ul{display:table;}
Arriola answered 1/6, 2015 at 14:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.