¿Cómo evitar que palabras largas rompan mi div?


148

Desde que se cambió del diseño TABLE al diseño DIV, un problema común sigue siendo:

PROBLEMA : llenas tu DIV con texto dinámico e inevitablemente hay una palabra súper larga que se extiende sobre el borde de tu columna div y hace que tu sitio se vea poco profesional.

RETRO-WHINING : Esto nunca sucedió con diseños de mesa. Una celda de tabla siempre se expandirá al ancho de la palabra más larga.

GRAVEDAD : Veo este problema incluso en los sitios más importantes, especialmente en sitios alemanes donde incluso palabras comunes como "límite de velocidad" son muy largas ("Geschwindigkeitsbegrenzung").

¿Alguien tiene una solución viable para esto?


44
Debes haber olvidado esos diseños de mesa super estirados y efectivamente rotos. Tomaré desbordamiento: oculto cualquier día sobre células que se estiran sin control.
Kornel

1
Una celda de tabla siempre estará bien ???????? expandirse al ancho de la palabra más larga
inspirar el

1
Conozco a muchas personas (y probablemente me consideraría entre ellas) que dirían que es un comportamiento mucho peor. El ancho de página y elemento suele ser algo que se dedica mucho tiempo. Si puede tener palabras aleatorias que hacen que los anchos sean incontrolables, ha fallado con su diseño.
Oli

13
Siempre he sentido que el comportamiento de la tabla estaba más en línea con la filosofía original de flexibilidad de HTML. La filosofía de ancho de columna rígido DIV / CSS parece provenir de los diseñadores de revistas que no pueden lidiar con que sus columnas sean a veces más anchas y otras más estrechas.
Edward Tanguay

1
Un buen diseño debe ser consistente; si el contenido de la página puede cambiar las dimensiones de la interfaz de usuario, violaría el diseño. En serio, ¿dónde dibujarías la línea con un diseño elástico? Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch?
Doctor Jones el

Respuestas:


138

Guión suave

Puede decirle a los navegadores dónde dividir palabras largas insertando un guión suave ( ­):

averyvery­longword

puede ser presentado como

averyverylongword

o

averyvery-
longword

Una buena expresión regular puede garantizar que no los inserte a menos que sea necesario:

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

Los navegadores y los motores de búsqueda son lo suficientemente inteligentes como para ignorar este carácter al buscar texto, y Chrome y Firefox (no han probado otros) lo ignoran al copiar texto en el portapapeles.

<wbr> elemento

Otra opción es inyectar <wbr>, un antiguo IE-ism , que ahora está en HTML5 :

averyvery<wbr>longword

Saltos sin guión:

averyvery
longword

Puede lograr lo mismo con el carácter de espacio de ancho cero &#8203;(o &#x200B).


Para su información, también hay CSShyphens: auto compatible con los últimos IE, Firefox y Safari ( pero actualmente no es Chrome ):

div.breaking {
  hyphens: auto;
}

Sin embargo, esa separación se basa en un diccionario de separación y no se garantiza que rompa palabras largas. Sin embargo, puede hacer que el texto justificado sea más bonito.

Solución de retro-lloriqueo

<table>porque el diseño es malo, pero display:tableen otros elementos está bien. Será tan peculiar (y elástico) como las mesas de la vieja escuela:

div.breaking {
   display: table-cell;
}

overflowy las white-space: pre-wraprespuestas a continuación también son buenas.


77
¡Frio! Según Wikipedia, puede obtener un espacio de ancho cero con & # 8203; - Desde que lo mencionaste, ¿conoces un código de escape menos feo para él?
Memorizaré

1
@ojrac: eso depende de si piensas & # x200B; es "menos feo" o no. :-) AFAIK, no hay "entidad de palabra" para el espacio de ancho cero.
Ben Blank

1
Eso es bueno, pero no es una solución al problema inicial.
Albus Dumbledore

25
Esto rompe copiar / pegar.
nornagon

44
Solo para tu información, también puedes usar <wbr>. Ver quirksmode.org/oddsandends/wbr.html .
HaxElit

40

Dos correcciones:

  1. overflow:scroll - esto asegura que su contenido se pueda ver a costa del diseño (las barras de desplazamiento son feas)
  2. overflow:hidden- solo corta cualquier desbordamiento. Sin embargo, significa que las personas no pueden leer el contenido.

Si (en el ejemplo SO) desea evitar que se superponga al relleno, probablemente tenga que crear otro div, dentro del relleno, para contener su contenido.

