Le CSS peut-il forcer un saut de ligne après chaque mot dans un élément?

159

Je construis un site multilingue, le propriétaire m'aidant pour quelques traductions. Certaines des phrases affichées nécessitent des sauts de ligne pour conserver le style du site.

Malheureusement, le propriétaire n'est pas un informaticien, donc s'il voit il foo<br />bary a une chance qu'il modifie les données d'une manière ou d'une autre pendant qu'il traduit.

Existe-t-il une solution CSS (en plus de changer la largeur) à appliquer à un élément qui se briserait après chaque mot?

(Je sais que je peux faire cela en PHP, mais je me demande s'il y a une astuce astucieuse que je ne connais pas en CSS pour accomplir la même chose, peut-être dans les fonctionnalités CJK.)

ÉDITER

Je vais essayer de schématiser ce qui se passe:

----------------          ----------------
| Short Word   |          | Gargantuan   |
|              |          | Word         |
----------------          ----------------

Le mot long se brise automatiquement, pas le mot court. Je veux que ça ressemble à ceci:

----------------          ----------------
| Short        |          | Gargantuan   |
| Word         |          | Word         |
----------------          ----------------
Ben
la source
2
En HTML, les éléments se cassent après chaque mot, lorsque la largeur d'un élément donné l'exige. Voulez-vous dire dans les mots?
Paul D.Waite
@Paul - Non, j'ai besoin d'une solution qui ne soit pas basée sur la fixation de la largeur. Le problème est que certaines phrases sont plus longues et se cassent automatiquement (comme vous le décrivez) et certaines phrases sont plus courtes et ne se cassent pas, ce qui donne une présentation incohérente.
Ben
@Paul - Oui, c'est comme vous le décrivez exactement. Ne nuit pas vraiment à la mise en page, mais cela pourrait mieux paraître.
Ben
vous pouvez utiliser l'espacement des mots, mais cela affecterait tous les mots. Je pense que vous ne pouvez pas vous déplacer en enveloppant ces mots dans des éléments span.
meo
@meo - On dirait ça, merci pour la pensée
Ben

Réponses:

261

Utilisation

.one-word-per-line {
    word-spacing: <parent-width>; 
}

.your-classname{
    width: min-intrinsic;
    width: -webkit-min-content;
    width: -moz-min-content;
    width: min-content;
    display: table-caption;
    display: -ms-grid;
    -ms-grid-columns: min-content;
}

<parent-width>est la largeur de l'élément parent (ou une valeur arbitraire élevée qui ne tient pas dans une ligne). De cette façon, vous pouvez être sûr qu'il y a même un saut de ligne après une seule lettre. Fonctionne avec Chrome / FF / Opera / IE7 + (et probablement même IE6 car il prend également en charge l'espacement des mots).

Hurs van Bloob
la source
C'est certainement la meilleure réponse à mon humble avis
Hezad
31
@ToniMichelCaubet La réponse est vraiment difficile à interpréter, mais il veut dire: .parent { word-spacing: 100px; }100pxest la largeur de l'élément parent. Le problème est que cette solution ne fonctionne pas si vous avez un parent fluide.
John Kurlak
5
Définissez simplement une valeur très élevée pour l'espacement des mots, par exemple, word-spacing: 100000pxet vous n'aurez pas à vous soucier de la fluidité du parent en termes de largeur. Définir un espacement des mots de 100% aurait eu du sens (cela aurait été 100% de la largeur du parent), mais les valeurs exprimées en pourcentage ne sont pas prises en charge pour cette propriété css.
sboisse
1
Cela a été très utile. Je l'ai utilisé dans une situation réactive, où à une largeur je veux que le texte dans les onglets soit enveloppé pour qu'ils soient tous de la même hauteur: word-spacing: 2em; et à une largeur mobile, je veux qu'ils soient sur une seule ligne:word-spacing: unset;
Sera
1
Ceci est incroyable. Des années dans le futur, merci beaucoup :)
Lucas Medina
124

La réponse donnée par @HursVanBloob fonctionne uniquement avec le conteneur parent de largeur fixe, mais échoue dans le cas de conteneurs à largeur fluide .

J'ai essayé beaucoup de propriétés, mais rien n'a fonctionné comme prévu. Enfin, je suis arrivé à la conclusion que donner word-spacingune valeur très énorme fonctionne parfaitement bien.

p { word-spacing: 9999999px; }

ou, pour les navigateurs modernes, vous pouvez utiliser l' vwunité CSS (largeur visuelle en% de la taille de l'écran).

