Como impedir que palavras longas quebrem minha div?


148

Desde a mudança do layout TABLE para o layout DIV, um problema comum permanece:

PROBLEMA : você preenche seu DIV com texto dinâmico e, inevitavelmente, há uma palavra muito longa que se estende pela borda da coluna div e faz com que seu site pareça não profissional.

RETRO-WHINING : Isso nunca aconteceu com layouts de tabelas. Uma célula da tabela sempre se expandirá bem para a largura da palavra mais longa.

GRAVIDADE : Eu vejo esse problema até nos sites mais importantes, especialmente nos sites alemães, onde mesmo palavras comuns como "limite de velocidade" são muito longas ("Geschwindigkeitsbegrenzung").

Alguém tem uma solução viável para isso?


4
Você deve ter esquecido os layouts de tabela super esticados e quebrados. Aceito transbordamentos: ocultos a qualquer dia em células que se estendem incontrolavelmente.
Kornel

1
Uma célula da tabela sempre será bem ???????? expandir para a largura da palavra mais comprida
inspite

1
Conheço muitas pessoas (e provavelmente me consideraria uma delas) que diriam que esse é um comportamento muito pior. A largura da página e do elemento geralmente é algo que tem muito tempo gasto nela. Se você pudesse ter palavras aleatórias que tornassem as larguras incontroláveis, você falhou em seu design.
263 Oli #

13
Sempre achei que o comportamento da tabela estava mais de acordo com a filosofia original de flexibilidade do HTML. A filosofia rígida de largura de coluna DIV / CSS parece vir dos designers da revista que não conseguem lidar com suas colunas, às vezes mais largas, às vezes mais estreitas.
Edward Tanguay

1
Um bom design deve ser consistente; se o conteúdo da página puder alterar as dimensões da interface do usuário, isso violaria o design. Sério, onde você traçaria a linha com um layout elástico? Llanfairpwllgwyngyllgogerychwyrndrobwllantysiliogogogoch?
Doctor Jones

Respostas:


138

Hífen suave

Você pode dizer aos navegadores onde dividir palavras longas, inserindo o hífen ( ­):

averyvery­longword

pode ser renderizado como

averyverylongword

ou

averyvery-
longword

Uma boa expressão regular pode garantir que você não as insira, a menos que seja necessário:

/([^\s-]{5})([^\s-]{5})/  $1­$2

Navegadores e mecanismos de pesquisa são inteligentes o suficiente para ignorar esse caractere ao pesquisar texto, e Chrome e Firefox (não testaram outros) o ignoram ao copiar texto para a área de transferência.

<wbr> elemento

Outra opção é injetar <wbr>, um antigo IE-ism , que agora está em HTML5 :

averyvery<wbr>longword

Quebras sem hífen:

cada
palavra muito longa

Você pode conseguir o mesmo com o caractere de espaço com largura zero &#8203;(ou &#x200B).


Para sua informação, também há CSShyphens: auto suportado pelo IE, Firefox e Safari mais recente ( mas atualmente não é o Chrome ):

div.breaking {
  hyphens: auto;
}

No entanto, essa hifenização é baseada em um dicionário de hifenização e não é garantido a quebra de palavras longas. Pode tornar o texto justificado mais bonito.

Solução lamentável

<table>para o layout é ruim, mas display:tableem outros elementos é bom. Será tão peculiar (e elástico) quanto as tabelas da velha escola:

div.breaking {
   display: table-cell;
}

overflowe as white-space: pre-wraprespostas abaixo também são boas.


7
Legal! De acordo com a wikipedia, você pode obter um espaço de largura zero com o & # 8203; - desde que você o criou, você conhece um código de escape menos feio para ele? Eu vou memorizar 8203 se eu tiver que, mas ...
ojrac

1
@ojrac - Isso depende se você pensa & # x200B; é "menos feio" ou não. :-) AFAIK, não há "entidade de palavras" para espaço com largura zero.
31119 Ben Blank

1
Isso é legal, mas não é uma solução para o problema inicial.
Albus Dumbledore

25
Isso quebra copiar / colar.
Nornagon

