<svg class="visuallyHidden">

  <!-- Base 0.0 to 1.0 values on the size of the bounding box.
       Essentially turn them into viewport units or percentages. -->
  <filter id="svg-underline" primitiveUnits="objectBoundingBox">
    
    <!-- Take the original image (the text) and expand it a little
         horizontally and a little more vertically. Then store it
         in a new layer. -->
    <feMorphology in="SourceGraphic" operator="dilate" radius="0.0075 0.05" result="outline"></feMorphology>
    
    <!-- Make a blue rectangle that’s 3% tall and 100% wide and expand it
         a little horizontally and a position it below the original text. -->
    <feFlood flood-color="blue" width="1" height="0.03" x="0" y="0.85" result="underline"></feFlood>
    
    <!-- Take the blue rectange and use the expanded text layer to mask
         out the parts we don’t want. This is where it skips descenders. -->
    <feComposite in="underline" in2="outline" operator="out" result="underline"></feComposite>
    
    <!-- Now stack the underline and the original text for export. -->
    <feMerge>
      <feMergeNode in="underline"></feMergeNode>
      <feMergeNode in="SourceGraphic"></feMergeNode>
    </feMerge>
  </filter>
</svg>

<p class="font-size-16px">
  <span class="underline">Tricky handgloves</span>
</p>

<p class="font-size-21px">
  <span class="underline">Tricky handgloves</span>
</p>

<p class="font-size-36px">
  <span class="underline">Tricky handgloves</span>
</p>

<p class="font-size-48px">
  <span class="underline">Tricky handgloves</span>
</p>

<p class="font-size-72px">
  <span class="underline">Tricky handgloves</span>
</p>
.underline {
  // Use the default underline for browsers that
  // don’t support @supports (<= IE11)
  text-decoration: underline;
  
  // Use the filter in browsers that support @supports, but aren’t Safari
  @supports not (-webkit-text-decoration-skip: objects) {
    filter: url('#svg-underline');
    text-decoration: none;
  }

  // And then disable the filter in Edge and
  // use the default underline instead
  @supports (-ms-ime-align: auto) {
    color: red;
    filter: none;
    text-decoration: underline;
  }
}

// Remove the SVG from the UI, but keep it the layout.
// This makes sure Firefox can reference the SVG filter.

.visuallyHidden {
  height: 1px;
  margin: -1px;
  overflow: hidden;
  width: 1px;
}

// ----- Unrelated ----- //
    
html {
  $square-color: #eee;
  $square-size: 8px;
  line-height: 1;
  padding: 20px;
  background-image:
    linear-gradient(45deg, $square-color 25%, transparent 25%, transparent 75%, $square-color 75%, $square-color), 
    linear-gradient(45deg, $square-color 25%, transparent 25%, transparent 75%, $square-color 75%, $square-color);
  background-position: 0 0, $square-size $square-size;
  background-size: ($square-size * 2) ($square-size * 2);
  font-family: 'Source Sans Pro', sans-serif;
}

body {
  margin-left: auto;
  margin-right: auto;
  max-width: 600px;
}

p {
  margin: 0;
  margin-bottom: 20px;
  
  &:last-child {
    margin-bottom: 0;
  }
}

@for $index from 1 through 100 {
  .font-size-#{ $index }px {
    font-size: #{ $index }px;
  }
}
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.