p { word-spacing: 100vw; }
Deepak Yadav
la source
c'est ce que je vais essayer!
vaskort
C'est une excellente solution!
Joe Conlin
Rompre complètement avec & nbsp; bien que.
Matt Fletcher
2
Eh bien, cela ne fonctionne pas pour moi qui rend la largeur fluide du conteneur très très haute.
Onza
@Onza pouvez-vous partager un lien de violon, montrant votre problème?
Deepak Yadav
37

Une solution alternative est décrite sur Phrase séparée à un mot par ligne , en appliquant display:table-caption;à l'élément

Malcomio
la source
En fait, cela ne regroupe que les mots en fonction de la largeur du mot le plus long.
James South
1
Bien que cela puisse regrouper les mots sur une ligne, cela fonctionne très bien dans de nombreuses situations et ne semble pas aussi piraté que l'option d'espacement massif des mots.
Dale
1
C'est celui qui a parfaitement fonctionné pour moi, gentil!
Matt Fletcher
1
Il ne donne aucun résultat
jafarbtech
32

Essayez d'utiliser white-space: pre-line;. Il crée un saut de ligne partout où un saut de ligne apparaît dans le code, mais ignore les espaces supplémentaires (tabulations et espaces, etc.).

Tout d'abord, écrivez vos mots sur des lignes séparées dans votre code:

<div>Short
Word</div>

Appliquez ensuite le style à l'élément contenant les mots.

div { white-space: pre-line; }

Attention cependant, chaque saut de ligne dans le code à l'intérieur de l'élément créera un saut de ligne. Donc, écrire ce qui suit entraînera un saut de ligne supplémentaire avant le premier mot et après le dernier mot:

<div>
    Short
    Word
</div>

Il existe un excellent article sur les astuces CSS expliquant les autres attributs d'espace blanc.

Nass
la source
Vous devez expliquer comment white-spacepeut être utilisé pour répondre à la question. Désolé, mais je ne vois pas comment.
jlgrall
2
Eh bien, l'article sur CSS Tricks l' explique complètement, alors j'ai pensé qu'un lien serait suffisant, plutôt que d'essayer de régurgiter la réponse ici.
Nass
Ok, alors vous suggérez de mettre de vrais sauts de ligne dans la source, et d'utiliser le CSS " white-space: pre;" pour afficher ces sauts de ligne comme le <pre>ferait une balise? Cela pourrait fonctionner, et un saut de ligne devrait sembler plus naturel aux traducteurs qu'un <br />. Je vais essayer de modifier votre réponse pour l'ajouter :)
jlgrall
Exactement. En fait, ce white-space: pre-line;serait probablement plus approprié, car il ignore les espaces supplémentaires dans votre code. Je mettrai à jour la réponse.
Nass
Bon, peut-être juste ajouter white-space: pre;pour IE 7.
jlgrall
12

Si vous souhaitez pouvoir choisir parmi différentes solutions, en plus des réponses données ...

Une autre méthode consiste à donner au conteneur une largeur de 0 et à s'assurer que le débordement est visible. Ensuite, chaque mot en débordera et sera sur sa propre ligne.

div {
  width: 0;
  overflow: visible;
}
<div>Short Word</div>
<hr>
<div>Gargantuan Word</div>

