Por que meus marcadores de itens da lista se sobrepõem a elementos flutuantes

166

Eu tenho uma página (XHTML Strict) onde flutuo uma imagem ao lado de parágrafos regulares de texto. Tudo vai bem, exceto quando uma lista é usada em vez de parágrafos. Os marcadores da lista se sobrepõem à imagem flutuada.

Alterar a margem da lista ou dos itens da lista não ajuda. A margem é calculada a partir da esquerda da página, mas o flutuador empurra os itens da lista para a direita dentro do lipróprio. Portanto, a margem só ajuda se eu a ampliar mais que a imagem.

Flutuar a lista ao lado da imagem também funciona, mas não sei quando a lista fica ao lado de uma bóia. Não quero flutuar todas as listas do meu conteúdo apenas para corrigir isso. Além disso, flutuar à esquerda altera o layout quando uma imagem é flutuada para a direita, em vez de para a esquerda da lista.

A configuração li { list-style-position: inside }move os marcadores junto com o conteúdo, mas também faz com que as linhas quebradas sejam alinhadas com o marcador, em vez de alinhadas com a linha acima.

Obviamente, o problema é causado pelo disparo da bala fora da caixa, o flutuador empurrando o conteúdo da caixa para a direita (não a própria caixa). É assim que o IE e o FF lidam com a situação e, até onde eu sei, não estão errados de acordo com as especificações. A questão é: como posso evitá-lo?

Kamiel Wanrooij
fonte

Respostas:

280

Eu encontrei uma solução para este problema. A aplicação de um ul { overflow: hidden; }ao ulgarante que a própria caixa seja afastada pelo flutuador, em vez do conteúdo da caixa.

Somente o IE6 precisa de um ul { zoom: 1; }em nossos comentários condicionais para garantir que o ullayout tenha.

Kamiel Wanrooij
fonte
1
+1: Ótimo CSS, procurei como um louco por uma solução BOM VERSÁTIL e aqui está o SO. A única pequena desvantagem é que a propriedade zoom não valida o CSS, mas eu testei e no IE7, o IE8 não é necessário, portanto, provavelmente é apenas para o IE6.
Marco Demaio 24/08/10
14
Para que isso funcionasse, eu também precisei aplicar: ul, ol {overflow: hidden; preenchimento esquerdo: 40 px; margem esquerda: 0; } ol li, ul li {posição do estilo da lista: fora; preenchimento esquerdo: 0; } Isso forçou a renderização consistente nos navegadores e forçou o IE6 a mostrar os marcadores. As balas estavam escondidas do contrário. O ul {zoom: 1; } ainda era necessário nas configurações específicas do ie6.
Mandrake
1
Solução tão ridiculamente simples para esse erro ridículo no MSIE.
SF.
10
Não é uma solução perfeita. Como o Blazemonger mencionou, se a imagem for pequena e a lista for muito longa, a lista não fluirá ao redor da imagem flutuante. A lista terá uma margem enorme de cima para o final, se a imagem for muito ampla.
yang
2
Agradável! Porém, não consigo ver como isso faz sentido ao ler o documento do W3C no estouro: w3schools.com/cssref/pr_pos_overflow.asp
MSC
66

Adicionando uma melhoria à solução 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/

Eu prefiro essa técnica, pois ela funciona quando a lista precisa fluir pela imagem flutuante, enquanto a overflow: hiddentécnica não. No entanto, também é necessário adicionar padding-right: 1emao lipara impedir que eles excedam o contêiner.

Blazemonger
fonte
Também prefiro essa correção, pois a principal quebrou minhas suspensões no Twitter Bootstrap e levei uma eternidade para descobrir que o método acima era o culpado.
Ian Hoar
2
Obrigado por isso. Aplicando estouro: oculto; para o contêiner, a UL impedia que o texto nos itens de linha individuais corresse adequadamente ao redor do bloco flutuante. Esta solução fez o truque!
Jsdalton
1
Encontrei um problema menor, porém crítico, com esta solução e gostaria de sugerir uma adição à sua melhoria. Não sei por que, mas quando você adiciona position: relative;ao item de linha, ele cria um problema de empilhamento com o conteúdo flutuante. Descobri (no Chrome e Firefox) que era difícil passar o mouse e clicar nos links do conteúdo flutuante. A correção para mim foi adicionar position: relative; z-index: 1;ao elemento flutuante, que parecia resolver o problema de empilhamento.
jsdalton
7
Infelizmente, no IE 10, os marcadores se sobrepõem ao elemento flutuante.
Munawwar 19/02
1
Considerando que ul {overflow: hidden;}o problema foi resolvido em todos os navegadores, a solução acima foi o único remédio para esse problema no Prince XML , um conversor de XHTML + CSS3 para PDF.
Serge Stroobandt 04/04
36

