Will McLean
Process diary

Using trigonometry to create a diagonal strikethough style with js

Last modified: June 17, 2018
Created: June 14, 2018

I recently had to make a diagonal strikethrough style to use on single word throughout a site. I toyed with the idea of an absolute positioned div with a background svg over the top but decided that that would stretch the shape of the line. Instead I decided to create a div for the line and set the length of it and the angle of rotation using trigonometry. A much better way to do it and much more interesting to code.

To begin with we create the mark-up:

<p><span class="strike-through">words</span></p>

Then the css:

.strike-through {
    position: relative;
    .after {
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 2px;
        background-color: $highlight;
        transform-origin: top left;
    }
}

This will give us a span with an underline absolutely positioned at the bottom of the element like so:

We need to find out the hypotenuse of the triangle to use as the length of our strikethrough and the relevant angle to use as our angle of rotation.

Calculating the length of the line can be done using this formula:

hypotenuse = √ adjacent2 + opposite2

let el = document.querySelector( '.strike-through' ),
        after = document.querySelector( '.strike-through .after' ),
        adjancent = el.offsetWidth,
        opposite = el.offsetHeight,
        hypontenuse = Math.sqrt(adjancent * adjancent + opposite * opposite)

The angle of reotation can be calculated by using inverse trigonometry:

angle = arcsine( opposite / hypotenuse ).

We need to turn the radian returned by the js asin function into a degree as you can see below.

rotation = Math.asin( opposite / hypontenuse ) * ( 180 / Math.PI );

The full js and the result can be seen below.

let el = document.querySelector( '.strike-through' ),
        after = document.querySelector( '.strike-through .after' ),
        adjancent = el.offsetWidth,
        opposite = el.offsetHeight,
        hypontenuse = Math.sqrt(adjancent * adjancent + opposite * opposite),
        rotation = Math.asin( opposite / hypontenuse ) * ( 180 / Math.PI );

    after.style.width = hypontenuse + 'px';
    after.style.transform = `rotate(-${rotation}deg)`;

This is a Knowledge Base post.