Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

prevent :after element from wrapping to next line

Tags:

css

I have this HTML:

<ul>
    <li class="completed"><a href="#">I want the icon to stay on the same line as this last <strong>word</strong></li>
</ul>

I'm appending an icon using the :after pseudo element:

ul li.completed a:after {
    background:transparent url(img.png) no-repeat; 
    content: '';
    display:inline-block;
    width: 24px;
    height: 16px;
}

The problem: if the available width is too small, the icon wraps to the next line. I would want it to stay on the same line as the last word of the link it's appended to:

enter image description here

Is this doable, without adding 'nowrap' to the entire link (I want the words to wrap, just not the icon).

See jsFiddle here.

like image 330
ptriek Avatar asked Apr 19 '13 09:04

ptriek


People also ask

How do you stop an element from going to the next line?

Inline elements behave in much the same way as text does. If you want to prevent them from wrapping, either remove the white space you have used for formatting, or add white-space:nowrap; to the rule for .

How do I stop text from going to the next line in CSS?

If you want to prevent the text from wrapping, you can apply white-space: nowrap; Notice in HTML code example at the top of this article, there are actually two line breaks, one before the line of text and one after, which allow the text to be on its own line (in the code).

How do I force HTML elements to stay on the same line?

You can force the content of the HTML <div> element stay on the same line by using a little CSS. Use the overflow property, as well as the white-space property set to “nowrap”.

How do you stop a line break in HTML?

There are several ways to prevent line breaks in content. Using &nbsp; is one way, and works fine between words, but using it between an empty element and some text does not have a well-defined effect. The same would apply to the more logical and more accessible approach where you use an image for an icon.


Video Answer


3 Answers

JSFiddle - http://jsfiddle.net/Bk38F/65/

Add a negative margin to the pseudo element, to compensate its width:

ul li.completed a:after {
    background:transparent url(img1.png) no-repeat; 
    content: ' ';
    display: inline-block;
    width: 24px;
    height: 16px;
    margin-right: -24px;
}

Now, that is going to make the icon overflow the container, and the line is going to break only when the text meet the end of the line. If you need to maintain the icon inside the original container width, you can add padding to compensate again:

ul li.completed a {
    display: inline-block;
    padding-right: 24px;
}

IMPORTANT UPDATE:

For this method to work, there must be no white space between the text and the closing tag of the element holding the pseudo element. Even though the pseudo element's width is compensated by a negative margin, the white space will make the line break when it meets the edge of the parent element. For example, this works:

<span>text goes here</span>

and this doesn't:

<span>
    text goes here
</span>
like image 105
Hugo Silva Avatar answered Oct 17 '22 11:10

Hugo Silva


you can add the image to the last word instead. that will make it break together.

add a class to word <strong class="test">word</strong>

and .test:after { ...

http://jsfiddle.net/52dkR/

the trick is also to make that class to be inline-block

and if you want to keep the underline see this.

http://jsfiddle.net/atcJJ/

add text-decoration:inherit;

like image 20
btevfik Avatar answered Oct 17 '22 12:10

btevfik


This is a little similar to a previous answer, but I thought that I'd flesh it out and explain it fully.

As soon as you set display: inline-block, :after becomes a non-text-binding element. This is why it wraps, and why nowrap has no effect. So leave display alone.

As it's a text element by default, the content binds to previous text, as long as there's no whitespace between them. So don't add any, but make sure you have content: "", or it's the same as display: none. The only problem is height and width are controlled by the content, which in this case is collapsed. So width is 0, and height is the line height.

Resize the area with padding; left or right, it doesn't matter. Add a little margin so the icon doesn't touch the text. Keep everything as relative sizes (em, pt, etc.), and use background-size: contain, so that the icon scales with the text, like an emoji or font. Finally position the icon where you want with background-position.

ul li.completed a:after {
  content: "";
  background: url('icon.svg');
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center center;
  margin-left: 0.2em; /* spacing*/
  padding-right: 0.75em; /* sizing */
}

I've used this for my external links (a[href*="://"]:after), and it's worked fine in Firefox, Chrome, and iOS. And since the icon remains a text element, even direct text after it binds, so any closing punctuation will wrap too.

like image 20
Phernost Avatar answered Oct 17 '22 13:10

Phernost