Editar: Como dicen las otras respuestas, hay una variedad de métodos para truncar las palabras, ya sea calcular el ancho de renderizado en el lado del cliente (nunca intente hacer este lado del servidor, ya que nunca funcionará de manera confiable, multiplataforma) a través de JS e insertando caracteres de ruptura, o usando etiquetas CSS no estándar y / o muy incompatibles ( word-wrap: break-word no parece funcionar en Firefox ).

Sin embargo, siempre necesitará un descriptor de desbordamiento. Si su div contiene otra pieza de contenido de tipo bloque demasiado ancho (imagen, tabla, etc.), necesitará un desbordamiento para que no destruya el diseño / diseño.

Por lo tanto, utilice otro método (o una combinación de ellos), pero recuerde agregar también el desbordamiento para que cubra todos los navegadores.

Edición 2 (para abordar su comentario a continuación):

Comience usando la overflowpropiedad CSS no es perfecta pero detiene la rotura de los diseños. Aplicar overflow:hiddenprimero. Recuerde que el desbordamiento puede no romperse en el relleno, por lo tanto, anide divo use un borde (lo que sea mejor para usted).

Esto ocultará el contenido desbordado y, por lo tanto, puede perder el significado. Puede usar una barra de desplazamiento (usando overflow:autoo en overflow:scrolllugar de overflow:hidden), pero dependiendo de las dimensiones del div y de su diseño, esto podría no verse o funcionar muy bien.

Para solucionarlo, podemos usar JS para hacer retroceder las cosas y hacer algún tipo de truncamiento automático. Estaba a mitad de camino escribiendo un pseudocódigo para usted, pero se vuelve muy complicado a mitad de camino. Si necesita mostrar tanto como sea posible, eche un vistazo al guionizador ( como se menciona a continuación ).

Solo tenga en cuenta que esto tiene un costo para las CPU del usuario. Podría provocar que las páginas tarden mucho en cargarse o cambiar su tamaño.


1
con desbordamiento de texto: puntos suspensivos; El texto se puede cortar muy bien.
Kornel

1
desbordamiento de texto: los puntos suspensivos son solo de IE (y, por extensión, no estándar).
Oli

Siempre iría por overflow: scroll;si el contenido contiene información útil. Y luego el próximo objetivo es intentar crear tal CSS que las barras de desplazamiento no aparezcan. Y en caso de que lo hagan, siempre tiene las barras de desplazamiento como respaldo.
Yeti

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

33

Este es un problema complejo, como sabemos, y no se admite de manera común entre los navegadores. La mayoría de los navegadores no admiten esta característica de forma nativa.

En algunos trabajos realizados con correos electrónicos HTML, donde se usaba el contenido del usuario, pero el script no está disponible (e incluso CSS no es muy compatible), el siguiente bit de CSS en un contenedor alrededor de su bloque de contenido sin espacio debería al menos ayudar algo:

.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) */
}

En el caso de los navegadores basados ​​en Mozilla, el archivo XBL mencionado anteriormente contiene:

<?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>

Desafortunadamente, a Opera 8+ no parece gustarle ninguna de las soluciones anteriores, por lo que JavaScript tendrá que ser la solución para esos navegadores (como Mozilla / Firefox). Otra solución de navegador cruzado (JavaScript) que incluye las ediciones posteriores de Opera sería utilizar el script de Hedger Wang que se encuentra aquí: http://www.hedgerwow.com/360/dhtml/css-word-break.html

Otros enlaces / pensamientos útiles:

Babble incoherente »Archivo del blog» Emulación de encapsulado de palabras CSS para Mozilla / Firefox
http://blog.stchur.com/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/

[OU] No se ajusta la palabra en Opera, se muestra bien en IE
http://list.opera.com/pipermail/opera-users/2004-November/024467.html
http://list.opera.com/pipermail/opera- usuarios / 2004-noviembre / 024468.html


¿Qué pasa si lo que necesito es ancho: 100%? Esto significa el 100% del contenedor exterior. El propósito de esto es evitar que aparezcan barras de desplazamiento horizontal en la página y estropear el resto del diseño.
pilavdzice

1
Las versiones más recientes de Firefox ahora admiten la word-wrap: break-word;propiedad CSS, por lo que si no necesita soporte en Firefox para versiones anteriores, puede eliminar el XBL.
Neil Monroe

27

CSS Cross Browser Word Wrap

.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+ */
}

No es compatible con Opera 9.24
SCC

14

Usa el estilo word-break:break-all;. Sé que funciona en las mesas.


@sanimalp No es compatible con Opera 9.24
SCC

13

