Pourquoi mes puces d'élément de liste chevauchent-elles des éléments flottants?

166

J'ai une page (XHTML Strict) où je flotter une image à côté de paragraphes de texte normaux. Tout se passe bien, sauf lorsqu'une liste est utilisée à la place de paragraphes. Les puces de la liste chevauchent l'image flottante.

La modification de la marge de la liste ou des éléments de la liste n'aide pas. La marge est calculée à partir de la gauche de la page, mais le flottant pousse les éléments de la liste vers la droite à l' intérieur d'li elle - même. Ainsi, la marge n'aide que si je la fais plus large que l'image.

Faire flotter la liste à côté de l'image fonctionne également, mais je ne sais pas quand la liste est à côté d'un flottant. Je ne veux pas faire flotter chaque liste de mon contenu juste pour résoudre ce problème. De plus, le flottement à gauche gâche la mise en page lorsqu'une image flotte vers la droite au lieu de la gauche de la liste.

Le réglage li { list-style-position: inside }déplace les puces avec le contenu, mais il amène également les lignes qui s'enroulent à commencer alignées avec la puce, au lieu d'être alignées avec la ligne ci-dessus.

Le problème est évidemment causé par le rendu de la balle à l'extérieur de la boîte, le flotteur poussant le contenu de la boîte vers la droite (pas la boîte elle-même). C'est ainsi que IE et FF gèrent la situation, et pour autant que je sache, pas mal selon les spécifications. La question est, comment puis-je l'empêcher?

Kamiel Wanrooij
la source

Réponses:

280

J'ai trouvé une solution à ce problème. L'application d'un ul { overflow: hidden; }sur le ulgarantit que la boîte elle-même est écartée par le flotteur, au lieu du contenu de la boîte.

Seul IE6 a besoin d'un ul { zoom: 1; }dans nos commentaires conditionnels pour s'assurer que la ulmise en page a.

Kamiel Wanrooij
la source
1
+1: Excellent CSS, j'ai cherché comme un fou une BONNE solution POLYVALENTE et la voici sur SO. Le seul petit inconvénient est que la propriété zoom ne valide pas le CSS, mais j'ai testé et sur IE7, IE8 n'est pas nécessaire, donc c'est probablement juste pour IE6.
Marco Demaio
14
Pour que cela fonctionne vraiment, je devais également appliquer: ul, ol {overflow: hidden; padding-left: 40px; marge gauche: 0; } ol li, ul li {position-style-liste: extérieur; padding-left: 0; } Cela a forcé un rendu cohérent à travers les navigateurs et a forcé IE6 à afficher les puces. Les balles étaient cachées autrement. Le ul {zoom: 1; } était également requis dans les paramètres spécifiques à ie6.
Mandrake
1
Solution tellement ridiculement simple à un tel BUG ridicule dans MSIE.
SF.
10
Ce n'est pas une solution parfaite. Comme Blazemonger l'a mentionné, si l'image est petite et que la liste est très longue, la liste ne circulera pas autour de l'image flottante. La liste aura une énorme marge du haut vers la fin si l'image est très large.
yang du
2
Agréable! Je ne vois pas en quoi cela a du sens, cependant, lors de la lecture de la documentation du W3C sur le débordement: w3schools.com/cssref/pr_pos_overflow.asp
MSC
66

Ajout d'une amélioration à la solution de Glen E. Ivey :

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

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

Je préfère cette technique, car elle fonctionne lorsque la liste doit circuler autour de l'image flottante, overflow: hiddencontrairement à la technique. Cependant, il est également nécessaire d'ajouter padding-right: 1emà la lipour les empêcher de déborder de leur conteneur.

Blazemonger
la source
Je préfère également cette solution, car celle du haut a cassé mes listes déroulantes Twitter Bootstrap et il m'a fallu une éternité pour comprendre que la méthode ci-dessus était la coupable.
Ian Hoar
2
Merci pour cela. Application du débordement: masqué; au conteneur UL empêchait le texte des éléments de campagne individuels de circuler correctement autour du bloc flottant. Cette solution a fait l'affaire!
jsdalton
1
J'ai rencontré un problème mineur mais critique avec cette solution, et j'aimerais suggérer un ajout à votre amélioration. Je ne sais pas pourquoi, mais lorsque vous ajoutez position: relative;à l'élément de campagne, cela crée un problème d'empilement avec le contenu flottant. J'ai trouvé (dans Chrome et Firefox) qu'il était difficile de survoler et de cliquer sur des liens dans le contenu flottant. Le correctif pour moi était d'ajouter position: relative; z-index: 1;à l'élément flottant, ce qui semblait résoudre le problème d'empilement.
jsdalton
7
Malheureusement, sur IE 10, les puces se chevauchent avec l'élément flottant.
Munawwar
1
Alors que ul {overflow: hidden;}ce problème a été résolu dans tous les navigateurs, la solution ci-dessus était le seul remède efficace à ce problème avec Prince XML , un convertisseur XHTML + CSS3 en PDF.
Serge Stroobandt
36

