6

How can I keep the <a> tag underline running from left to right without any breaks when there are <span> tags inside, and with left/right padding or margin set? It would also be helpful to know why that happens?

I can probably use box shadow or border bottom instead, but I'm not looking for those solutions.

span {
  padding-right: 10px;
}
<a href="#">
  <span>&lt;</span>
  <span>Previous page</span>
</a>
Stickers
  • 75,527
  • 23
  • 147
  • 186

3 Answers3

5

In your case padding will add 10px space between both text so we can instead use letter-spacing with the first span to create this space.

If you refer to the specification you can read:

Underlines, overlines, and line-throughs are applied only to text (including white space, letter spacing, and word spacing): margins, borders, and padding are skipped

span:first-child {
  letter-spacing: 10px;
}
<a href="#">
  <span>&lt;</span>
  <span>Previous page</span>
</a>

To make this more generic we can consider letter-spacing with pseudo-element to simulate space between span:

By the way don't forget to consider white space [as mentionned above] that is already present in some cases.

.first span:after {
  content:" ";
  letter-spacing: 15px;
}

.second span:after {
  content:" ";
  letter-spacing: 30px;
}

span:last-child::after {
  display:none;  /* no need for last child*/
}
<a href="#">
  <span>aa</span>
  <span>bb</span>
  <span>cc</span>
</a>
<br>
<a href="#"><span>aa</span><span>bb</span><span>cc</span></a>
<br>
<a href="#" class="first">
  <span>aa</span>
  <span>bb</span>
  <span>cc</span>
</a>
<br>
<a href="#" class="first"><span>aa</span><span>bb</span><span>cc</span></a>
<br>
<a href="#" class="second">
  <span>aa</span>
  <span>bb</span>
  <span>cc</span>
</a>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • That is a smart approach, and it works. I hope I can also find out why for the original question. – Stickers Jan 31 '18 at 19:30
  • @Stickers because letter spacing increase the width of the letter and thus each letter will have more space ;) and text-underline consider the space of the whole letter ... i also added a more generic solution – Temani Afif Jan 31 '18 at 19:32
  • @Stickers here is another question for more information https://stackoverflow.com/questions/4015263/css-text-underlining-too-long-when-letter-spacing-is-applied – Temani Afif Jan 31 '18 at 19:40
0

For anybody running across this problem in 2023 (like me), I have some good news to share.

Currently, as mentioned by Temani back in 2018, the behavior of underlines is defined in CSS 2.1:

Underlines, overlines, and line-throughs are applied only to text (including white space, letter spacing, and word spacing): margins, borders, and padding are skipped. User agents must not render these text decorations on content that is not text. For example, images and inline blocks must not be underlined.

However, the CSS Text Decoration Module, level 3, says the following (emphasis my own):

Note that CSS 2.1 required skipping margins, borders, and padding always. In this level, by default only the margins, borders, and padding of the decorating box are skipped. In the future CSS2.1 may be updated to match this new default. Also, control over decorating leading/trailing spaces is expected in Level 4, and will be applied by default to the HTML <ins> and <del> elements.

What this means is that any descendants of a decorated box will have their entire margin box decorated over, unless specified otherwise using the text-decoration-skip-* properties, defined in level 4.

Therefore, one new possible answer to this question is to simply wait until Text Decoration level 3 is becomes standard (or at least until it's implemented by browser vendors). It's currently a Candidate Recommendation Draft, which browsers may implement, but needs to become a Recommendation before it's officially considered a "standard."

As far as when that will be, I have no idea—but I feel like it's worth mentioning.

matthew-e-brown
  • 2,837
  • 1
  • 10
  • 29
-3

Removing the padding and inserting a space would be an option.

<a href="#">
  <span>&lt; </span>
  <span>Previous page</span>
</a>
Aaron Stein
  • 526
  • 7
  • 18