azangru
azangru

Reputation: 2748

Prevent line break between last word of an element and another element

Given an inline (or inline-block) element with text of variable length, and another element to the right of the first one that acts as a kind of badge, is there a way to prevent a line break between the last word of the first element and the second element? Both elements occupying the same line is fine; a line break occurring in the text of the first element is also fine; but a line break between the two elements is undesirable. Here is an illustration explaining what I mean.

line break diagram

Is there a way to do this? I tried to have the two elements as spans and put a non-breaking space between them, but that didn't work.

UPDATE: Here's a quick and dirty Codepen example: http://codepen.io/anon/pen/LkzBQJ

html:

<h1>
  <span class="title-text">
    This is some text
  </span><span class="badge">yo!</span>
</h1>
<h1>
  <span class="title-text">
    This is some broken text
  </span><span class="badge">yo!</span>
</h1>

css:

h1 {
  width: 350px;
}

.badge {
  color: #f6511d;
  display: inline-block;
  border: 1px solid #f6511d;
  border-radius: 3px;
  font-size: 0.8em;
  padding: 0.1em 0.2em;
  line-height: 0.97em;
  margin-left: 0.4em;
  vertical-align: 1px;
}

UPDATE2: In my particular case, both the text in the first element, and the badge have to be rendered dynamically, using JavaScript. So Ricardo’s solution below (wrap the last word of the text and the badge in a span with white-space: nowrap), although working, will not be very easy to implement.

Upvotes: 9

Views: 6815

Answers (5)

Bramus
Bramus

Reputation: 2088

You can do this with modern CSS, by declaring text-wrap: pretty. See the answer at https://stackoverflow.com/a/76701845/2076595.

(Yes, this question is a duplicate but I don’t have enough points to cast any “this is a duplicate question” vote)

Upvotes: 2

ak0000
ak0000

Reputation: 167

You can add padding to the text and a negative margin:

<h1>
  <span class="title-text" style="padding-right: 15px;">
    This is some text
  </span><span class="badge" style="margin-left: -15px;">yo!</span>
</h1>
<h1>
  <span class="title-text" style="padding-right: 15px;">
    This is some broken text
  </span><span class="badge" style="margin-left: -15px;">yo!</span>
</h1>

This works for even dynamically generated content, unlike having to make a tag around the last word of the text and the image.

(Based on an answer I saw here: https://stackoverflow.com/a/25857961/5899236)

Upvotes: 1

lhermann
lhermann

Reputation: 490

This problem is called a widow in typesetting. There are 3 ways to fix this.

Use the widows css property

Only break the last two words together.

<h1 style="widows: 2;">
  <span>This is some broken text</span>
  <span class="badge">yo!</span>
</h1>

Caveat: Not supported by Firefox (https://caniuse.com/?search=widows) and seems to only work properly with page breaks and column breaks

Use a &nbsp; character

Add a "physical" non-breaking space character, and only that character, between the last word and the badge.

<h1 style="widows: 2;">
  This is some broken text&nbsp;<span class="badge">yo!</span>
</h1>

If you have to do this with multi-line code, you can use HTML comments to avoid breaking spaces.

<h1 style="widows: 2;">
  This is some broken text<!--
  -->&nbsp;<span class="badge">yo!</span>
</h1>

Caveat: It's ugly

Wrap the last word and the badge in a white-space: nowrap span.

<h1 style="widows: 2;">
  This is some broken <span style="white-space: nowrap;">text <span class="badge">yo!</span></span>
</h1>

Caveat: Not always possible if you are dealing with dynamically generated code

Upvotes: 1

Giorgos Lemonidis
Giorgos Lemonidis

Reputation: 61

Check this! This line <h1>This is some text</h1><span class="badge">yo!</span> must be in one line to work.

https://codepen.io/lemonjelly/pen/rNNvLGE

Upvotes: 5

Ricky Ruiz
Ricky Ruiz

Reputation: 26791

SOLUTION:

The solution I could come up with is creating some sort of fix, wrapping text with the badge in a span and using the css property white-space: nowrap;.


JSFiddle


CODE SNIPPET:

.row {
  display: flex;
  counter-reset: paragraph;
}
.col {
  width: 50%;
  padding: 1em;
}
.col--left {
  background-color: #011627;
  padding-right: 0;
}
.col--right {
  background-color: #F71735;
  border-left: 2px dotted #ddd;
}
.col p {
  color: #fff;
}
.col p::before {
  counter-increment: paragraph;
  content: counter(paragraph)". ";
}
.badge-fix {
  display: inline-block;
  white-space: nowrap;
}
.badge {
  display: inline-block;
  padding: .2em .6em .3em;
  font-size: 75%;
  font-weight: 700;
  line-height: 1;
  color: #fff;
  text-align: center;
  white-space: nowrap;
  vertical-align: baseline;
  border-radius: .25em;
}
.badge--royalblue {
  background-color: royalblue;
}
.badge--tomato {
  background-color: tomato;
}
.badge--crimson {
  background-color: crimson;
}
<div class="row">
  <div class="col col--left">
    <p>
      This is <span class="badge-fix">some text
      <span class="badge badge--royalblue">badge</span></span>
    </p>
    <p>
      This is some <span class="badge-fix">reasonably long
      <span class="badge badge--tomato">badge</span></span>
    </p>
    <p>
      This is some <span class="badge-fix">longish text
      <span class="badge badge--crimson">badge</span></span>
    </p>
  </div>
  <div class="col col--right">

  </div>
</div>

Upvotes: 1

Related Questions