20

I design a great deal of simple single page web items for sales or email. I often find I run into issues with headlines and my desired line breaks at different media widths.

For example, I could have a headline such as:

Our New thingamabob is the best thing since sliced bread!

With absolutely no attention to line breaks the line breaks like this:

Our New thingamabob is the best thing since
sliced bread!

At full web size, I'd like to break the line after "the". Creating two lines.

Our New thingamabob is the
best thing since sliced bread!

For a screen with a medium width, I'd break twice:

Our New thingamabob
is the best thing
since sliced bread!

For even narrower screens, I'd break after "new", after "thingamabob", and after "thing". Creating four lines.

Our New
thingamabob
is the best thing
since sliced bread!

I really don't want to use break tags (<br>) because that hard-sets the breaks at all sizes. Up until now I've used media queries and width percentages for the various h1-h5 tags so that the width of the tag forces a break. But this seems "hacky" to me (it is also very temperamental at times based upon the actual text).

What's the best way to control line breaks without hard coding them into the html?

0

8 Answers 8

14

I'm only advising this on the basis that it's used for short snippets of text and not paragraphs.

The formatting of headlines can and should be controlled as much as possible within reasonable limits. JavaScript, or extra unnecessary elements are not quite "reasonable limits".

Non-Breaking Spaces on the other hand...               can be useful when used in moderation.
Placing them between the word pairs and triplets that you would like to keep together can produce the results you want.

However, you cannot use many consecutively, depending on the lengths of the words you're using, linking too many will force the text to overflow out of the viewport or its container.

Some quick experimentation on your own particular set of words should reveal the best words to link.

For the example in this question the HTML could look like:

<span>Our&nbsp;New thingamabob is&nbsp;the best&nbsp;thing since&nbsp;sliced&nbsp;bread!</span>

There is actually no CSS necessary here. The CSS in this example I've produced is just for fun.


In a nutshell, the key to this method is limiting the number of places where the text is allowed to break.


After re-reading the question, I realise I didn't quite satisfy the requirements. For this specific case, and on the assumption that there are other pages that require the same attention, I would define a single <br> for a full-width breakpoint. I would then reuse the same class on each of the pages at the most ideal place in the heading.

This <br> class would collapse at anything smaller than full-width acting as if it isn't even there, with the use of media queries. At viewport sizes less than full width, we rely on the &nbsp;'s alone.

Another example with a single <br> that's closer to the mark.

The HTML:

<span>
    Our&nbsp;New thingamabob is&nbsp;the<br class="full-width-breakpoint"/> best&nbsp;thing since&nbsp;sliced&nbsp;bread!
</span>

The CSS:

@media screen and (max-width:550px) {    /* Max Width depends on your design */     
    .full-width-breakpoint {             /* only experimentation or */
        display:none;                    /* calculation will reveal */
        line-height:0;                   /* the best max-width */
    }
}
2
  • 4
    For something as specific as the example in the question, this is the way to go Dec 20, 2014 at 17:45
  • 1
    This would seem to be the easiest, most straight-forward method. Thanks.
    – Scott
    Jan 2, 2015 at 17:22
6

The best practice is to acknowledge that you have no real control over line breaks on the web and it's best to design with that in mind.

Any solution to the contrary will, invariably, have to be hacky. As it will be a hack as HTML doesn't adhere to user defined line breaks outside of hard coding. You could do it with JS fairly easily. Set up your break points with empty spans with unique classes then based on the viewport size you could inject BR tags into each SPAN desired.

There are some CSS styles that will work on newer browsers to control the way the browser handles line wrapping, but it still won't give you the exact control you're looking for in this situation.

On the other hand, if your goal isn't so much to control specific line breaks, but to make sure your text block 'stacks' in relatively even rows, I'd setting the width of the DIV differently for each viewport. It won't be perfect, but likely pretty close and might be the best compromise.

1
4
+25

There's a jquery plugin for that, Balance Text.

It's an Adobe-made plugin created alongside of Adobe's proposal to get a CSS option text-wrap: balance; that would just do this like Adobe InDesign's Balance Ragged Lines feature (sounds great, but even if it is accepted, it'll be years before browsers support it).

The plugin, however, works right now. It balances any elements that have the class balance-text, or on using jQuery like $('.some-elements').balanceText();

Limitations

This code currently only works on text in block-level tags with no inline elements.

In demo 4 you'll see how anything within your block of balanced text like an <a> link, <span>s or emphasis like <em>, <strong>, <b>, <i> etc gets removed.

Also, comparing demos 1, 2 and 5, you'll see you seem to need to use both the CSS class and the jQuery call.