C'est là que la propriété "display" prend tout son sens. Définissez le CSS ci-dessous pour que la liste fonctionne avec le contenu flottant.

affichage: table; fonctionne avec le contenu flottant (comblant le vide) mais sans cacher le contenu derrière lui. Un peu comme une table :-)

.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: N'oubliez pas d'ajouter une classe pour isoler les listes pour lesquelles vous souhaitez faire cela. Par exemple "ul.in-content" ou plus généralement ".content ul"

martinedwards
la source
29

Essayez list-style-position: inside pour changer la disposition des puces.

Annakata
la source
3
list-style-position:insideserait une excellente solution, mais fait que les lignes qui s'enroulent commencent alignées avec la puce, au lieu d'être alignées avec la ligne ci-dessus.
Marco Demaio
débordement caché; ne fonctionne pas pour mon image flottante gauche, mais la position de style de liste: à l'intérieur l'a fait! merci
menardmam
C'était la seule solution qui enveloppait encore le contenu dans IE pour moi. Merci!
jordan314
C'est une excellente solution lorsque le contenu flotte entre vos puces et le contenu des puces.
TylersSN
Cela devrait être la réponse choisie.
Sleek Geek
18

Sur http://archivist.incutio.com/viewlist/css-discuss/106382, j'ai trouvé une suggestion qui a fonctionné pour moi: stylisez les éléments 'li' avec:

position: relative;
left: 1em;

Où vous remplacez "1em" par la largeur du remplissage / marge gauche que vos éléments de liste auraient si le flottant n'était pas présent. Cela fonctionne très bien dans mon application, même en traitant le cas où le bas du flottant se trouve au milieu des listes - les puces reviennent à la marge gauche (locale) juste à droite.

Glen E. Ivey
la source
2
Solution fantastique, fonctionne comme un charme! Bien que j'ai dû me salir les mains avec IE7 car il n'a pas montré les numéros d'élément de liste sur des listes qui n'étaient pas à côté d'un élément flottant.
maryisdead le
@maryisdead Quelle est votre solution pour IE7?
TJ.
IE7 avait besoin d'une marge supplémentaire à gauche sur les éléments de la liste. Voir ce violon jsfiddle.net/maryisdead/wu6ew/5 et prendre note des deux hacks IE7. Désolé de ne pas avoir ajouté cela plus tôt.
maryisdead
18

Pourquoi ça overflow: hiddenmarche

La solution est aussi simple que:

ul {overflow: hidden;}

Une boîte de bloc avec overflow:autre que visible établit un nouveau contexte de formatage de bloc pour son contenu. Recommandation W3C: http://www.w3.org/TR/CSS2/visuren.html#block-formatting

Exemple

Les boutons de mon site Web , qui sont <li>déguisés, sont faits comme ça. Réduisez la taille de la fenêtre (fenêtre) de votre navigateur pour voir l' indentation en action .

Mon site Web à titre d'exemple

Réponses connexes

Article avec exemples

Serge Stroobandt
la source
1
merci d'avoir expliqué pourquoi cela fonctionne (n'est pas mentionné dans la solution acceptée)
schellmax
17

En ajoutant overflow: auto;à vos ulœuvres au moins pour moi.

Mettre à jour

J'ai mis à jour mon jsfiddle pour visualiser ce qui se passe. Lorsque vous avez le ulcôté flottant img, le contenu du ulsera poussé par le flotteur, mais pas le conteneur réel. En ajoutant overflow: autol'ensemble, la ulboîte sera poussée par le flotteur au lieu de seulement le contenu.

Maehler
la source
13

Vous pouvez attribuer position: relative; left: 10px;au li. (Vous pouvez également lui donner un margin-right: 10px;, sinon il risque de devenir trop large sur le côté droit.)

Ou, si vous souhaitez utiliser floatpour le ul- comme suggéré par d'autres - vous pouvez probablement empêcher le reste de flotter à droite de l'ul en utilisant clear: leftl'élément qui suit l'ul.

Chris Lercher
la source
merci chris, cette position: relative travaillé. le problème qui résulterait de l'effacement de l'élément après ul est que l'élément effacerait également le div flotté gauche.
superUntitled
7

J'utilise ceci pour résoudre ce problème:

ul {
   display: table;
}
La vie est courte
la source
7

Avertissement

Les listes à côté des éléments flottants posent des problèmes. À mon avis, le meilleur moyen d'éviter ce type de problèmes flottants est d'éviter les images flottantes qui se croisent avec le contenu. Cela aidera également lorsque vous devrez prendre en charge la conception réactive.

Une conception simple consistant à centrer des images entre les paragraphes semblera très attrayante et sera beaucoup plus facile à supporter que d'essayer d'être trop sophistiquée. C'est aussi à un pas d'un <figure>.

Mais je veux vraiment des images flottantes!