É aqui que a propriedade "display" se destaca. Defina o CSS abaixo para fazer a lista funcionar junto com o conteúdo flutuante.

display: mesa; funciona ao lado de conteúdo flutuante (preenchendo a lacuna), mas sem ocultar o conteúdo por trás dela. Muito parecido com uma mesa :-)

.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: Lembre-se de adicionar uma classe para isolar quais listas você deseja fazer isso. Por exemplo, "ul.in-content" ou mais geralmente ".content ul"

martinedwards
fonte
29

Tente list-style-position: inside para alterar o layout das balas.

annakata
fonte
3
list-style-position:insideseria uma ótima solução, mas faz com que as linhas que quebram iniciem alinhadas com o marcador, em vez de alinhadas com a linha acima.
Marco Demaio
estouro: oculto; não trabalho para a minha imagem flutuante esquerda, mas a posição do estilo de lista: por dentro, isso! graças
menardmam
Essa foi a única solução que ainda envolveu o conteúdo do IE para mim. Obrigado!
precisa saber é o seguinte
Essa é uma ótima solução para quando o conteúdo está flutuando entre seus marcadores e o conteúdo do marcador.
TylersSN
Essa deve ser a resposta escolhida.
Sleek Geek
18

Em http://archivist.incutio.com/viewlist/css-discuss/106382 , encontrei uma sugestão que funcionou para mim: estilize os elementos 'li' com:

position: relative;
left: 1em;

Onde você substitui "1em" pela largura do preenchimento / margem esquerdo que seus itens de lista teriam se o flutuador não estivesse presente. Isso funciona muito bem no meu aplicativo, mesmo lidando com o caso em que a parte inferior do flutuador ocorre no meio das listas - os marcadores voltam para a margem esquerda (local) exatamente à direita.

Glen E. Ivey
fonte
2
Solução fantástica, funciona como um encanto! Embora eu tivesse que sujar as mãos com o IE7, pois ele não mostrava os números dos itens da lista nas listas que não estavam próximas a um elemento flutuante.
Maryisdead 29/06
@maryisdead Qual é a sua solução para o IE7?
TJ.
O IE7 precisava de uma margem extra à esquerda nos itens da lista. Veja este violão jsfiddle.net/maryisdead/wu6ew/5 e observe os dois hacks do IE7. Desculpe por não adicionar isso anteriormente.
Maryisdead 28/03/12
18

Por que overflow: hiddenfunciona

A solução é tão fácil quanto:

ul {overflow: hidden;}

Uma caixa de bloco overflow:diferente de visible estabelece um novo contexto de formatação de bloco para seu conteúdo. Recomendação do W3C: http://www.w3.org/TR/CSS2/visuren.html#block-formatting

Exemplo

Os botões do meu site , que estão <li>disfarçados, são feitos assim. Diminua a viewport (janela) do seu navegador para ver o recuo em ação .

Meu site como exemplo

Respostas relacionadas

Artigo com exemplos

Serge Stroobandt
fonte
1
obrigado por explicar por que isso funciona (não é mencionado na solução aceite)
schellmax
17

Ao adicionar overflow: auto;aos seus ultrabalhos para mim, pelo menos.

Atualizar

Atualizei meu jsfiddle para visualizar o que está acontecendo. Ao ter o ullado do flutuante img, o conteúdo do ulserá empurrado pelo flutuador, mas não pelo contêiner real. Ao adicionar a overflow: autocaixa inteira ul, será empurrada pelo flutuador em vez de apenas pelo conteúdo.

Maehler
fonte
13

Você pode atribuir position: relative; left: 10px;ao li. (Você também pode querer dar um margin-right: 10px;, caso contrário, ele poderá ficar muito largo no lado direito.)

Ou, se você quiser usar floato ul- como sugerido por outros - provavelmente poderá impedir o resto de flutuar à direita da ul usando clear: lefto elemento que segue a ul.

Chris Lercher
fonte
graças chris, essa posição: parente trabalhou. o problema que surgiria da limpeza do elemento após a ul é que o elemento também limparia a div flutuada à esquerda.
superUntitled
7

Estou usando isso para resolver este problema:

ul {
   display: table;
}
A vida é curta
fonte
7

aviso Legal

As listas ao lado dos elementos flutuantes causam problemas. Na minha opinião, a melhor maneira de evitar esses tipos de problemas flutuantes é evitar imagens flutuantes que se cruzam com o conteúdo. Também ajudará quando você precisar oferecer suporte ao design responsivo.