It seems moderately reliable but sometimes glitchy - at time of writing, it occasionally slips up when it's in a side column, leaving lone orphans (but it seems to work 95%+ of the time and I've not yet seen it slip up except when in a side column), and for unexplained reasons, my demos don't work on Firefox but Adobe's demos do (fine in IE9+, can't test in IE8 right now). If you use it, factor in some testing time.

3
  • No idea, but the GitHub page includes a description of how it works. Sounds like it just uses the DOM searching and basic manipulation stuff, so you might be able to get away with just using Sizzle (the selector bit of jQuery) then patching up the element manipulation stuff as necessary. But that could easily spiral into a LOT of work... Dec 29, 2014 at 14:44
  • I'd imagine that's the "algorithim" described at the start of the readme file. Basically, they're just saying they used jQuery for easier cross-browser compatibility. Dec 29, 2014 at 16:00
  • @DumbNic If you're worried about the size of jQuery, you could try using Zepto.js, but I'm not 100% certain it works with this plugin natively. I don't think there's a vanilla js version available (though it's possible to make one) Dec 29, 2014 at 20:15
3

You can use JavaScript to detect the screen width and write the correct version (with < br>'s as you have them in your post) into an empty div via innerHTML.

Unfortunately, "desired web breaks" and "best web practices" don't go together. Let go of your perfectionist desire to get every word in the right place -- there are just too many screen possibilities and too many readers who don't have the designer mindset you have to even care about line breaks in their titles. Look up Responsive Web Design to get a better understanding of these issues.

3
  • 1
    This is very hard to do responsively and requires a lot of calculation. I don't recommend using this approach Dec 25, 2014 at 16:58
  • The question seems to have changed. I gave the answer to the question he gave at the time, which was to display the line breaks where he wanted them.
    – Steve
    Dec 26, 2014 at 18:38
  • I was addressing the "desired line breaks." I gave him a theoretical JS implementation to get what he wants. My second para tells my position, though, and I'm against that approach. RWD is the way to go, and that's what I use in my apps.
    – Steve
    Dec 26, 2014 at 23:56
3

I have to deal with this somewhat regularly, with input from designers wanting things to break a certain way. I've found the most straightforward way to do this is to put a span with a class inside the text, and then have that span be display: block; for the media queries.

So it would look something like this:

<p>This is some text and I want <span class="mobile-only-line-break">only this text to break, but only on mobile</span></p>

Then I would have CSS with something like this:

@media all and (max-width: 767px) {
.mobile-only-line-break { 
display: block;
}
}

You still have to go through and finesse it to make sure things break the way you want for all widths.

If it's a frequent issue, you could create your own set of line-break classes a la Twitter Bootstrap or whatever grid system you're using, modeling the class names after whatever naming convention you're using.

2

My current method...

<h1>Our New thingamabob is the best thing since sliced bread!</h1>

And the CSS:

@media only screen 
and (min-device-width : 320px) 
and (max-device-width : 480px) {
   h1 { margin: 0 auto; text-align: center; width: 280px; }
}

@media only screen 
and (min-width : 321px) {
    h1 { margin: 0 auto; text-align: center; width: 280px; }
}


@media only screen 
and (max-width : 320px) {
    h1 { margin: 0 auto; text-align: center; width: 280px; }
}


@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) {
    h1 { margin: 0 auto; text-align: center; width: 550px; }
}


@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) 
and (orientation : landscape) {
    h1 { margin: 0 auto; text-align: center; width: 800px; }
}


@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) 
and (orientation : portrait) {
    h1 { margin: 0 auto; text-align: center; width: 550px; }
}


@media only screen 
and (min-width : 1224px) {
    h1 { margin: 0 auto; text-align: center; width: 800px; }
}

/* Large screens ----------- */
@media only screen 
and (min-width : 1824px) {
    h1 { margin: 0 auto; text-align: center; width: 1200px; }
}


@media
only screen and (-webkit-min-device-pixel-ratio : 1.5),
only screen and (min-device-pixel-ratio : 1.5) {
    h1 { margin: 0 auto; text-align: center; width: 280px; }
}

Widths sometimes need some adjustment based upon actual text being used, but this is the general scheme I use. Essentially reducing the width of the h1 tag so that the line breaks where I want it to break.

This does work, it just requires testing thoroughly to ensure breaks are occurring where desired. But, then thorough testing is needed in any event. So, it's not necessarily more work in that respect.

3
  • Note: you can apply margin: 0 auto; text-align: center; just once outside of a media query and it will apply to all of them Dec 26, 2014 at 18:51
  • 1
    Also, with something this specific to the content it'd likely be better to just use inner spans... All this CSS is a bit much and as soon as you change the font size or something similar it will all have to be changed accordingly Dec 26, 2014 at 18:53
  • Agreed. Font sizes are controlled more globally for all media sizes. This was just a sample of the markup.
    – Scott
    Dec 26, 2014 at 23:38
1

This is now supported in CSS! Two new options on text-wrap were added in 2023:

  • text-wrap: balance to wrap lines at around the same length
    • browser rollout started in May 2023
    • see current browser support: caniuse
    • it should only be used for short text e.g. headings:

      Because counting characters and balancing them across multiple lines is computationally expensive, this value is only supported for blocks of text spanning a limited number of lines (six for Chromium and ten for Firefox).

      https://developer.mozilla.org/en-US/docs/Web/CSS/text-wrap#balance

  • text-wrap: pretty to reduce lone "orphan" words or words sticking out
    • browser rollout started in September 2023
    • see current browser support: caniuse
    • it's good for body text, but not for very text-heavy performance-sensitive pages:

      ...the user agent will use a slower algorithm that favors better layout over speed. This is intended for body copy where good typography is favored over performance (for example, when the number of orphans should be kept to a minimum)

      https://developer.mozilla.org/en-US/docs/Web/CSS/text-wrap#pretty

Chrome's 2023 summary blog includes a live demo:

1
  • Wow. Thanks for responding to a very old question! :)
    – Scott
    Jan 10 at 15:16
1

You could add white-space: nowrap and place <wbr> at the places where you'd like to allow line breaks. If this is not enough and you want fine control with media queries you can still add classes like <wbr class="mobileOnly">

<wbr> doc: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.