4
Apenas para sua informação, você também pode usar <wbr>. Consulte quirksmode.org/oddsandends/wbr.html .
HaxElit

40

Duas correções:

  1. overflow:scroll - isso garante que seu conteúdo possa ser visto ao custo do design (as barras de rolagem são feias)
  2. overflow:hidden- apenas corta qualquer excesso. Isso significa que as pessoas não conseguem ler o conteúdo.

Se (no exemplo SO) você deseja impedir que ele se sobreponha ao preenchimento, você provavelmente precisará criar outra div, dentro do preenchimento, para manter seu conteúdo.

Edit: Como as outras respostas afirmam, há uma variedade de métodos para truncar as palavras: trabalhar a largura de renderização no lado do cliente (nunca tente fazer isso no lado do servidor, pois nunca funcionará de forma confiável, em várias plataformas) através JS e inserção de caracteres de interrupção ou uso de tags CSS não padronizadas e / ou totalmente incompatíveis ( word-wrap: break-word não parece funcionar no Firefox ).

Você sempre precisará de um descritor de estouro. Se a sua div contiver outro conteúdo do tipo bloco muito amplo (imagem, tabela etc.), será necessário estourar para não destruir o layout / design.

Portanto, por qualquer meio, use outro método (ou uma combinação deles), mas lembre-se de adicionar excesso também para cobrir todos os navegadores.

Edite 2 (para endereçar seu comentário abaixo):

Comece usando a overflowpropriedade CSS não é perfeita, mas impede a quebra de design. Aplique overflow:hiddenprimeiro. Lembre-se de que o excesso pode não quebrar no preenchimento; portanto, aninhe divs ou use uma borda (o que for melhor para você).

Isso ocultará o conteúdo transbordante e, portanto, você poderá perder o significado. Você pode usar uma barra de rolagem (usando overflow:autoou em overflow:scrollvez de overflow:hidden), mas dependendo das dimensões da div e do seu design, isso pode não parecer ou não funcionar muito bem.

Para corrigi-lo, podemos usar o JS para recuar e executar alguma forma de truncamento automatizado. Eu estava no meio da escrita de algum pseudo-código para você, mas fica seriamente complicado no meio do caminho. Se você precisar mostrar o máximo possível, dê uma olhada no hifenizador ( como mencionado abaixo ).

Esteja ciente de que isso custa às CPUs dos usuários. Isso pode levar muito tempo para carregar e / ou redimensionar as páginas.


1
com excesso de texto: reticências; o texto pode ser bem cortado.
Kornel

1
excesso de texto: as reticências são apenas para o IE (e, por extensão, não padrão).
264 Oli #

Eu sempre procuraria se overflow: scroll;o conteúdo contivesse informações úteis. E o próximo objetivo é tentar criar um CSS que as barras de rolagem não apareçam. E, caso o façam, você sempre terá as barras de rolagem como backup.
Yeti

sobre o uso de text-overflow: ellipsis stackoverflow.com/a/22811590/759452 #
Adrien Be

33

Esse é um problema complexo, como sabemos, e não é suportado de maneira comum entre navegadores. A maioria dos navegadores não suporta esse recurso de forma nativa.

Em algum trabalho feito com emails em HTML, em que o conteúdo do usuário estava sendo usado, mas o script não está disponível (e nem o CSS é suportado muito bem), o seguinte bit de CSS em um wrapper em torno do bloco de conteúdo não espaçado deve ao menos ajudar um pouco:

.word-break {
  /* The following styles prevent unbroken strings from breaking the layout */
  width: 300px; /* set to whatever width you need */
  overflow: auto;
  white-space: -moz-pre-wrap; /* Mozilla */
  white-space: -hp-pre-wrap; /* HP printers */
  white-space: -o-pre-wrap; /* Opera 7 */
  white-space: -pre-wrap; /* Opera 4-6 */
  white-space: pre-wrap; /* CSS 2.1 */
  white-space: pre-line; /* CSS 3 (and 2.1 as well, actually) */
  word-wrap: break-word; /* IE */
  -moz-binding: url('xbl.xml#wordwrap'); /* Firefox (using XBL) */
}

