On 27th of October 2020 is the first global conference of Next.js, I’m so excited about it as a React developer, That’s why I’ve registered immediately after I knew about it, but what happened after I registered was super interesting, I’ve got a confirmation message from the conf committee with this URL https://nextjs.org/conf/tickets/medhatdawoud 🔗 which is an interactive ticket, well designed and well animated I’d like to thank the team for designing and developing that, and today we are going to make a clone of it (for learning purposes).
We have quite some challenges here to resolve:
- building the ticket itself (✅ will just start with a pre-created one)
- implement the gradient borders.
- implement the half-circles right and left.
- implement the animation according to the cursor move.
Let’s start with the implementation step by step, hence the final code could be found in this github repo 🔗 alongside other challenges as well.
1. building the ticket itself
As we agreed earlier, that would be ready one, you can find the whole code in the repo, but this is the HTML:
event-logos.png is the lower part of the ticket that I took it as a screenshot because that is out of our focus today.
And the CSS is as follow:
Now it looks as follow:
2. implementing the gradient borders
The first goto CSS property for making a gradient or even an image as a border is the
border-image property, which has great support on all browsers including ie11 as per MDN 🔗.
The only problem with using it is that it doesn’t support
border-radius so we cannot use it, unfortunately, and will make some work-around to implement that.
The idea is mainly to use a
div inside another
div, let’s call them parent div and child div, you can easily add an image or gradient color in our case as background to the parent div, then give a solid color to the child div for example solid black in our case, then give the parent div
padding of the width of the border you want, in our case
5px, and technically what the
padding is doing is to put a space between the border and the content inside the
element, so it will press the child div with
5px from all directions, and that will enable 5px to show from the parent div as if they are a border to the child div.
well, let’s implement that, we have a parent child which is
.ticket-visual_visual then we can give it a background with the desired gradient border colors, after getting the 4 colors from the main conf website and create them as custom properties as follow:
linear-gradient the first param is
to right as we needed to have that gradient from left to right.
Now we need to make the child div with solid background as we agreed, the child div here is
.ticket-visual-wrapper, so let’s give it a background:
Now we have made it with that work-around for a gradient border, let’s now try to give them border radius:
and the current result should be:
Well, we reached a good stage, for now, we have made a curved border with gradient color.
3. implementing the half-circles right and left
With the same idea, we used before we need to use
pseudo-elements of the parent div as parent elements and for the child div as child elements.
so basically will use
:after pseudo-elements as follow:
As you can notice, we treat them as divs and positioned them in the middle left and right of the card, also give both of them the extremes of the gradient colors, the left one takes the first color
--color1 as background and the right one takes
--color4 as background, so the result now should be as follow:
Then we need to add a child circle for each of them with a solid color (black), let’s add
pseudo-elements for the
.ticket-visual-wrapper as well, but first let’s add
position: relative to it:
As you see, we made 2 smaller circles
50px X 50px then the parent ones
60px X 60px and the background here for both are the color of the background
--background which is black, the last notice here is that I give them
z-index: 3 to make them get elevated on top of the parent
The current result:
The only remaining thing is to hide the outer halves of the circles, TBW I found that having something like a cover for them could be a good solution, so I decided to add 2 divs that could be used as covers inside
.ticket-visual_visual as follow:
and in CSS as they are inside a
position: relative div, by giving them
position: absolute they will be positioned well:
giving them background black, and
z-index: 4 to be on to and cover the halves of the circles, the final result is:
Now the design is complete like the one implemented in the conf website.
4. implementing the animation according to the cursor move
I decided to add that in an inline script tag in the same HTML file because it doesn’t require a separate file.
before the listening we need to select the ticker element and get its bounding rect as well, to calculate the center point of the ticket element as follow:
then inside the
mousemove event lister we need to add some code to transform that ticket, simply we can add some calculations for the degree that we will use for rotation as follow:
Note that this calculation means: we get the difference between the current mouse position and the center point we calculated earlier, then multiply them by a very small number
0.008, I got it by trying and error until I feel that fit best.
Then we can use these calculated degrees to make the transformation:
5 you can find that we simply set the
perspective of the element to
1000px which is a big number to make it move very smooth without rotation, also we used the rotation of
y based on the calculated degrees.
Then the final result will be:
And, we’re done here, you might notice some shiny gradient on moving the mouse, but that’s for you for homework to make the ticket look glossy, please let me know if you did.
I’ve enjoyed writing this article, and I hope you enjoyed reading it as well: we’ve learned from it multiple things or at least I hope so:
- How to work-around and make a gradient border with border-radius in place
- How to implement a half-circle with a gradient border
- How to use
perspectivein implementing a 3D animation
- How to think about the calculation of the variable
- All code is on Github 🔗 go check it out, fork, clone, and do your homework 😉.
Finally, feel free to share it or discuss it with me on Twitter 🔗 if you want any help, or follow and let’s be friends.
If you understand Arabic, here is an explanation step by step in an Arabic tutorial: https://youtu.be/BfAydRvM-vk 🔗
Tot ziens 👋