¿Quiere decir que, en los navegadores que lo admiten, word-wrap: break-wordno funciona?

Si se incluye en la definición del cuerpo de la hoja de estilo , debería funcionar en todo el documento.

Si el desbordamiento no es una buena solución, solo un javascript personalizado podría dividir artificialmente una palabra larga.

Nota: también existe esta <wbr>etiqueta Word Break . Esto le da al navegador un lugar donde puede dividir la línea. Desafortunadamente, la <wbr>etiqueta no funciona en todos los navegadores, solo en Firefox e Internet Explorer (y Opera con un truco CSS).


9

Acabo de comprobar IE 7, Firefox 3.6.8 Mac, Firefox 3.6.8 Windows y Safari:

word-wrap: break-word;

funciona para enlaces largos dentro de un div con un ancho establecido y sin desbordamiento declarado en el css:

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

No veo ningún problema de incompatibilidad.



6

Después de muchas peleas, esto es lo que funcionó para mí:

.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 en las últimas versiones de Chrome, Firefox y Opera.

Tenga en cuenta que excluí muchas de las white-spacepropiedades que sugirieron los demás, lo que realmente rompió la presangría para mí.


5

Para mí en un div sin tamaño fijo y con contenido dinámico, funcionó usando:

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

4

Regex en este comentario , es bueno, pero agrega el guión tímido solo entre grupos de 5 caracteres que no son espacios en blanco o guiones. Eso permite que el último grupo sea mucho más largo de lo previsto, ya que no hay un grupo coincidente después de él.

Por ejemplo, esto:

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

... resulta en esto:

abcde&shy;12345678901234

Aquí hay una versión con anticipación positiva para evitar ese problema:

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

... con este resultado:

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

4

La solución que generalmente uso para este problema es establecer 2 reglas CSS diferentes para IE y otros navegadores:

word-wrap: break-word;

woks perfecto en IE, pero word-wrap no es una propiedad CSS estándar. Es una propiedad específica de Microsoft y no funciona en Firefox.

Para Firefox, lo mejor que se puede hacer usando solo CSS es establecer la regla

overflow: hidden;

para el elemento que contiene el texto que desea ajustar. No ajusta el texto, pero oculta la parte del texto que supera el límite del contenedor . Puede ser una buena solución si no es esencial que muestre todo el texto (es decir, si el texto está dentro de una <a>etiqueta)


word-wrap: break-word parece funcionar bien para mí en Firefox 10.
Jon Schneider

CanIUse dice que es compatible con IE8 +, Firefox28 +, Chrome33 +, Safari7 + y más. caniuse.com/#search=word-wrap
Adrien Be

4

Actualización: Manejar esto en CSS es maravillosamente simple y de bajo costo, pero no tienes control sobre dónde ocurren las interrupciones cuando lo hacen. Eso está bien si no le importa, o si sus datos tienen ejecuciones alfanuméricas largas sin interrupciones naturales. Teníamos muchas rutas de archivos largas, URL y números de teléfono, todos los cuales tienen lugares en los que es significativamente mejor que otros.

