TL;DR
The codepen is at the end of the post
⚠️Important
Before diving into how to make this, it's important to note that the View Transitions API is not yet fully supported in all browsers. At the time of writing, Firefox and Safari do not fully support this API. For users on unsupported browsers, we will provide a fallback method to ensure a consistent experience across different platforms.
HTML
Let's start by setting up the HTML structure for our tabs. It is a simple navigation bar with buttons:
<nav>
<button> Explore </button>
<button> Discover </button>
<button> Navigate </button>
<button> Journey </button>
<button> Quest </button>
</nav>
CSS (part 1/2)
Next, we'll add some CSS to style our navigation and create the tabbed interface. We'll use flexbox to organize the buttons horizontally and apply a custom underline effect.
The underline is actually a :after
pseudo-element that gets applied to a element that have a .active
class.
button {
background: none;
border: none;
color: #fff;
cursor: pointer;
position: relative;
font-size: 24px
}
/* This is the underline element */
button.active:after {
content: '';
position: absolute;
inset: 0 0 -8px 0;
top: unset;
height: 3px;
background: #fff;
}
Javascript (part 1/2)
Now, let's add some JavaScript to handle button click events and update the active tab accordingly:
const buttons = document.querySelectorAll('button');
buttons.forEach(button => {
button.addEventListener('click', e => updateView(e))
});
const updateView = ({ target }) => {
// Remove the .active class of all elements
buttons.forEach(button => button.classList.remove('active'));
// Add the .active class only to the clicked element
target.classList.add('active');
}
If we run the project, we have this:
We are almost there 😅
CSS (part 2/2)
Here comes the wizardry 🧙
The view-transition-name
property expects a string, any value that don't start with a number will do the job.
button.active:after {
/* ... */
view-animation-name: my-custom-transition; // unique name
}
Javascript (part 2/2)
Here comes the wizardry² 🧙
The startViewTransition()
method expects a callback function to make some good stuff:
- Handle the loading and positioning of the old and new content.
- Animate the old and new states to create the transition.
- Stop accidental user interactions with the old content from causing problems.
- Remove the old content once the transition is complete.
const buttons = document.querySelectorAll('button');
buttons.forEach(button => {
button.addEventListener('click', (e) => {
// Fallback, in case your browser
// doesn't support startViewTransition
if (!document.startViewTransition) {
updateView(e);
return
}
// tada 🪄
document.startViewTransition(() => updateView(e))
})
});
const updateView = ({ target }) => {
buttons.forEach(item => item.classList.remove('active'));
target.classList.add('active');
}
There you have it 🎉
With the View Transitions API, we can create seamless animations between different views or states of your web application, enhancing the overall user experience.
Codepen:
Top comments (6)
AWESOME!!!!!!!!!!!!!!!!!!!!!!!!!!!
how about 'hover event', ex: mouseenter/mouseleave? I dont see any result in the Internet T_T
Hey @phongpticdvn, thanks for the message.
If you change the eventListener to mouseenter, it should work when hover the button, like this
button.addEventListener('mouseenter', ....
(on line 4)But I'm not sure if that is what you need, you have an example to illustrate the effect you are trying to do?
I know that but the event i triggered continously, try it at: w3schools.com/tags/tryit.asp?filen...
with this script code:
const details = document.querySelector('details')
const summary = document.querySelector('summary')
summary.addEventListener('mouseenter', (event) => {
console.log(event)
event.preventDefault()
document.startViewTransition(() => {
details.setAttribute('open', '')
})
})
I think you want to animate the element when open/close, right?
I didn't try that yet. Although I found a blog post on dealing with this animated element, here: css-tricks.com/how-to-animate-the-...
It uses the Web Animation API insted of View Transition API, but maybe is this the effect you are looking for, and it will work in all browsers, hope it helps
Hey @phongpticdvn, check this out 🎉
youtube.com/watch?v=Vzj3jSUbMtI