How can I prevent a line break at an SVG icon?

92 Views Asked by At

In an HTML document, suppose I have something like a link that starts after another non-whitespace character, e.g.

p {
  max-width: 140px;
}
<p>This is some text that includes a link (<a href="https://example.com">example</a>)</p>

If the viewport width is such that the line has to break in the middle of the first word of the link text, then the preceding character (the opening parenthesis, in this case) "sticks" to the link, i.e. the standard layout algorithm breaks the line at the closest preceding whitespace.

However, if I want to insert an SVG icon at the start of the a element:

p {
  max-width: 140px;
}
<p>This is some text that includes a link (<a href="https://example.com"><svg style="height: 1em; color: green;" viewbox="0 0 10 10" fill="currentColor"><circle cx="5" cy="5" r="5" /></svg>example</a>)</p>

Then the line is now allowed to break either side of the SVG.

Question

Is there any way to make the layout engine treat the svg the same as it would normal text characters, so that the open parenthesis still "sticks" to the link text?

I can't make the whole paragraph or the whole link white-space: nowrap - I want the text to be able to wrap normally both within and outside the link, I just need it not to break around the <svg> (unless the link as a whole is preceded by whitespace). Basically I want to be able to insert an icon at the start of the link without interfering with the normal text layout behaviour, as if the icon were just another character with all the same Unicode properties as the first character of the existing link text.

Is this possible?

4

There are 4 best solutions below

2
Lucas Tesseron On BEST ANSWER

You could try to simulate characters for your SVG using pure CSS (the ::first-letter pseudo-element can be an option).

But I think you won't achieve the exact behavior of a standard character.

Tanishq's response works, but for example, if the parenthesis were before the image as it was in your initial example, not after, the parenthesis and the image would be separated onto different lines.

If you truly want character-like behavior, personally, I would turn to a Dingbat typography.

You can certainly create your own Dingbat typography to embed a set of SVG icons and use them as you wish in the characters flow (it's the same principle as Google Material Icon).

For example, Fontello website allows you to create your own typography in a few clicks.

1
Tanishq S On

I've got a solution for you which required 2 basic changes

  1. Convert the SVG to a .svg image URL.
  2. Add a ::before to the anchor tag and add the SVG to its content

Example:

p {
  max-width: 140px;
}

a {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.a::before {
  content: url('https://img.cdn4dd.com/s/media/photosV2/1954ba82-d91f-43a2-8838-767fd2ad386f-retina-large.svg');
  display: block;
  width: auto;
  height: auto;
}
<p>
  This is some text that includes a link

  <a class="a" href="https://example.com">
    <span>
      &#40;example&#41;
    </span>
  </a>
</p>

1
Danny '365CSI' Engelman On

I don't 100% understand what you are after.

<nobr> can keep content together:

p {
  width: 140px;
  background: #eee;
}
<p>This is some text that includes a link 
  <nobr>(
    <a href="https://example.com">
      <svg style="height: 1em; color: green;" viewbox="0 0 10 10" fill="currentColor"><circle cx="5" cy="5" r="5" /></svg>example example example example example 
    </nobr>
  </a>)</p>

1
Stickers On

I guess your best bet is to add the svg icon as a background image.

p {
  width: 140px;
  resize: both;
  overflow: auto;
  outline: 1px solid;
}

a {
  background: url("data:image/svg+xml,%3Csvg viewBox='0 0 10 10' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='5' cy='5' r='5' fill='green' /%3E%3C/svg%3E%0A") 0 0 / contain no-repeat;
  padding-left: 1.25em;
}
<p>This is some text that includes a link (<a href="https://example.com">example</a>)</p>