Nuestra solución fue usar primero un reemplazo de expresiones regulares para poner un espacio de ancho cero (& # 8203;) después de cada 15 (digamos) caracteres que no son espacios en blanco o uno de los caracteres especiales donde preferiríamos los saltos. Luego hacemos otro reemplazo para poner un espacio de ancho cero después de esos caracteres especiales.

Los espacios de ancho cero son agradables, porque nunca son visibles en la pantalla; los guiones tímidos eran confusos cuando aparecían, porque los datos tienen guiones significativos. Los espacios de ancho cero tampoco se incluyen cuando copia texto fuera del navegador.

Los caracteres de corte especiales que estamos usando actualmente son punto, barra diagonal, barra diagonal inversa, coma, guión bajo, @, | y guión. No pensaría que necesitaría hacer algo para alentar la ruptura después de los guiones, pero Firefox (3.6 y 4 al menos) no se rompe solo en guiones rodeados de números (como los números de teléfono).

También queríamos controlar el número de caracteres entre descansos artificiales, en función del espacio de diseño disponible. Eso significaba que la expresión regular para coincidir con largas carreras sin interrupción tenía que ser dinámica. Esto se llama mucho, y no queríamos crear las mismas expresiones regulares idénticas una y otra vez por razones de rendimiento, por lo que utilizamos un simple caché de expresiones regulares, clave por la expresión de expresiones regulares y sus banderas.

Aquí está el código; Probablemente, el espacio de nombres de las funciones en un paquete de utilidad:

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 = {};

Prueba así:

makeWrappable('12345678901234567890 12345678901234567890 1234567890/1234567890')

Actualización 2: Parece que los espacios de ancho cero de hecho están incluidos en el texto copiado en al menos algunas circunstancias, simplemente no puede verlos. Obviamente, alentar a las personas a que copien texto con caracteres ocultos es una invitación a que ingresen datos como ese en otros programas o sistemas, incluso en el suyo, donde pueden causar problemas. Por ejemplo, si termina en una base de datos, las búsquedas en su contra pueden fallar, y es probable que las cadenas de búsqueda como esta también fallen. El uso de teclas de flecha para moverse por datos como este requiere (correctamente) una pulsación de tecla adicional para moverse por el personaje que no puede ver, algo extraño para los usuarios si lo notan.

En un sistema cerrado, puede filtrar ese carácter en la entrada para protegerse, pero eso no ayuda a otros programas y sistemas.

En total, esta técnica funciona bien, pero no estoy seguro de cuál sería la mejor opción de personaje que causa la ruptura.

Actualización 3: Tener este personaje terminar en datos ya no es una posibilidad teórica, es un problema observado. Los usuarios envían datos copiados de la pantalla, se guardan en la base de datos, las búsquedas se rompen, las cosas se ordenan de forma extraña, etc.

Hicimos dos cosas:

  1. Escribió una utilidad para eliminarlos de todas las columnas de todas las tablas en todas las fuentes de datos para esta aplicación.
  2. Se agregó un filtro para eliminarlo a nuestro procesador de entrada de cadena estándar, por lo que desaparece cuando cualquier código lo ve.

Esto funciona bien, al igual que la técnica en sí, pero es una historia de advertencia.

Actualización 4: Estamos usando esto en un contexto en el que los datos alimentados a esto pueden ser HTML escapado. En las circunstancias correctas, puede insertar espacios de ancho cero en el medio de entidades HTML, con resultados originales.

La solución fue agregar ampersand a la lista de personajes en los que no rompemos, así:

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

if(domainName.length > 15) domainName.replace(/([^\\s]{5})(?=[^\\s])/g, '$1&#8203;');
Usé

3

Es necesario establecer "diseño de tabla: fijo" para que funcione el ajuste de texto


1
¡Gracias por esto! Ajuste de palabra: palabra de interrupción; de lo contrario no funcionará para las tablas.
liviucmg

2

HYPHENATOR es la respuesta correcta (dada anteriormente). El verdadero problema detrás de su pregunta es que los navegadores web siguen siendo (en 2008) extremadamente primitivos que no tienen una función de separación silábica. Mire, todavía estamos en los inicios del uso de la computadora: tenemos que ser pacientes. Mientras los diseñadores dominen el mundo web, tendremos dificultades para esperar algunas características nuevas realmente útiles.

ACTUALIZACIÓN: A partir de diciembre de 2011, ahora tenemos otra opción, con el soporte emergente de estas etiquetas en FF y Safari:

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

He hecho algunas pruebas básicas y parece funcionar en una versión reciente de Mobile Safari y Safari 5.1.1.

Tabla de compatibilidad: https://developer.mozilla.org/en/CSS/hyphens#AutoCompatibilityTable



2

Utilizar este

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

1

Si tienes esto ...

  <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>

simplemente cambie a un formato vertical que contenga divs y use min-width en su CSS en lugar de ancho -

  <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/>

Por supuesto, si está mostrando datos tabulares genuinos, está bien usar una tabla real, ya que es semánticamente correcta e informará a las personas que usan lectores de pantalla que se supone que están en una tabla. Los está utilizando para el diseño general o el corte de imágenes para que la gente lo linche.


1

Tuve que hacer lo siguiente porque, si las propiedades no se declararan en el orden correcto, rompería las palabras al azar en el lugar equivocado y sin agregar un guión.

    -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;

Publicado originalmente por Enigmo: https://stackoverflow.com/a/14191114


1

Sí, si es posible, establecer un ancho absoluto y la configuración overflow : autofunciona bien.


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


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



0

Después de que la palabra termine y se rompa, conserve su desbordamiento y vea si esto resuelve su problema. simplemente cambie la pantalla de su div a:display: inline;


-1

Una función simple (requiere underscore.js) - basada en la respuesta @porneL

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

-1

He escrito una función que funciona muy bien donde inserta &shy;x letras en la palabra para un buen salto de línea. Todas las respuestas aquí no son compatibles con todos los navegadores y dispositivos, pero esto funciona bien con 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);

}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.