A place to cache linked articles (think custom and personal wayback machine)
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

index.md 11KB

title: Highlight Text When a User Scrolls Down to That Piece of Text url: https://frontendmasters.com/blog/highlight-text-when-a-user-scrolls-down-to-that-piece-of-text/ hash_url: 5ff0fe74d4 archive_date: 2024-03-12 og_image: https://frontendmasters.com/blog/wp-json/social-image-generator/v1/image/639 description: I was reading a great post on Lene Saile’s blog and noticed a cool little design feature on her site that highlights a line of text once you scroll to it. Here’s a video so you can see … favicon: https://frontendmasters.com/favicon-32x32.png language: en_US

I was reading a great post on Lene Saile’s blog and noticed a cool little design feature on her site that highlights a line of text once you scroll to it. Here’s a video so you can see what I mean:

The highlighted line is done with a <mark> element in HTML, which feels right. I noticed the class name on Lene’s implementation is .gsap-highlight which implies GSAP is used which has as a great Scroll Trigger plugin. Let’s do this without JavaScript though, especially now that I’m hip to Scroll-Driven Animations.

Basic HTML

A paragraph with a mark (with a class):

<p>Lorem, ipsum dolor sit amet <mark class="scroll-highlight">consectetur adipisicing elit</mark>. Magnam voluptas aliquid, distinctio voluptatum neque qui modi. In adipisci ratione id officiis nulla veritatis, porro explicabo illum laudantium iure eius velit!</p>Code language: HTML, XML (xml)

CSS Mark Styling in CSS

I just want a solid background on the mark. But I’m not going to use background-color. Instead I’m going to use background-image, because then I can control the background-size which I ultimately want to animate. So:

mark.scroll-highlight {
background-size: 100% 100%;
background-repeat: no-repeat;
background-color: transparent;
background-image: linear-gradient(purple, purple);
}Code language: CSS (css)

Now I can animate that background-size from 0% 100% to 100% 100% which is the look we’re after. It even works when the text breaks across lines which is a miracle.

Now it’s a matter of when to run the animation.

Scroll-Driven Animation for the Mark

Here’s the whole trick:

mark.scroll-highlight {
background-size: 0 100%;
background-repeat: no-repeat;
background-color: transparent;
background-image: linear-gradient(purple, purple);

animation: mark-it linear;
animation-fill-mode: forwards;
animation-timeline: view();
animation-iteration-count: 1;
animation-range: contain 0% contain 25%;
}

@keyframes mark-it {
0% {
background-size: 0 100%;
}
100% {
background-size: 100% 100%;
}
}Code language: CSS (css)

The coolest part to me is the animation-range which gives us the opportunity to say when to start and end the animation with a solid amount of control. In the code above we’re saying to start the animation as soon as the element is fully within the viewport, then finish when it’s 25% of the way up the currently visible viewport.

Here the element is maybe 20% up the current viewport, so the animation is 80% finished.

Demo

Remember native support for Scroll-Driven Animations is essentially Chrome ‘n’ friends only right now. You could easily treat this as a progressive enhancement, wrapping the animation stuff in a @supports (animation-timeline: view()) { } block or however you wanna do it.