Ben
Ben

Reputation: 57209

Can CSS force a line break after each word in an element?

I'm building a multilingual site, with the owner helping me with some translations. Some of the displayed phrases need line breaks to maintain the style of the site.

Unfortunately, the owner isn't a computer guy, so if he sees foo<br />bar there's the chance he'll modify the data somehow as he's translating.

Is there a CSS solution (besides changing the width) to apply to an element which would break after every word?

(I know I can do this in PHP, but I'm wondering if there's a nifty trick I don't know about in CSS to accomplish the same thing, perhaps in the CJK features.)

EDIT

I'll attempt to diagram what's happening:

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

The long word breaks automatically, the short word doesn't. I want it to look like this:

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

Upvotes: 231

Views: 294587

Answers (14)

PussInBoots
PussInBoots

Reputation: 12303

TL;DR: Split the words and join them with a <br> tag.

Note 1: This is a non-CSS alternative solution.

Note 2: This is specific to my own specific problem and it works fine and I'm okay with the cons; i.e. more compute power needed, the addition of JavaScript and adding extra
tags between each word. Again, this works fine in my React.js project and I thought I'd share it in case someone finds it useful.

// @ts-nocheck
const HeadingCell = ({cell}) => {
  const splitHeading = (heading) => {
    const words = heading.split(' ')
    const joinedWords = words.join('<br>')
    return joinedWords
  }

  return <span dangerouslySetInnerHTML={{__html: splitHeading(cell.data.heading)}}></span>
}

export default HeadingCell

Upvotes: 0

Mike Vosseller
Mike Vosseller

Reputation: 4197

If you can add markup (e.g. a span) around each word then you can use CSS to insert a line break after each.

Note that the "content" we are inserting is \a which is hex for decimal 10 which is the newline character.

.break-after-each-word > .word::after {
  content: "\a";
  white-space: pre;
}
<div class="break-after-each-word">
  <span class="word">Foo</span>
  <span class="word">Bar</span>
  <span class="word">Baz</span>
</div>

Upvotes: 0

user2970934
user2970934

Reputation: 79

I did this on a project where the client wanted the 3 word title on a different line. Basically your increase the spaces with CSS the use the white-space to separate the lines.

    word-spacing:9999px;
    white-space: pre-line;

Upvotes: 3

claudiu
claudiu

Reputation: 289

<span> is an inline element and I'm adding an display: inline-block to give a width to the element max-width: min-content;, min-content is the value/width of the smallest word in your text/sentance.

If you use min-content, the "width" will be your longest word. In this case Example is your longer word. But if you have different words like and if or few 2/3 char words then this words will fit on the same line.

If you want to keep the on word behavior you can give a fixed width, for example 5px.

Check more examples in CodePen.

.wrapWord {
  display: inline-block;
  max-width: min-content;
}
<div>
  <span class="wrapWord">
   Example Word
  </span>
</div>

Upvotes: 24

Hurs van Bloob
Hurs van Bloob

Reputation: 3132

Use

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

where <parent-width> is the width of the parent element (or an arbitrary high value that doesn't fit into one line). That way you can be sure that there is even a line-break after a single letter. Works with Chrome/FF/Opera/IE7+ (and probably even IE6 since it's supporting word-spacing as well).

Upvotes: 310

Emanuel Hiroshi
Emanuel Hiroshi

Reputation: 358

In my case,

    word-break: break-all;

worked perfecly, hope it helps any other newcomer like me.

Upvotes: -4

Cosimo wiSe
Cosimo wiSe

Reputation: 133

The best solution is the word-spacing property.

Add the <p> in a container with a specific size (example 300px) and after you have to add that size as the value in the word-spacing.

HTML

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

CSS

div {
 width: 300px;
}

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

In this way, your sentence will be always broken and set in a column, but the with of the paragraph will be dynamic.

Here an example Codepen

Upvotes: 8

eep
eep

Reputation: 61

I faced the same problem, and none of the options here helped me. Some mail services do not support specified styles. Here is my version, which solved the problem and works everywhere I checked:

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

OR using CSS:

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

Upvotes: 2

Mr Lister
Mr Lister

Reputation: 46539

If you want to be able to choose from different solutions, in addition to the given answers...

An alternative method is to give the container a width of 0 and to make sure overflow is visible. Then each word will overflow out of it and will be on its own line.

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

Or you can use one of those newly proposed width values, provided those still exist by the time you read this.

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>

Upvotes: 29

Deepak Yadav
Deepak Yadav

Reputation: 7069

The answer given by @HursVanBloob works only with fixed width parent container, but fails in case of fluid-width containers.

I tried a lot of properties, but nothing worked as expected. Finally I came to a conclusion that giving word-spacing a very huge value works perfectly fine.

p { word-spacing: 9999999px; }

or, for the modern browsers you can use the CSS vw unit (visual width in % of the screen size).

p { word-spacing: 100vw; }

Upvotes: 204

Onza
Onza

Reputation: 1830

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

For those seeking for a solution that works within a flexible parent container with a children that is flexible in both dimensions. eg. navbar buttons.

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

Upvotes: 2

malcomio
malcomio

Reputation: 711

An alternative solution is described on Separate sentence to one word per line, by applying display:table-caption; to the element

Upvotes: 45

Mark
Mark

Reputation: 427

You can't target each word in CSS. However, with a bit of jQuery you probably could.

With jQuery you can wrap each word in a <span> and then CSS set span to display:block which would put it on its own line.

In theory of course :P

Upvotes: 6

Nass
Nass

Reputation: 709

Try using white-space: pre-line;. It creates a line-break wherever a line-break appears in the code, but ignores the extra whitespace (tabs and spaces etc.).

First, write your words on separate lines in your code:

<div>Short
Word</div>

Then apply the style to the element containing the words.

div { white-space: pre-line; }

Be careful though, every line break in the code inside the element will create a line break. So writing the following will result in an extra line break before the first word and after the last word:

<div>
    Short
    Word
</div>

There's a great article on CSS Tricks explaining the other white-space attributes.

Upvotes: 55

Related Questions