Aiwatko
Aiwatko

Reputation: 495

No line break between text and SVG

I have a short text that is followed by an SVG in a limited-width container. The expected behaviour is that the text breaks if it's longer than the container width BUT I would like it NOT to break right between the text and the svg:

Current result:
Current result:

Expected result:
enter image description here

Adding a <nobr> or a <span>tag in the middle of the text (before blue) and closing it after the SVG is not an option as the text comes from an external database and cannot be edited.

<span class="text">
    Jack Wolfskin Jacke Colorado Flex - Midnight Blue
</span>
<span class="svg">
    <svg>
    ....
    </svg>
</span>

Upvotes: 23

Views: 10034

Answers (7)

Yozi
Yozi

Reputation: 12755

I combined solutions from the answers above to create this CSS class. It uses a zero-width space instead of a non-breaking one, which is added using CSS. As a result, the HTML looks cleaner and more predictable, without visible extra space.

CSS

.tail-icon {
  white-space: nowrap;
}
.tail-icon::before {
  content: "\200B";
}

HTML

<div>
  Lorem ipsum dolor sit<span class="tail-icon"><svg></svg></span>
</div>

Example: https://codepen.io/yozi-developer/pen/KKbWmqR

Upvotes: 6

Peter
Peter

Reputation: 3008

This is the solution I have been using:

svg {
  height: 1em;
  width: 1em;
  margin-left: -1em;
}
<div>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  Quisque eros mi, accumsan quis egestas vitae, auctor eu
  metus. Donec aliquet dolor elementum mauris
  tincidunt.&nbsp;&nbsp;&nbsp;&nbsp;<svg viewBox="0 0 24 24">
    <path fill="none" stroke=currentColor d="M20 20l-7 -7a5 5 0 1 1 .1 -.1" class=""></path>
  </svg>
</div>

A few remarks though:

  • The negative margin-left in the CSS equals the width of the icon.
  • The amount of distance between text and icon is controlled by the number of &nbsp; used. So this distance is not controlled from CSS.
  • It is vital that there is no whitespace (no newlines) between the last word, each of the &nbsp;s, and the opening <svg> tag.

Upvotes: 0

radarfox
radarfox

Reputation: 129

You can prevent the line breaking with this markup. It doesn't need to include the last word, so you can use it even with a generated content.

JSX

<div>
  {children}
  <span className="tail">
      {'\u00a0'}
      <svg></svg>
  </span>
</div>

HTML

<div>
  Lorem ipsum dolor sit<span class="tail">&nbsp;<svg></svg></span>
</div>

CSS

.tail {
  white-space: nowrap;  
}

https://jsfiddle.net/radarfox/65h40jt7/

Upvotes: 10

ak0000
ak0000

Reputation: 167

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

<span class="text" style="padding-right: 15px;">
    Jack Wolfskin Jacke Colorado Flex - Midnight Blue
</span>
<span class="svg" style="margin-left: -15px;">
    <svg>
    ....
    </svg>
</span>

That way, if there isn't room for the padding, the last word will get pushed to the next line also.

(This is based on this answer: https://stackoverflow.com/a/25857961/5899236)

Upvotes: 0

Jay
Jay

Reputation: 303

You can define position: absolute on the SVG, with auto for top, right, etc.

https://codepen.io/jsit/pen/xxOQoVW

The only side-effect is this will allow the SVG to appear outside of the containing box; this is in a sense the reason it works at all.

enter image description here

Upvotes: 0

Maciej Dudziński
Maciej Dudziński

Reputation: 406

The only solution I found required a nasty change in the origin HTML.

To make sure the icon is never alone in the new line I wrapped the last word and the icon in a new element with white-space: no-wrap;, plus if we want it to still split if the line cannot accommodate last word with the icon we can make this new container inline flex and flex-wrappable.

<div>
  Lorem ipsum dolor sit
  <span class="last_word">
      very_long_last_word
      <svg>...</svg>
  </span>
</div>

.last_word {
  /* Stick icon to last word */
  white-space: no-wrap;  
  
  /* Make sure last word and icon will break ultimately */
  display: inline-flex;
  flex-wrap: wrap; 
}

Live example: https://jsfiddle.net/uerzo6sa/

Upvotes: 4

Sergey Sklyar
Sergey Sklyar

Reputation: 1970

add display-block to svg container:

.svg {
  display: inline-block;
}

Upvotes: 2

Related Questions