Ok, donc si tu es fou assez persistant pour continuer dans cette voie, il y a des techniques de couple qui peuvent être utilisés.

Le plus simple est de faire en sorte que la liste utilise overflow: hiddenou overflow: scrollpour que la liste soit essentiellement réduite, ce qui ramène le remplissage là où il est utile:

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>

Cette technique présente cependant quelques problèmes. Si la liste devient longue, elle ne s'enroule pas réellement autour de l'image, ce qui va à l'encontre de l'objectif de l'utilisation floatde l'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>

Mais je veux vraiment emballer des listes!

Ok, donc si vous êtes encore plus fou, plus persévérant et vous devez absolument continuer sur cette voie, il existe une autre technique qui peut être utilisée pour envelopper les éléments de la liste et maintenir les puces.

Au lieu de remplir le <ul>et d'essayer de le faire se comporter correctement avec des balles (ce qu'il ne semble jamais vouloir faire), retirez ces balles du <ul>et donnez-les au <li>s. Les balles sont dangereuses, et le <ul>juste n'est pas assez responsable pour les gérer correctement.

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>

Ce comportement d'encapsulation peut faire des choses étranges sur du contenu complexe, je ne recommande donc pas de l'ajouter par défaut. Il est beaucoup plus facile de le configurer comme quelque chose qui peut être choisi plutôt que comme quelque chose qui doit être remplacé.

zzzzBov
la source
J'aime la deuxième option, mais le texte commence en fait par les puces sur les textes plus longs (2 lignes) :-(
Arany
4

Essayez ce qui suit sur votre étiquette UL. Cela devrait prendre en charge les puces superposées à votre image et vous n'avez pas à gâcher votre alignement gauche causé par list-position: inside.

overflow: hidden; 
padding-left: 2em; 
Joe
la source
J'ai dû l'utiliser avec la solution de Blazemonger (n ° 2 ci-dessus). BLazemonger seul ne fonctionnait pas dans IE 9-11 et Opera. Avec cela, cela fonctionne dans tous les navigateurs. La solution de Kamiel (n ° 1) n'a pas fonctionné pour moi car elle cachait mes balles. Conflit avec Bootstrap3 peut-être.
Leraa
3

J'ai lutté avec cela moi-même. Le mieux que j'ai réussi est le suivant:

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

Le texte n'est pas réellement en retrait mais la puce apparaît.

Stephen
la source
2

Modifié pour mettre à jour en fonction du commentaire d'OP

ok, puis divisez-le en 2 div imbriqués ensemble

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>

essayez de changer le css ul li en

ul {float: gauche; fond: bleu; }

ANC_Michael
la source
merci, cela fonctionne, cependant, maintenant les paragraphes ci-dessous flottent contre le côté droit.
superUntitled
2

Après avoir combattu ce problème intéressant dans plusieurs projets et étudié pourquoi cela se produit, je crois enfin avoir trouvé les deux: une solution fonctionnelle et «réactive» .

Voici le tour de magie, exemple en direct: 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 */
}
Kaloyan Kosev
la source
J'ai ajouté display: flex;à li, de sorte que la puce soit centrée verticalement, lorsque je change la taille de la police de la :beforepièce.
Arany
1

Travailler dans un LMS sans accès à la tête du document a trouvé plus facile à utiliser en margin-right: 20pxtant que style en ligne pour l'image. Ce que je dois à ce site .

Lynda Williams
la source
0

essaye ça:

li{
    margin-left:5px;
}

Si vous voulez qu'ils partent à gauche, entrez simplement une valeur - ## px.

Douglas
la source
0

ou vous pouvez faire ceci:

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

puis supprimez tout le style de la li

Reece
la source
1
flottant le ul résout effectivement le problème, cependant, un autre problème se pose ... tous les éléments de paragraphe qui viennent après le ul flottent à droite de ul.
superUntitled
vous a donné +1 pour cela ... Je supposais ici en regardant le lien associé à cette question que le <p> flotterait à droite de <ul>. Bonne prise.
Reece
0

Que dis-tu de ça?

ul{float:left; clear:right}
Adam Lynch
la source
0
width: 300px;
height: 30px;
margin-left: auto;
right: 10px;

margin-left: auto fera que l'élément lui-même sera aligné à droite. Définissez la hauteur et la largeur de l'élément souhaité - dans mon cas, c'est une image d'arrière-plan dans un div à l'intérieur

Nikolay Ivanov
la source
0

Vous pouvez également essayer de faire flotter le ulvers la gauche et définir unwidth , de sorte qu'il flotte à côté de l'image.

Quelque chose d'un peu comme ça jsfiddle ?

Houdmont
la source
0

Je l'ai réparé avec

div.class-name ul {
  clear: both;
}
Neal Garrett
la source
0
width: auto; overflow: hidden;
evan toder
la source
-1

Ajouter display:table; à ul:

ul{display:table;}
evan toder
la source