Adding a line break between two inline elements
If you need to have two inline elements where one breaks into the next line within another element, you can accomplish this by adding a pseudo-element :after</code> with content:'\A'</code> and white-space: pre</code>
HTML
<h3>
<span class="label">This is the main label</span>
<span class="secondary-label">secondary label</span>
</h3>
CSS
.label:after {
content: '\A';
white-space: pre;
}
Codepen: http://bit.ly/YdBPKo
Support: http://reference.sitepoint.com/css/white-space
Written by Rodrigo Martinez
Related protips
17 Responses
Nice... I can see this being very useful in responsive website, where the way items in a footer, for example, break funny at different widths. Sometimes, you want to force a line-break, but dont want to use javascript to inject a <br> (or similar) into the DOM or include a <br> that you end up hiding with display: none most of the time.
What does the \A reference or do? Not familiar with this CSS syntax...
Is it specific to the pseudo selectors and content: ""; ?
Great tip though!
@mattquirk \A
is a linebreak character (hexadecimal code A
, or 10
in decimal)
@pe1999 To your point, there also a win when keeping RWD in consideration. Not having to add extra elements to show/hide for different screen sizes aids on page performance since you avoid unnecessary DOM elements added to the document.
@mattquirk Thanks! and thanks @dpashkevich for replying. It's important to note that other values of white-space</code> like pre-wrap</code> and pre-line</code> will yield a similar effect since they all handle \a</code> characters the same way.
I just had another thought - would it be problematic if you just changed display: inline
to display: block;
instead of the suggested way? Of course you'd need to check your margins to preserve the same visual line height.
@dpashkevich That's a valid point. I don't think it will make a difference in this case. The main point of doing it this way is to not have to change the default display value of an inline element. In the example posted above I am placing the elements inside a block level element but you could very well do it inside another inline element.
You semantics are wrong, so this approach is invalid. You have 2 headings, so they should be different heading tags.
<hgroup>
<h2>This is the main label</h2>
<h3>Secondary label</h3>
</hgroup>
Actually, @milesj, the W3C dropped the hgroup
tag, so you'd just wrap the headings in a header
. But there's a couple things about this that make me raise my eyebrow a little.
1) In your use-case example, the markup is off. Those labels really ought to be li
s in an ul
for the purposes of semantics. Default UA styles for a ul
are exactly what you're aiming for here, in the end.
2) In a use-case situation where (1) doesn't apply*, why use pseudo-elements + content
when display:block
applied to that span
would suffice? I see that you don't want to change the display
property, but in trying to avoid something that (which confuses me further--there's no inherent problem with changing the display
property), you add extra code. I mean, we could be talking mere bytes in this case, but still.
*The only use-case I could come up with is a situation where you want a heading to break a line for design purposes. span
is correct in this case because it has no semantic value and will degrade elegantly.
@milesj Your code is wrong and invalid. You closed an h3</code> with an h2</code>.
Even though the W3 has dropped hgroup</code> from the spec, no one can be certain what will happen to that tag going forward. It is possible that it will come back but with a new specification.
Now, whether the content should be marked up differently is and should be determined by the content itself. I don't agree that these should be broken up into separate headers or that they ought to be li</code>s in a ul</code>. And no, I was not aiming for default ul</code> styles. Otherwise I would have done exactly that.
There are multiple use cases this can apply to. I had to do this on a header that was made up of an icon (floated left), a label (which was a countdown) and a secondary label (which was a message that came right after the countdown) hence the example above. And while I agree with the comments that there are different ways of accomplishing this type of display, this specific solution works well if you can not (or do not want to) change the default display</code> value of an element. And yes, you are right @vfalconi on guessing that this is for design purposes only because that was exactly the case for the project I had to do this on.
@vfalconi @napotopia - It may be deprecated, but splitting the text into two heading tags is still the correct approach.
@milesj -- I agree, I meant you'd use a header
element to wrap the two headings rather than an hgroup
.
@napotopia -- Maybe I'm just misunderstanding by what you're calling "labels." Generally, when people refer to "labels" I see a form of taxonomy for some kind of content. Ex: Gmail tags or whatever they're called.
@vfalconi I called the text node a label but I see how that leads to confusion. I'm not trying to achieve any new behavior for a label</code> tag, however. If that piece of text is confusing replace it with anything that can make sense. Here's another example:
<h3>
<span class="main-title-portion">There are few scenarios where these two lines</span>
<span class="secondary-title-portion">should be broken up into 2.</span>
</h3>
Essentially, this is the same thing as my initial example. Because of design requirements I needed to create a line break on an inline element. And maybe I didn't go the display:block</code> route because I would only apply that rule for a specific screen size and drop it on bigger screen sizes. Or maybe that would create issues if I was trying to float an element. There are most likely other reasons one might need to do something like this.
I'm not able to get this trick to work with <li/>, is there a work-around for lists?
@mikezarandona Are you setting the display</code> property to something other than block</code> (for ul</code>s) or list-item</code> for li</code>s
This is a nice trick, but it doesn't work with display:inline-block elements. Do you know of any alternatives? (I also don't want to float them)
If you are building a responsive website then