Search code examples
csspseudo-elementtypographytext-decorations

Remove underline from ::first-letter


I'm trying underline all letters except the first. I attempted to remove the underline from the first letter via ::first-letter without success. Why doesn't that work here?

<a class="sample underline letter-underline-none"
   href="https://twitter.com/ryanve"
>@ryanve</a>

How can I remove the underline without changing this markup? I made a codepen with this CSS.

.letter-underline::first-letter,
.underline {
  text-decoration: underline;
}

.letter-underline-none::first-letter,
.underline-none {
  text-decoration: none;
}

.sample {
  display: block;
}

Solution

  • From https://developer.mozilla.org/en-US/docs/Web/CSS/text-decoration:

    Text decorations are drawn across descendant text elements. This means that if an element specifies a text decoration, then a child element can't remove the decoration.

    (emphasis mine). Of course, in your case you don't have a true child element (merely a first-letter pseudo-element), but the same logic applies.

    That said, some experimentation suggests a child element can add its own underline (covering up the ancestor's), and then specify the color of that underline using the text-decoration-color. So you could potentially hack together your desired visual effect, in most cases, by writing something like

    .letter-underline-none::first-letter {
      text-decoration: underline;
      text-decoration-color: #FFF;
    }
    

    (adjusting the #FFF part to match the intended background color). I don't think I'd recommend that, though — it seems too likely to have weird edge cases that look worse than the all-underline effect to begin with.