web-dev-qa-db-fra.com

Comment empêcher les longs mots de casser ma div?

Depuis le passage de TABLE-layout à DIV-layout, un problème commun subsiste:

PROBLÈME : vous remplissez votre DIV de texte dynamique et il y a inévitablement un mot très long qui s'étend sur le bord de votre colonne div et donne à votre site un aspect peu professionnel. .

RETRO-WHINING: Ceci n'est jamais arrivé avec les dispositions de table. Une cellule de tableau s'étendra toujours à la largeur du mot le plus long.

GRAVITÉ : Je vois ce problème même sur les sites les plus importants, en particulier sur les sites allemands où même des mots tels que "limitation de la vitesse" sont très longs ("Geschwindigkeitsbegrenzung" ").

Quelqu'un at-il une solution viable à cela?

146
Edward Tanguay

Trait d'union

Vous pouvez indiquer aux navigateurs où scinder des mots longs en insérant un trait d'union (­):

averyvery­longword

peut être rendu comme

averyverylongword

ou

averyvery-
longword

Une expression régulière Nice peut vous assurer de ne pas les insérer sauf si nécessaire:

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

Les navigateurs et les moteurs de recherche sont suffisamment intelligents pour ignorer ce caractère lors de la recherche de texte et Chrome et Firefox (n’ont pas testé les autres)) l’ignorent lors de la copie de texte dans le presse-papiers.

<wbr> élément

Une autre option consiste à injecter <wbr>, un ancien IE-ism , qui est maintenant en HTML5 :

averyvery<wbr>longword

Pauses sans trait d'union:

averyvery
longword

Vous pouvez obtenir le même résultat avec le caractère espace zéro-largeur &#8203; (ou &#x200B).


FYI il y a aussi CSS hyphens: auto pris en charge par les derniers IE, Firefox et Safari ( pas actuellement Chrome ):

div.breaking {
  hyphens: auto;
}

Toutefois, cette césure est basée sur un dictionnaire de césure et il n'est pas garanti que les mots longs soient cassés. Cela peut rendre le texte justifié plus joli cependant.

Rétro-gémissante

<table> pour la mise en page est mauvais, mais display:table sur d'autres éléments, c'est bien. Ce sera aussi bizarre (et extensible) que les tables old school:

div.breaking {
   display: table-cell;
}

overflow et white-space: pre-wrap Les réponses ci-dessous sont bien aussi.

135
Kornel

Deux correctifs:

  1. overflow:scroll _ - cela garantit que votre contenu peut être vu au détriment de la conception (les barres de défilement sont laides)
  2. overflow:hidden - juste couper tout débordement. Cela signifie cependant que les gens ne peuvent pas lire le contenu.

