I think I've come across the same problem. I've found a decision, using js. It works from ie11 (I didn't test below).
The main thing is to get width of every line.
Codepen
Pug:
.container
.text Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi exercitationem quos, facere ipsum perspiciatis labore dolores, quibusdam, culpa numquam deleniti nihil ad. Tempore beatae nobis facere deserunt nam dicta earum.
br
br
div.test
SCSS:
.text {
display: inline-block;
line-height: 1.2;
}
.container {
position: relative;
}
.line {
position: absolute;
width: 0;
height: 2px;
background: red;
transition: width .5s;
}
.container:hover line {
left: 0;
right: auto;
}
JS:
function multilineTextUnderline() {
var text = document.querySelector('.text');
var words = text.innerText.split(' ');
var div = document.querySelector('.test');
var initialText = text.innerText;
var widths = [];
var lineHeight = parseInt($(text).css('line-height'), 10);
var firstWord = 0;
text.innerText = words[0];
var currentHeight = text.offsetHeight;
$('.test span').remove();
$('.test br').remove();
function getWidths() {
words.forEach(function(word, i) {
text.innerText = words.slice(firstWord, i + 1).join(' ');
if(currentHeight < text.offsetHeight) {
text.innerText = words.slice(firstWord, i).join(' ');
widths.push(text.offsetWidth);
firstWord = i;
var newSpan = document.createElement('span');
newSpan.innerText = text.innerText;
div.appendChild(newSpan);
div.appendChild(document.createElement('br'));
if(i === words.length - 1) {
text.innerText = words[i];
widths.push(text.offsetWidth);
var newSpan = document.createElement('span');
newSpan.innerText = text.innerText;
div.appendChild(newSpan);
div.appendChild(document.createElement('br'));
}
} else if(i === words.length - 1) {
widths.push(text.offsetWidth);
var newSpan = document.createElement('span');
newSpan.innerText = words.slice(firstWord).join(' ');
div.appendChild(newSpan);
div.appendChild(document.createElement('br'));
}
});
}
getWidths();
text.innerText = initialText;
console.log(' widhts: ', widths);
var controlWidths = [];
[].forEach.call(document.querySelectorAll('.test span'), function(span) {
controlWidths.push(span.offsetWidth);
});
console.log('control widths: ', controlWidths);
//rendering underlines
var container = document.querySelector('.container');
var containerWidth = container.offsetWidth;
var lines = [];
$('.line').remove();
widths.forEach(function(lineWidth, i) {
var line = document.createElement('div');
line.classList.add('line');
line.style.top = lineHeight * (i + 1) - 2 + 'px';
lines.push(line);
});
lines.forEach(function(line) {
container.appendChild(line);
});
container.addEventListener('mouseenter', function() {
lines.forEach(function(line, i) {
line.style.width = widths[i] + 'px';
line.style.left = 0;
line.style.right = 'auto';
});
});
container.addEventListener('mouseleave', function() {
lines.forEach(function(line, i) {
line.style.width = 0;
line.style.left = 'auto';
line.style.right = containerWidth - widths[i] + 'px';
});
});
}
multilineTextUnderline();
window.addEventListener('resize', function() {
multilineTextUnderline();
});