Ou vous pouvez utiliser l'une de ces nouvelles widthvaleurs proposées , à condition qu'elles existent toujours au moment où vous lisez ceci.

div {
  width: min-intrinsic;       /* old Chrome, Safari */
  width: -webkit-min-content; /* less old Chrome, Safari */
  width: -moz-min-content;    /* current Firefox */
  width: min-content;         /* current Chrome, Safari; not IE or Edge */
}
<div>Short Word</div>
<hr>
<div>Gargantuan Word</div>

Monsieur Lister
la source
4

Vous ne pouvez pas cibler chaque mot en CSS. Cependant, avec un peu de jQuery, vous pourriez probablement le faire.

Avec jQuery, vous pouvez envelopper chaque mot dans un <span>intervalle de jeu CSS, puis dans display:blocklequel le placerait sur sa propre ligne.

En théorie bien sûr: P

marque
la source
Oui, j'avais peur de ça. Je pourrais aussi le faire en PHP mais cela semble être une solution moche. Je pensais qu'il pourrait y avoir un :first-childtruc ou quelque chose là-bas ...
Ben
@Steve: non, les sélecteurs CSS vous permettent actuellement de sélectionner uniquement des éléments HTML, pas des nœuds de texte. J'ai jeté un coup d'œil au module CSS 3 Text , mais il ne semble pas y avoir quoi que ce soit qui force une pause après chaque mot dans un élément. La solution de Mark est votre meilleur pari.
Paul D.Waite
@Paul, @Mark - Si l'un de vous veut le représentant, vous pouvez en faire une réponse et je l'accepterai. Je vais marquer cela comme sans réponse (pour l'instant) par meta.stackoverflow.com/questions/48013/… .
Ben
Je pense que Mark a déjà fait une réponse, tout le représentant est à lui en ce qui me concerne.
Paul D.Waite
@Paul - +1 joueur d'équipe donne au gars un badge ou quelque chose :)
Ben
2

https://jsfiddle.net/bm3Lfcod/1/

Pour ceux qui recherchent une solution qui fonctionne dans un conteneur parent flexible avec un enfant flexible dans les deux dimensions. par exemple. boutons de la barre de navigation.

//the parent (example of what it may be)
div {
  display:flex;
  width: 100%;
}

//The children
a {
  display: inline-block;
}

//text wrapper
span {
  display: table-caption;
}
Onza
la source
Essayez de donner cette durée à toute autre CSSpropriété que vous pouvez donner. Dites une propriété qui pourrait causerbrowser reflow
Deepak Yadav
1
redistribution du navigateur?
Onza
2

J'ai été confronté au même problème et aucune des options proposées ici ne m'a aidé. Certains services de messagerie ne prennent pas en charge les styles spécifiés. Voici ma version, qui a résolu le problème et fonctionne partout où j'ai vérifié:

<table>
    <tr>
        <td width="1">Gargantuan Word</td>
    </tr>
</table>

OU en utilisant CSS:

<table>
    <tr>
        <td style="width:1px">Gargantuan Word</td>
    </tr>
</table>
eep
la source
2

La meilleure solution est la word-spacingpropriété.

Ajoutez le <p>dans un conteneur avec une taille spécifique (exemple 300px) et après vous devez ajouter cette taille comme valeur dans l'espacement des mots.

HTML

<div>
 <p>Sentence Here</p>
</div>

CSS

div {
 width: 300px;
}

p {
 width: auto;
 text-align: center;
 word-spacing: 300px;
}

De cette façon, votre phrase sera toujours coupée et placée dans une colonne, mais le avec du paragraphe sera dynamique.

Voici un exemple Codepen

Cosimo wiSe
la source
-1

Dans mon cas,

    word-break: break-all;

a fonctionné parfaitement, j'espère que cela aidera tout autre nouveau venu comme moi.

Emanuel Hiroshi
la source
Un -1 de ma part car c'est une réponse incorrecte. Cela coupe la ligne à chaque caractère SI nécessaire.
Emobe le