Lorem ipsum dolor sit amet.

function wrapWords" /> Lorem ipsum dolor sit amet.

function wrapWords" /> Lorem ipsum dolor sit amet.

function wrapWords"/>

Using JavaScript .join() results in misaligned vertical characters

43 Views Asked by At

I'm using the following code to wrap every word inside two span elements:

<p data-anim="wrap-words">Lorem ipsum dolor sit amet.</p>
function wrapWords() {
    const strings = document.querySelectorAll('[data-anim="wrap-words"]');
    
    for (let i = 0; i < strings.length; i++) {
        const string = strings[i];
        const words = string.textContent.split(' ');
        const wrappedWords = words.map(word => `<span><span>${word}</span></span>`);
        const wrappedString = wrappedWords.join(' ');
        
        string.innerHTML = wrappedString;
    }
} wrapWords();

I split by spaces and re-add these spaces again in the join statement. This causes the spaces to be misaligned vertically, which screws with the visual line-height.

Instead of joining with a ' ' I joined with an 'x' to visualize the problem better: Screenshot

Does anybody have an idea why this happens? I couldn't find anything about this error. CSS vertical-align does not seem to influence anything.

function wrapWords() {
    const strings = document.querySelectorAll('[data-anim="wrap-words"]');

    strings.forEach(string => {
        const words = string.textContent.split(' ');
        const wrappedWords = words.map(word => `<span><span>${word}</span></span>`);
        const wrappedString = wrappedWords.join('x');

        string.innerHTML = wrappedString;
    });
} wrapWords();
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
html {
    font-size: 16px;
    line-height: 1.375;
    color: #000;
    font-family: 'Arial', sans-serif;
}
.container {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    padding: 2vw;
}

/* paragraph */
.paragraph p {
    max-width: 20rem;
}

/* anim */
[data-anim="wrap-words"] > span {
    overflow: hidden;
    display: inline-block;
}
[data-anim="wrap-words"] span span {
    display: inline-block;
    animation-name: slideFromBottom;
    animation-duration: .75s;
    animation-timing-function: cubic-bezier(.2,0,.2,1);
    animation-iteration-count: 1;
    animation-fill-mode: both;
}

@keyframes slideFromBottom {
    0% {
        transform: translateY(100%);
    }
    100% {
        transform: translateY(0);
    }
}
<div class="container paragraph">
    <p data-anim="wrap-words" data-delayDelta=".0025">In ac sagittis nibh. Duis eleifend tortor ac nunc pretium, sit amet sollicitudin lectus pretium. Nulla laoreet ac tellus id imperdiet. Sed molestie iaculis varius. Fusce commodo lacinia dapibus. Pellentesque ullamcorper lectus at erat volutpat cursus.</p>
</div>

0

There are 0 best solutions below