Ethan C
Ethan C

Reputation: 1508

Force no line-break on pseudo element (:after)

http://codepen.io/ethanclevenger91/pen/vNjOyP

EDIT: This CodePen now showcases the variety of proposed solutions

If you resize the available space in this pen, you'll see that in the top heading, you eventually reach a point where the diamond (created via a pseudo-element) will line-break, but the last word does not, so the pseudo-element is on its own line.

I'd like to fashion a solution using pure CSS that behaves like the second heading, where the last word breaks if the pseudo-element breaks. Currently I've implemented it via Javascript, as the content of the headings will come from a database.

HTML:

<div class="container">
<h1 class="alpha">A heading that takes up nearly the entire width</h1>
<h1 class="alpha solution1">A solution that would require Javascript</h1>
</div>

SCSS:

$brand-primary:lightblue;
$brand-secondary:darken(lightblue, 40%);
@mixin hidpi($ratio) {
  @media (-webkit-min-device-pixel-ratio: $ratio), (min-resolution: #{round($ratio*96)}dpi) {
      @content;
  }
}
body {
  position:relative;
  height:100vh;
  background:$brand-primary;
  width:100%;
}
.container {
  top:50%;
  transform:translateY(-50%);
  position:relative;
}
.alpha {
  text-align:center;
  color:$brand-secondary;
  &:not(.solution1) {
    &:after {
      content:'';
      @extend %diamond;
      margin-left:11px;
    }
  }
  &.solution1 {
    .diamond {
      @extend %diamond;
      margin-left:11px;
    }
  }
}
%diamond {
  width:13px;
  height:14px;
  display:inline-block;
  transform:rotate(-45deg);
  border:1px solid $brand-secondary;
  vertical-align:middle;
  @include hidpi(2) {
    height:13px;
  }
}

JS:

jQuery(document).ready(function($) {
  var content = $('.solution1').html();
  var lastChar = content.slice(-1);
  $('.solution1').html(content.slice(0, -1)+'<span style="white-space:nowrap">'+lastChar+'<span class="diamond"></span></span>');
});

Upvotes: 4

Views: 4511

Answers (2)

Luizgrs
Luizgrs

Reputation: 4873

You can also go with using the standard diamond from UTF8: .

If you let your :after as display: inline it will not break because you're not adding any space between the last word and it.

.alpha.solution3:after {
  display: inline;
  content: "◇";
  font-weight: normal;
  font-size: 1.2em;
}
<h1 class="alpha solution3">A solution that does not require Javascript neither a SPAN</h1>

If this character is too bold for you, you can make your own font, use font-face and go with it.

http://codepen.io/anon/pen/BoxjzO

This will also work on browsers which do not support transform.

Upvotes: 4

Oriol
Oriol

Reputation: 287980

You can try using white-space to prevent line breaks in the h1, and wrap the text in a span element where you restore the normal behavior.

h1 {
  white-space: nowrap;
}
h1 > span {
  white-space: normal;
}

Additionally, Chrome also needs

h1 > span::after {
  content: '';
  white-space: nowrap;
}

body {
  position: relative;
  height: 100vh;
  background: lightblue;
  width: 100%;
}
.container {
  top: 50%;
  -webkit-transform: translateY(-50%);
  -ms-transform: translateY(-50%);
  transform: translateY(-50%);
  position: relative;
}
.alpha {
  text-align: center;
  color: #2e7e99;
}
.alpha:after {
  content: '';
  width: 13px;
  height: 14px;
  display: inline-block;
  -webkit-transform: rotate(-45deg);
  -ms-transform: rotate(-45deg);
  transform: rotate(-45deg);
  border: 1px solid #2e7e99;
  vertical-align: middle;
  margin-left: 11px;
}
h1 {
  white-space: nowrap;
}
h1 > span {
  white-space: normal;
}
h1 > span::after {
  content: '';
  white-space: nowrap;
}
<div class="container">
  <div class="row">
    <div class="col-xs-12">
      <h1 class="alpha">
        <span>A heading with a decorative pseudo-element that breaks by itself</span>
      </h1>
    </div>
  </div>
</div>

Upvotes: 3

Related Questions