Um design simples de ter imagens centralizadas entre parágrafos parecerá muito atraente e será muito mais fácil de suportar do que tentar ficar extravagante. Também está a um passo de a <figure>.

Mas eu realmente quero imagens flutuadas!

Ok, se você é louco por persistência o suficiente para continuar nesse caminho, há algumas técnicas que podem ser usadas.

O mais simples é fazer com que a lista use overflow: hiddenou overflow: scrollpara que a lista seja essencialmente encolhida, o que puxa o preenchimento de volta para onde é útil:

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>

Esta técnica tem alguns problemas, no entanto. Se a lista for longa, na verdade ela não contorna a imagem, o que praticamente derrota todo o propósito de usá float-la.

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>

Mas eu realmente quero listas de quebra-cabeças!

Ok, se você é ainda mais louco e persistente e precisa continuar por esse caminho, existe outra técnica que pode ser usada para agrupar os itens da lista e manter marcadores.

Em vez de preencher <ul>e tentar fazer com que ele se comporte bem com marcadores (o que nunca parece querer fazer), retire-os <ul>e dê-os ao <li>s. As balas são perigosas e os <ul>justos não são responsáveis ​​o suficiente para lidar com elas adequadamente.

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>

Esse comportamento de agrupamento pode fazer coisas estranhas ao conteúdo complexo, por isso não recomendo adicioná-lo por padrão. É muito mais fácil configurá-lo como algo que pode ser incluído, em vez de algo que deve ser substituído.

zzzzBov
fonte
Eu gosto da segunda opção, mas o texto começa com os marcadores nos textos mais longos (2 linhas) :-(
Arany
4

Tente o seguinte na sua etiqueta UL. Isso deve cuidar das marcas que cobrem sua imagem e você não precisa atrapalhar o alinhamento esquerdo causado por list-position: inside.

overflow: hidden; 
padding-left: 2em; 
Joe
fonte
Eu tive que usar isso com a solução Blazemonger (# 2 acima). O BLazemonger sozinho não funcionou no IE 9-11 e no Opera. Com isso, ele funciona em todos os navegadores. A solução de Kamiel (# 1) não funcionou para mim, pois escondia minhas balas. Conflito com o Bootstrap3 talvez.
Leraa
3

Eu mesmo lutava com isso. O melhor que gerenciei é o seguinte:

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

O texto não é realmente recuado, mas o marcador é exibido.

Stephen
fonte
2

Editado para atualizar com base no comentário do OP

ok, basta dividi-lo em 2 divs aninhados

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>

tente alterar o ul li css para

ul {flutuar: esquerda; fundo: azul; }

ANC_Michael
fonte
obrigado, isso funciona, no entanto, agora os parágrafos abaixo estão flutuando no lado direito.
superUntitled
2

Depois de lutar com essa questão interessante em vários projetos e investigar por que isso acontece, finalmente acredito que encontrei as duas: uma solução funcional e 'responsiva' .

Aqui está o truque de mágica, exemplo ao vivo: 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
fonte
Eu adicionei display: flex;a li, para que o marcador esteja centralizado verticalmente, quando altero o tamanho da fonte da :beforepeça.
217 Arany
1

Trabalhando em um LMS sem acesso ao cabeçalho do documento, ficou mais fácil usar o margin-right: 20pxestilo embutido da imagem. O que devo a este site .

Lynda Williams
fonte
0

tente isto:

li{
    margin-left:5px;
}

Se você quiser que eles vire à esquerda, basta colocar um valor de - ## px.

Douglas
fonte
0

ou você pode fazer isso:

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

e remova todo o estilo do li

Reece
fonte
1
flutuar o ul realmente resolve o problema, no entanto, outro problema surge ... todos os elementos de parágrafo que vêm depois do ul flutuam para a direita do ul.
superUntitled
dei +1 a você por isso ... Eu estava assumindo aqui, olhando o link associado a esta pergunta, que o <p> estaria flutuando à direita de <ul>. Boa pegada.
Reece
0

Que tal agora?

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

margin-left: auto fará com que o próprio elemento fique alinhado à direita. Defina a altura e a largura do elemento que você deseja - no meu é uma imagem de fundo em uma div dentro

Nikolay Ivanov
fonte
0

Você também pode tentar flutuar ulpara a esquerda e definir um apropriado widthpara ele, para que flutue próximo à imagem.

Algo um pouco como este jsfiddle ?

Houdmont
fonte
0

Eu consertei com

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

Adicionar display:table; a ul:

ul{display:table;}
evan toder
fonte