No caso de navegadores baseados no Mozilla, o arquivo XBL mencionado acima contém:

<?xml version="1.0" encoding="utf-8"?>
<bindings xmlns="http://www.mozilla.org/xbl" 
          xmlns:html="http://www.w3.org/1999/xhtml">
  <!--
  More information on XBL:
  http://developer.mozilla.org/en/docs/XBL:XBL_1.0_Reference

  Example of implementing the CSS 'word-wrap' feature:
  http://blog.stchur.com/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/
  -->
  <binding id="wordwrap" applyauthorstyles="false">
    <implementation>
      <constructor>
        //<![CDATA[
        var elem = this;

        doWrap();
        elem.addEventListener('overflow', doWrap, false);

        function doWrap() {
          var walker = document.createTreeWalker(elem, NodeFilter.SHOW_TEXT, null, false);
          while (walker.nextNode()) {
            var node = walker.currentNode;
            node.nodeValue = node.nodeValue.split('').join(String.fromCharCode('8203'));
          }
        }
        //]]>
      </constructor>
    </implementation>
  </binding>
</bindings>

Infelizmente, o Opera 8+ não parece gostar de nenhuma das soluções acima, portanto o JavaScript terá que ser a solução para esses navegadores (como Mozilla / Firefox.) Outra solução entre navegadores (JavaScript) que inclui as edições posteriores do Opera seria usar o script de Hedger Wang encontrado aqui: http://www.hedgerwow.com/360/dhtml/css-word-break.html

Outros links / pensamentos úteis:

Babble Incoerent »Arquivo de Blog» Emulando o quebra-cabeças CSS para Mozilla / Firefox
http://blog.stchur.com/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/

[OU] Não há quebra de linha no Opera, é exibido no IE
http://list.opera.com/pipermail/opera-users/2004-November/024467.html
http://list.opera.com/pipermail/opera- users / 2004-November / 024468.html


E se o que eu preciso for largura: 100%? Isso significa 100% do contêiner externo. O objetivo disso é evitar que barras de rolagem horizontal apareçam na página e atrapalhem o restante do layout.
22412 Pilavdzice

1
As versões mais recentes do Firefox agora suportam a word-wrap: break-word;propriedade CSS; portanto, se você não precisar de suporte no Firefox para versões anteriores, poderá eliminar o XBL.
Neil Monroe

27

Quebra de linha do CSS Cross Browser

.word_wrap
{
    white-space: pre-wrap; /* css-3 */
    white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
    white-space: -pre-wrap; /* Opera 4-6 */
    white-space: -o-pre-wrap; /* Opera 7 */
    word-wrap: break-word; /* Internet Explorer 5.5+ */
}

Não suportado no Opera 9.24
SCC

14

Use o estilo word-break:break-all;. Eu sei que funciona em mesas.


@sanimalp Não suportado no Opera 9.24
SCC

13

Você quer dizer que, em navegadores compatíveis, word-wrap: break-wordnão funciona?

Se incluída na definição do corpo da folha de estilo , ela funcionará em todo o documento.

Se o estouro não for uma boa solução, apenas um javascript personalizado pode quebrar artificialmente a palavra longa.

Nota: também existe esta <wbr>tag de quebra de palavra . Isso fornece ao navegador um local onde ele pode dividir a linha. Infelizmente, a <wbr>tag não funciona em todos os navegadores, apenas no Firefox e no Internet Explorer (e no Opera com um truque de CSS).


9

Apenas verifiquei o IE 7, Firefox 3.6.8 Mac, Firefox 3.6.8 Windows e Safari:

word-wrap: break-word;

funciona para links longos dentro de uma div com uma largura definida e nenhum estouro declarado no css:

#consumeralerts_leftcol{
    float:left;
    width: 250px;
    margin-bottom:10px;
    word-wrap: break-word;
}

Não vejo nenhum problema de incompatibilidade



6

Depois de muita luta, foi isso que funcionou para mim:

.pre {
    font-weight: 500;
    font-family: Courier New, monospace;
    white-space: pre-wrap;
    word-wrap: break-word;
    word-break: break-all;
    -webkit-hyphens: auto;
    -moz-hyphens: auto;
    hyphens: auto;
}

