JSFiddle - React, Tailwind, and code Playground
by Chris Ball
HTML
<ul class="nav-list">
<li><a href="#"><span>Link One</span></a></li>
<li><a href="#"><span>Bit of a Longer Link</span></a></li>
<li><a href="#"><span>Extraordinary Verboseness Inherent in a Text</span></a></li>
<li><a href="#"><span>Something</span></a></li>
<li><a href="#"><span>Blah Fucking Blah</span></a></li>
</ul>
SCSS
ul {
font-size: 13px;
float: right;
font-family: monospace;
list-style-type: none;
text-align: right;
}
li {
max-width: 15em;
max-width: 15ch;
padding: 1em;
}
a {
display: block;
max-width: 15em;
max-width: 15ch;
text-decoration: none;
&:hover span:after {
transform: scaleX(1);
}
}
span{
display: inline-block;
position: relative;
&:after {
background: yellow;
bottom: 0;
content: '';
display: block;
left: 0;
position: absolute;
right: 0;
top: 50%;
transform: scaleX(0);
transition: transform 500ms;
transform-origin: bottom left;
z-index: -1;
}
}
JavaScript
var list = $('.nav-list').eq(0);
var addSpans = function( string, limit ){
// Split string into component words and spaces
// Init the current string length, contents and array container
var splitString = string[0].innerText.split(/(\s+)/),
currentLength = 0,
currentString = '',
stringArray = [];
for( var i = 0; i < splitString.length; i++ ){
currentLength += splitString[i].length;
// Remove leading whitespace
if( currentString === ' ' ){
currentString = '';
}
// When the limit is exceeded
// And it's a single word, push it straight in
// Or if it's a collection, add current iteration and push
// THen reset
if( currentLength > limit ){
if( currentString === '' ){
stringArray.push( splitString[i] );
} else {
currentString += splitString[i];
stringArray.push( currentString );
}
currentLength = 0;
currentString = '';
// If uder the limit, continue adding
} else {
currentString += splitString[i];
if( i == splitString.length - 1 ){
stringArray.push( currentString );
}
}
}
var output = '<span>' + stringArray.join('</span><span>') + '</span>';
return output;
}
var setLinkSpans = function(){
// Setup constants
var li = list.find('li:first'),
maxWidth = parseInt( li.css('max-width') ),
fontSize = parseInt( li.css('font-size') ),
maxWidthInEms = ( maxWidth / fontSize );
list.find('a').each(function(){
var $this = $(this),
linkLength = $this.text().length;
if( linkLength > maxWidthInEms ){
$this.html( addSpans( $this, maxWidthInEms ) );
}
});
}
setLinkSpans();