Si (dans l'exemple SO)) vous souhaitez empêcher le chevauchement du remplissage, vous devrez probablement créer un autre div, à l'intérieur du remplissage, pour contenir votre contenu.

Edit: Comme l’autre état des réponses, il existe différentes méthodes pour tronquer les mots, notamment l’épaisseur de rendu du côté client (ne tentez jamais de le faire côté serveur car il ne fonctionnera jamais de manière fiable, multiplate-forme). JS et l’insertion de sauts de caractères, ou l’utilisation de balises CSS non standard et/ou très incompatibles (Word-wrap: break-Wordne semble pas fonctionner dans Firefox ).

Cependant, vous aurez toujours besoin d'un descripteur de débordement. Si votre div contient un autre élément de contenu de type bloc trop large (image, tableau, etc.), vous aurez besoin d'un débordement pour éviter de détruire la mise en page/conception.

Donc, bien sûr, utilisez une autre méthode (ou une combinaison des deux), mais n'oubliez pas d'ajouter un débordement afin de couvrir tous les navigateurs.

Edit 2 (pour répondre à votre commentaire ci-dessous):

Commencer par utiliser la propriété CSS overflow n’est pas parfait, mais empêche la création de conceptions. Appliquer overflow:hidden première. Rappelez-vous que le débordement peut ne pas se rompre lors du remplissage, vous devez donc imbriquer divs ou utiliser une bordure (à votre convenance).

Cela masquerait le contenu débordant et vous risqueriez de perdre tout son sens. Vous pouvez utiliser une barre de défilement (en utilisant overflow:auto ou overflow:scroll au lieu de overflow:hidden) mais selon les dimensions de la div et votre conception, cela pourrait ne pas sembler ou ne pas bien fonctionner.

Pour résoudre ce problème, nous pouvons utiliser JS pour récupérer des données et effectuer une forme de troncature automatisée. J'étais à mi-chemin en train de vous écrire un pseudo-code, mais cela devient sérieusement compliqué à mi-chemin. Si vous avez besoin de montrer autant que possible, jetez un oeil à trait d'union ( comme mentionné ci-dessous ).

Sachez simplement que cela se fait au détriment des processeurs de l'utilisateur. Le chargement et/ou le redimensionnement de pages prendrait beaucoup de temps.

41
Oli

Comme nous le savons, il s’agit d’un problème complexe qui n’est pas pris en charge de manière commune par les navigateurs. La plupart des navigateurs ne supportent pas cette fonctionnalité de manière native.

Dans certains travaux effectués avec des courriels HTML, où le contenu de l'utilisateur était utilisé, mais le script n'est pas disponible (et même le CSS n'est pas très bien supporté), le bit CSS suivant enveloppant votre bloc de contenu non espacé devrait au moins aider un peu:

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

Dans le cas des navigateurs basés sur Mozilla, le fichier XBL mentionné ci-dessus contient:

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

Malheureusement, Opera 8+ ne semble aimer aucune des solutions ci-dessus, JavaScript doit donc être la solution pour ces navigateurs (comme Mozilla/Firefox.). Une autre solution inter-navigateurs ( JavaScript) qui inclut les éditions ultérieures de Opera serait d'utiliser le script de Hedger Wang trouvé ici: http://www.hedgerwow.com/360/dhtml/css-Word- break.html

Autres liens/pensées utiles:

Incoherent Babble "Blog Archive" Émulation de CSS Word-wrap pour Mozilla/Firefox
http://blog.stchur.com/2007/02/22/emulating-css-Word-wrap-for-mozillafirefox/

[OU] Pas de retour à la ligne dans Opera, l'affichage est parfait dans IE
http://list.opera.com/pipermail/opera-users/2004-November/024467.html
http://list.opera.com/pipermail/opera-users/2004-November/024468.html

33
Neil Monroe

Retour à la ligne CSS Word 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+ */
}
27
Remo

Utilisez le style Word-break:break-all;. Je sais que cela fonctionne sur les tables.

14
sanimalp

Voulez-vous dire que, dans les navigateurs qui le prennent en charge, Word-wrap: break-Word ne fonctionne pas?

Si inclus dans la définition du corps de la feuille de style , cela devrait fonctionner dans tout le document.

Si le dépassement de capacité n'est pas une bonne solution, seul un javascript personnalisé peut rompre artificiellement Word long.

Remarque: il y a aussi ceci [balise <wbr> Word Break) . Cela donne au navigateur un endroit où il peut diviser la ligne. Malheureusement, la balise <wbr> Ne fonctionne pas dans tous les navigateurs, uniquement dans Firefox et Internet Explorer (et Opera avec une astuce CSS).

13
VonC

Nous venons de cocher IE 7, Firefox 3.6.8 Mac, Firefox 3.6.8 Windows et Safari:

Word-wrap: break-Word;

fonctionne pour les liens longs à l'intérieur d'une div avec une largeur définie et aucun dépassement de capacité déclaré dans le fichier css:

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

Je ne vois aucun problème d'incompatibilité

9
Zac Imboden

Je viens de découvrir trait d'union de cette question . Cela pourrait résoudre le problème.

6
dylanfm

Après de nombreux combats, voici ce qui a fonctionné pour moi:

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

Fonctionne dans les dernières versions de Chrome, Firefox et Opera.

Notez que j’ai exclu beaucoup des propriétés white-space Proposées par les autres - qui ont cassé l’indentation pre pour moi.

6
mpen

Pour moi sur un div sans taille fixe et avec un contenu dynamique, cela a fonctionné en utilisant:

display:table;
Word-break:break-all;
5
Jacob

La solution que j'utilise habituellement pour résoudre ce problème consiste à définir 2 règles CSS différentes pour IE et les autres navigateurs:

Word-wrap: break-Word;

woks est parfait dans IE, mais Word-wrap n'est pas une propriété CSS standard. C'est une propriété spécifique à Microsoft et ne fonctionne pas dans Firefox.

Pour Firefox, la meilleure chose à faire en utilisant uniquement CSS est de définir la règle

overflow: hidden;

pour l'élément qui contient le texte que vous voulez envelopper. Cela n’enveloppe pas le texte, mais cache la partie du texte qui dépasse la limite du conteneur. Ce peut être une bonne solution si ce n’est pas essentiel pour vous d’afficher tout le texte (c’est-à-dire si le texte est à l’intérieur d’un <a> tag)

4
alexmeia

Re la regex dans ce commentaire , c'est bon, mais il ajoute le trait d'union timide uniquement entre les groupes de 5 caractères non-blancs-ou-tirets. Cela permet au dernier groupe d'être beaucoup plus long que prévu, car il n'y a pas de groupe correspondant après.

Par exemple, ceci:

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

... résultats dans ceci:

abcde&shy;12345678901234

Voici une version utilisant le lookahead positif pour éviter ce problème:

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

... avec ce résultat:

abcde&shy;12345&shy;67890&shy;1234
4
enigment

Mise à jour: Gérer cela en CSS est merveilleusement simple et peu onéreux, mais vous n’avez aucun contrôle sur le lieu où se produisent les ruptures. Cela ne pose pas de problème si vous ne vous en souciez pas ou si vos données ont une longue durée alphanumérique sans interruption naturelle. Nous avions beaucoup de longs chemins de fichiers, d'URL et de numéros de téléphone, qui ont tous des emplacements qu'il est nettement préférable de percer que d'autres.

Notre solution consistait tout d'abord à utiliser un remplacement d'expression régulière pour insérer un espace de largeur nulle (# 8203;) après 15 (par exemple) caractères qui ne sont pas des espaces ni l'un des caractères spéciaux pour lesquels nous préférerions les pauses. Nous faisons ensuite un autre remplacement pour mettre un espace de largeur zéro après ces caractères spéciaux.

Les espaces de largeur nulle sont agréables, car ils ne sont jamais visibles à l'écran. Les tirets timides étaient source de confusion quand ils ont montré, parce que les données ont des traits importants. Les espaces de largeur zéro ne sont pas non plus inclus lorsque vous copiez du texte hors du navigateur.

Les caractères de rupture spéciaux que nous utilisons actuellement sont les points, les barres obliques, les barres obliques inverses, les virgules, les traits de soulignement, @, | et les tirets. Vous ne penseriez pas que vous auriez besoin de faire quelque chose pour encourager la rupture après les traits d'union, mais Firefox (3.6 et 4 au moins) ne se casse pas lui-même lorsque les traits d'union sont entourés de chiffres (comme des numéros de téléphone).

Nous voulions également contrôler le nombre de caractères entre les pauses artificielles, en fonction de l'espace de disposition disponible. Cela signifiait que la regex pour correspondre à de longues exécutions non interrompues devait être dynamique. Cela s'appelle beaucoup, et pour des raisons de performance, nous ne voulions pas créer les mêmes regex identiques, nous avons donc utilisé un simple cache de regex, indexé par l'expression regex et ses indicateurs.

Voici le code; vous voudriez probablement nommer les fonctions dans un paquet d'utilitaire:

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

Testez comme ceci:

makeWrappable('12345678901234567890 12345678901234567890 1234567890/1234567890')

Mise à jour 2: Il semble que les espaces de largeur nulle sont inclus dans le texte copié dans au moins certaines circonstances, vous ne pouvez tout simplement pas les voir. Bien entendu, encourager les utilisateurs à copier du texte contenant des caractères masqués est une invitation à saisir des données de ce type dans d’autres programmes ou systèmes, même les vôtres, là où elles risquent de poser problème. Par exemple, si elle aboutit dans une base de données, les recherches peuvent échouer et les chaînes de recherche comme celle-ci risquent également d'échouer. Utiliser les touches fléchées pour parcourir des données comme celle-ci nécessite (à juste titre) un appui supplémentaire sur la touche pour vous déplacer dans le personnage que vous ne pouvez pas voir, ce qui est un peu étrange pour les utilisateurs s'ils le remarquent.

Dans un système fermé, vous pouvez filtrer ce caractère en entrée pour vous protéger, mais cela n’aide en rien les autres programmes et systèmes.

Tout compte fait, cette technique fonctionne bien, mais je ne suis pas certain du meilleur choix du personnage qui causera la rupture.

Mise à jour 3: Avoir ce personnage dans les données n’est plus une possibilité théorique, c’est un problème observé. Les utilisateurs soumettent des données copiées à partir de l’écran, elles sont enregistrées dans la base de données, les recherches sont interrompues, les choses s’arrangent étrangement, etc.

Nous avons fait deux choses:

  1. A écrit un utilitaire pour les supprimer de toutes les colonnes de toutes les tables de toutes les sources de données pour cette application.
  2. Ajout du filtrage pour le supprimer dans notre processeur d’entrée de chaîne standard, afin qu’il disparaisse au moment où le code le détecte.

Cela fonctionne bien, de même que la technique elle-même, mais c'est un récit édifiant.

Mise à jour 4: Nous l'utilisons dans un contexte où les données qui y sont introduites peuvent être échappées en HTML. Dans les bonnes circonstances, il peut insérer des espaces de largeur nulle au milieu d'entités HTML, avec des résultats géniaux.

Le correctif consistait à ajouter des esperluettes à la liste des caractères sur lesquels nous ne passons pas, comme ceci:

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

Besoin de définir "table-layout: fixed" pour que Word-wrap fonctionne

3
Aleks

tilisez ceci

Word-wrap: break-Word;
overflow-wrap: break-Word;
Word-break: break-all;
2
Jay Patel

HYPHENATOR est la bonne réponse (donnée ci-dessus). Le vrai problème qui se cache derrière votre question est que les navigateurs Web sont encore (en 2008) extrêmement primitifs et qu’ils n’ont pas de fonction de coupure de mots. Regardez, nous en sommes encore aux débuts de l'utilisation de l'ordinateur - nous devons être patients. Tant que les concepteurs domineront le Web, nous aurons du mal à attendre de nouvelles fonctionnalités vraiment utiles.

MISE À JOUR: En décembre 2011, nous avions maintenant une autre option, avec le support émergent de ces balises dans FF et Safari:

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

J'ai fait quelques tests de base et cela semble fonctionner sur une version récente de Mobile Safari et Safari 5.1.1.

Tableau de compatibilité: https://developer.mozilla.org/en/CSS/hyphens#AutoCompatibilityTable

2
Snaky Love

Pour la compatibilité avec IE 8+ utilisation:

-ms-Word-break: break-all;
     Word-break: break-all;

     /* Non standard for webkit */
     Word-break: break-Word;

-webkit-hyphens: auto;
   -moz-hyphens: auto;
        hyphens: auto;

Voir ici http://css-tricks.com/snippets/css/prevent-long-urls-from-breaking-out-of-container/

Tout ce que j'avais à faire était d'appliquer cela au style du conteneur div avec une largeur définie.

2
DoctorFox

Si vous avez ceci -

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

il suffit de passer à un format vertical contenant des div et d'utiliser min-width dans votre CSS au lieu de width -

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

Bien sûr, si vous affichez de véritables données tabulaires, vous pouvez utiliser un vrai tableau car il est sémantiquement correct et informera les personnes qui utilisent des lecteurs d’écran qui sont supposées se trouver dans un tableau. C’est pour les utiliser pour la mise en page générale ou le découpage d’image que les gens vont vous lyncher.

1
Dan Brown

Oui, si cela est possible, définir une largeur absolue et un paramètre overflow : auto fonctionne bien.

1
John Gietzen
p {
    overflow-wrap: break-Word;
}


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

Je devais faire ce qui suit parce que, si les propriétés n'étaient pas déclarées dans le bon ordre, les mots seraient cassés au hasard au mauvais endroit et sans ajouter de trait d'union.

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

Publié à l'origine par Enigmo: https://stackoverflow.com/a/14191114

1
jacobsvensson

"Word-wrap: break-Word" fonctionne dans Firefox 3.5 http://hacks.mozilla.org/2009/06/Word-wrap/

0
mb21

Ajoutez ceci à css de votre div: Word-wrap: break-Word;

0
Kishan Subhash

après tout ce que Word résout et casse, conservez votre débordement et voyez si cela résout votre problème. changez simplement l'affichage de votre div en: display: inline;

0
Olofu Mark