Funciona nas versões mais recentes do Chrome, Firefox e Opera.

Observe que eu excluí muitas das white-spacepropriedades sugeridas pelos outros - que realmente quebraram o prerecuo para mim.


5

Para mim, em uma div sem tamanho fixo e com conteúdo dinâmico, funcionou usando:

display:table;
word-break:break-all;

4

No regex deste comentário , é bom, mas adiciona o hífen tímido apenas entre grupos de 5 caracteres que não são de espaço em branco ou hífen. Isso permite que o último grupo seja muito mais longo do que o pretendido, pois não há um grupo correspondente a ele.

Por exemplo, isto:

'abcde12345678901234'.replace(/([^\s-]{5})([^\s-]{5})/g, '$1&shy;$2')

... resulta nisto:

abcde&shy;12345678901234

Aqui está uma versão usando lookahead positivo para evitar esse problema:

.replace(/([^\s-]{5})(?=[^\s-])/g, '$1&shy;')

... com este resultado:

abcde&shy;12345&shy;67890&shy;1234

4

A solução que costumo usar para esse problema é definir duas regras css diferentes para o IE e outros navegadores:

word-wrap: break-word;

woks perfeitos no IE, mas a quebra de linha não é uma propriedade CSS padrão. É uma propriedade específica da Microsoft e não funciona no Firefox.

Para o Firefox, a melhor coisa a fazer usando apenas CSS é definir a regra

overflow: hidden;

para o elemento que contém o texto que você deseja quebrar. Não quebra o texto, mas oculta a parte do texto que ultrapassa o limite do contêiner . Pode ser uma boa solução se não for essencial para você exibir todo o texto (ou seja, se o texto estiver dentro de uma <a>tag)


word-wrap: break-palavra parece funcionar bem para mim no Firefox 10.
Jon Schneider

O CanIUse diz que é compatível com IE8 +, Firefox28 +, Chrome33 +, Safari7 + e mais. caniuse.com/#search=word-wrap
Adrien Seja

4

Atualização: lidar com isso em CSS é maravilhosamente simples e com pouca sobrecarga, mas você não tem controle sobre onde ocorrem as quebras quando ocorrem. Tudo bem se você não se importa, ou seus dados têm execuções alfanuméricas longas sem interrupções naturais. Tínhamos muitos caminhos de arquivos, URLs e números de telefone longos, todos com lugares em que é significativamente melhor procurar do que outros.

Nossa solução foi usar primeiro uma substituição de regex para colocar um espaço de largura zero (& # 8203;) após cada 15 (digamos) caracteres que não são espaços em branco ou um dos caracteres especiais onde preferimos quebras. Em seguida, fazemos outra substituição para colocar um espaço de largura zero após esses caracteres especiais.

Espaços com largura zero são bons, porque eles nunca são visíveis na tela; hífens tímidos eram confusos quando mostraram, porque os dados têm hífens significativos. Os espaços com largura zero também não são incluídos quando você copia o texto do navegador.

Os caracteres de interrupção especiais que estamos usando atualmente são ponto final, barra invertida, barra invertida, vírgula, sublinhado, @, | e hífen. Você não acha que precisaria fazer algo para encorajar a quebra de hífens, mas o Firefox (pelo menos 3.6 e 4) não quebra sozinho em hífens cercados por números (como números de telefone).

Também queríamos controlar o número de caracteres entre quebras artificiais, com base no espaço de layout disponível. Isso significava que o regex para corresponder a longas execuções sem interrupção precisava ser dinâmico. Isso é chamado muito, e não queríamos criar as mesmas regexes idênticas repetidamente por motivos de desempenho; portanto, usamos um cache de regex simples, codificado pela expressão de regex e seus sinalizadores.

Aqui está o código; você provavelmente nomeará as funções em um pacote de utilitários:

makeWrappable = function(str, position)
{
    if (!str)
        return '';
    position = position || 15; // default to breaking after 15 chars
    // matches every requested number of chars that's not whitespace or one of the special chars defined below
    var longRunsRegex = cachedRegex('([^\\s\\.\/\\,_@\\|-]{' + position + '})(?=[^\\s\\.\/\\,_@\\|-])', 'g');
    return str
                .replace(longRunsRegex, '$1&#8203;') // put a zero-width space every requested number of chars that's not whitespace or a special char
                .replace(makeWrappable.SPECIAL_CHARS_REGEX, '$1&#8203;'); // and one after special chars we want to allow breaking after
};
makeWrappable.SPECIAL_CHARS_REGEX = /([\.\/\\,_@\|-])/g; // period, forward slash, backslash, comma, underscore, @, |, hyphen


cachedRegex = function(reString, reFlags)
{
    var key = reString + (reFlags ? ':::' + reFlags : '');
    if (!cachedRegex.cache[key])
        cachedRegex.cache[key] = new RegExp(reString, reFlags);
    return cachedRegex.cache[key];
};
cachedRegex.cache = {};

Teste assim:

makeWrappable('12345678901234567890 12345678901234567890 1234567890/1234567890')

Atualização 2: Parece que espaços com largura zero estão incluídos no texto copiado em pelo menos algumas circunstâncias, você simplesmente não pode vê-los. Obviamente, incentivar as pessoas a copiarem textos com caracteres ocultos é um convite para que dados como esses sejam inseridos em outros programas ou sistemas, até os seus, onde isso pode causar problemas. Por exemplo, se ele terminar em um banco de dados, as pesquisas nele poderão falhar e as cadeias de pesquisa como essa provavelmente também falharão. O uso das teclas de seta para mover dados como esse requer (com razão) um pressionamento de tecla extra para mover o personagem que você não pode ver, um tanto bizarro para os usuários, se eles perceberem.

Em um sistema fechado, você pode filtrar esse caractere na entrada para se proteger, mas isso não ajuda outros programas e sistemas.

No total, essa técnica funciona bem, mas não tenho certeza de qual seria a melhor escolha de personagem causador de quebra.

Atualização 3: Ter esse personagem nos dados não é mais uma possibilidade teórica, é um problema observado. Os usuários enviam os dados copiados da tela, eles são salvos no banco de dados, as pesquisas quebram, as coisas ficam estranhamente etc.

Fizemos duas coisas:

  1. Escreveu um utilitário para removê-los de todas as colunas de todas as tabelas em todas as fontes de dados para este aplicativo.
  2. Adicionado filtro para removê-lo para o nosso processador de entrada de string padrão, para que ele acabe quando qualquer código o vir.

Isso funciona bem, assim como a própria técnica, mas é uma história de advertência.

Atualização 4: estamos usando isso em um contexto em que os dados fornecidos a isso podem ser escapados em HTML. Sob as circunstâncias certas, ele pode inserir espaços de largura zero no meio de entidades HTML, com resultados descolados.

A correção foi adicionar e comercial à lista de caracteres que não quebramos, assim:

var longRunsRegex = cachedRegex('([^&\\s\\.\/\\,_@\\|-]{' + position + '})(?=[^&\\s\\.\/\\,_@\\|-])', 'g');

Eu usei isso, mas eu só precisava para executar este uma vez por um nome de domínio longa, então eu só encurtou a:if(domainName.length > 15) domainName.replace(/([^\\s]{5})(?=[^\\s])/g, '$1&#8203;');
CBarr

3

É necessário definir "layout da tabela: fixo" para que o quebra-cabeças funcione


1
Obrigado por isso! Quebra de palavra: quebra de palavra; caso contrário, não funcionará para tabelas.
Liviucmg 27/10/10

2

HYPHENATOR é a resposta certa (dada acima). O verdadeiro problema por trás da sua pergunta é que os navegadores da web ainda são (em 2008) extremamente primitivos, pois não possuem um recurso de hifenização. Olha, ainda estamos no começo do uso do computador - precisamos ser pacientes. Enquanto os designers dominarem o mundo da web, teremos dificuldade em aguardar alguns novos recursos realmente úteis.

ATUALIZAÇÃO: Em dezembro de 2011, agora temos outra opção, com o suporte emergente dessas tags no FF e Safari:

p {
    -webkit-hyphens: auto;
    -moz-hyphens: auto;
    hyphens: auto;
}

Fiz alguns testes básicos e parece funcionar em uma versão recente do Mobile Safari e Safari 5.1.1.

Tabela de compatibilidade: https://developer.mozilla.org/en/CSS/hyphens#AutoCompatibilityTable



2

Usa isto

word-wrap: break-word;
overflow-wrap: break-word;
word-break: break-all;

1

Se você tem isso -

  <style type="text/css">
      .cell {
            float: left;
            width: 100px;
            border: 1px solid;
            line-height: 1em;
      }
  </style>

  <div class="cell">TopLeft</div>
  <div class="cell">TopMiddlePlusSomeOtherTextWhichMakesItToLong</div>
  <div class="cell">TopRight</div>
  <br/>
  <div class="cell">BottomLeft</div>
  <div class="cell">BottomMiddle</div>
  <div class="cell">bottomRight</div>

basta mudar para um formato vertical contendo divs e usar largura mínima no CSS em vez de largura -

  <style type="text/css">
      .column {
            float: left;
            min-width: 100px;
      }
      .cell2 {
            border: 1px solid;
            line-height: 1em;
      }
  </style>

  <div class="column">
      <div class="cell2">TopLeft</div>
      <div class="cell2">BottomLeft</div>
  </div>
  <div class="column">
      <div class="cell2">TopMiddlePlusSomeOtherTextWhichMakesItToLong</div>
      <div class="cell2">BottomMiddle</div>
  </div>
  <div class="column">
      <div class="cell2">TopRight</div>
      <div class="cell2">bottomRight</div>
  </div>
  <br/>

Obviamente, se você estiver exibindo dados tabulares genuínos, não há problema em usar uma tabela real, pois ela é semanticamente correta e informará as pessoas que usam leitores de tela que deveriam estar em uma tabela. É para usá-los para o layout geral ou para fatiar imagens pelas quais as pessoas o lincham.


1

Eu tive que fazer o seguinte porque, se as propriedades não fossem declaradas na ordem correta, elas quebrariam aleatoriamente as palavras no lugar errado e sem adicionar um hífen.

    -moz-white-space: pre-wrap;
white-space: pre-wrap;        
    hyphens: auto;
    -ms-word-break: break-all;
    -ms-word-wrap: break-all;
    -webkit-word-break: break-word;
    -webkit-word-wrap: break-word;
word-break: break-word;
word-wrap: break-word;
    -webkit-hyphens: auto;
    -moz-hyphens: auto;
    -ms-hyphens: auto;
hyphens: auto;

Originalmente enviada por Enigmo: https://stackoverflow.com/a/14191114


1

Sim, se for possível, definir uma largura absoluta e definir overflow : autobem.


1
p {
    overflow-wrap: break-word;
}


@-moz-document url-prefix() { 
    p {
        white-space: -moz-pre-wrap;
        word-wrap: break-word;
    }
}



0

depois de toda a palavra quebrar e quebrar, preserve seu excesso e veja se isso resolve seu problema. basta alterar a exibição da sua div para:display: inline;


-1

Uma função simples (requer underscore.js) - baseada na resposta @porneL

    String.prototype.shyBreakString = function(maxLength) {
        var shystring = [];
        _.each(this.split(' '), function(word){
            shystring.push(_.chop(word, maxLength).join('&shy;'));
        });
        return shystring.join(' ');
    };

-1

Eu escrevi uma função que funciona muito bem onde insere &shy;x letras na palavra para uma boa quebra de linha. Todas as respostas aqui não suportam todos os navegadores e dispositivos, mas isso funciona bem usando o PHP:

/**
 * Add line-break to text x characters in
 * @param  string  $text          
 * @param  integer $characters_in 
 * @return string                 
 */
function line_break_text($text, $characters_in = 10) {

    $split = explode(' ', $text);

    if ( ! empty($split)) {

        foreach ($split as $key => $var) {

            if ( strlen($var) > $characters_in ) {

                $split[$key] = substr_replace($var, '&shy;', $characters_in, 0);

            }

        }

    }

    return implode(' ', $split);

}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.