Hello everyone, I'm Zero One . Today I will show you how to implement a Douyin LOGO with animation using only one HTML tag . It involves a lot of knowledge points. Welcome to exchange and discuss.
First, the results are as follows:
Restoration should be fine, right?
Douyin Logo Structure
If you want to use CSS to draw Douyin's Logo, you must first understand its structure, which must be a combination of geometric figures. Because many industry leaders have already learned about the structure of Douyin's Logo before, I will borrow it. one time:
OK, it's a bit complicated, to simplify it, it's actually 4
parts
The area delineated by each color represents a section, so at the end: 1/4圆环
+ 半圆
+ 长条矩形
+ 半径略大一些的1/4圆环
Production ideas
Going back to the title of this article, someone wants to say that I am a headline party. This logo
is divided into four parts. How can you do it with one label? Even if you use ::before
and ::after
, there are three parts in total with the label body
and! logo
has two layers:
As you can see, a cyan note and a red note are superimposed
so! So many elements, how do you do it with one tag? And also said to bring animation, are you kidding us?
Well, don't worry, let's think about it first:
Let’s start by thinking about the general direction of the elements:
- Need to implement a black background (requires a label)
- Two notes superimposed ("black background" is already a label, those two notes can only be two pseudo-elements)
Then start to break through from the small details of the elements:
- The entire note pattern needs to be drawn in one stroke in a pseudo-element (let me think about it...)
How to draw the entire note pattern in one pseudo-element?
💡 I figured out a way, it's super simple, let me show you
<style>
/* 为了保证文章整洁,省略一些代码... */
.douyin::before {
background: url('青色的音符.png')
}
.douyin::affter {
background: url('红色的音符.png')
}
</style>
<div class="douyin"/>
Well, easy to get it, this article is over! Applause 👏🏻 Everyone, like , favorite, forward, let's go~
Stop scolding, stop scolding, I just made a little joke with everyone, the text is on!
We must use the background
attribute, otherwise where is the color block, go to the MDN document:
Don't think about it anymore, only one background-image
is useful, let's take a look at it:
Focus ! Students, background-image
supports setting one or more images for an element, let's see which image types it supports:
After reading the grammar, I found that basically the <image>
type supports directly setting the picture, and only one supports the gradient function, for example: linear-gradient
, repeating-linear-gradient
, radial-gradient
, conic-gradient
...
If you don't know CSS syntax yet, you can read my previous discussion: Why is CSS so hard to learn? It must be that your method is wrong . It explains in detail how to interpret the syntax of CSS (with actual combat)
What is a gradient function? According to their word names, it can be known that linear, radial (actually circular), and conical color gradients are supported. We can use the first two to satisfy the structure of logo
Because according to the explanation on MDN, we can use multiple gradient functions to control the background image of the element, and multiple values are separated by ,
, such as the official example:
background-image: linear-gradient(rgba(0, 0, 255, 0.5), rgba(255, 255, 0, 0.5)),
url("../../media/examples/lizard.png");
To use a more vivid analogy, background-image
just like we write, we need to write one stroke by one stroke, and in background-image
,
separate each value Like each stroke, these values together form an "image"
Then we can use these functions to draw the Douyin logo.
go, go, go
First, let's measure the aspect ratio of the notes in the Douyin logo, in order to leave a certain space for the notes
I specially used the screenshot tool to circle the part of the red note, and the obtained width and height are 248 * 285
. Calculate the aspect ratio and it is approximately equal to 248/285 = 0.87
, then we have to leave one in the middle Rectangular position with aspect ratio 0.87
for note
lay the foundation
Then lay the foundation first!
<style>
.douyin {
width: 100px;
aspect-ratio: 0.87; /* 宽高比 0.87 */
border-radius: 25%;
padding: 20px calc(20px + 100px / 0.87 * 0.13 / 2); /* 四周留白,中间腾出位置给音符 */
background-color: #000;
}
</style>
<div class="douyin" />
Here I need to explain the setting of the value of padding
11544680aae319591cfa1f76c5fe1783---, 20px
is a margin size I set casually, since the top and bottom are both 20px
, and itself The aspect ratio of the overall element is not 1:1
(the whole is not a square), so for the visual centering and the overall width and height 1:1
, we need to increase the left and right margins to the whole width equals height
Therefore 100px / 0.87
get the overall height, and then multiply it by 0.13
to get the difference between the width and height, because it needs to be divided evenly on both sides, so it has to be divided by 2
Now it is properly a square, the current effect:
Here, in order to let the notes of the waiting session only be drawn in that area of the figure, we set the external container display: grid
, and the waiting session also needs to use the ability of grid
layout
.douyin::before,
.douyin::after {
content: '';
grid-area: 1/1; /* 居中展示 */
}
draw 1/4 circle
How to draw a circle ? Let's demonstrate with a simple example:
<style>
.demo {
/* demo 是一个正方形 */
background:
radial-gradient(
100% 100% at 100% 100%,
transparent 0 50%,
red 50% 100%,
transparent,
);
}
</style>
<div class="demo"/>
We get a graph like this:
How to get something like this 1/4圆环
? Let's break down the style:
100% 100% at 100% 100%
:
The left side of at represents the horizontal and vertical radial length of the circle (or ellipse); the right side of at represents the position of the circle on the coordinate axis
That corresponds to this figure:
transparent 0 50%
radial-gradient()
In addition to the first parameter of the function, the rest of the parameters represent the color and gradient degree
Therefore transparent 0 50%
means from the center of the circle to the position where the radius is half the length and the color is transparent
I'm afraid that you won't be able to see it here, so I changed transparent
to blue
and showed the renderings for everyone to see:
red 50% 100%
The principle is the same as the previous one, from the position with the radius 50%
100%
to the part with the radius ---9f96537dbed73875d48dd37191e666a1---, showing red
The effect picture is:
In fact, only the area pointed out by the yellow arrow is caused by our code, so why is it all red until the upper left corner of the square? Because radial-gradient()
function needs to set a color-stop
at the end, please see below
transparent
This is also the last parameter of the function, indicating that the gradient ends with a transparent color , that is, from the end position of the previous position ( red 50% 100%
) to the edge of the container, it is displayed as transparent
Now take a look at the effect:
Such a one 1/4圆环
is drawn
So back to our text
.douyin::before,
.douyin::after {
content: '';
grid-area: 1/1; /* 居中展示 */
+ background:
+ radial-gradient(
+ 100% 100% at 100% 100%,
+ transparent 0 50%,
+ #08fff9 50% 100%,
+ transparent
+ );
}
Now the container we store the notes is a rectangle with an aspect ratio of 0.87
. If we follow the code we just drew the rectangle, the final output should look like this:
Obviously, the widths of the two ends of the ring are inconsistent. At this time, we can use background-size
to compress it to get a ring with the same width. Fine tune it
This time it is almost the same width, and it is probably a standard 1/4圆环
, and then we have to put it in the lower middle position on the left side, the code is as follows:
.douyin::before,
.douyin::after {
content: '';
grid-area: 1/1; /* 居中展示 */
background:
radial-gradient(
100% 100% at 100% 100%,
transparent 0 50%,
#08fff9 50% 100%,
transparent
)
+ left 52%/41% 36% no-repeat;
}
There is a smell inside, is there?
draw a semicircle
The principles are similar, just put a semicircle generation and displacement process diagram:
The code is as follows, and I don't explain the meaning of the various values too much, because I am all fine-tuning:
.douyin::before,
.douyin::after {
content: '';
grid-area: 1/1; /* 居中展示 */
background:
radial-gradient(
100% 100% at 100% 100%,
transparent 0 50%,
#08fff9 50% 100%,
transparent
) left 52%/41% 36% no-repeat,
+ radial-gradient(
+ 50% 100% at top,
+ transparent 44%,
+ #08fff9 45% 98%,
+ transparent
+ ) 0 100%/73% 31% no-repeat;
}
draw strips
The strip may not be the same as the ring and semicircle. It uses linear-gradient()
linear function. We don't do fancy operations, just fill the entire area with colors, and then scale horizontally and vertically get a rectangle
.douyin::before,
.douyin::after {
content: '';
grid-area: 1/1; /* 居中展示 */
background:
radial-gradient(
100% 100% at 100% 100%,
transparent 0 50%,
#08fff9 50% 100%,
transparent
) left 52%/41% 36% no-repeat,
radial-gradient(
50% 100% at top,
transparent 44%,
#08fff9 45% 98%,
transparent
) 0 100%/73% 31% no-repeat,
+ linear-gradient(#08fff9, #08fff9) 66% 0/20% 70% no-repeat;
}
The animation of the effect process is as follows:
Draw a 1/4 circle with a slightly larger radius
Skip the explanation again and look directly at the code:
.douyin::before,
.douyin::after {
content: '';
grid-area: 1/1; /* 居中展示 */
background:
radial-gradient(
100% 100% at 100% 100%,
transparent 0 50%,
#08fff9 50% 100%,
transparent
) left 52%/41% 36% no-repeat,
radial-gradient(
50% 100% at top,
transparent 44%,
#08fff9 45% 98%,
transparent
) 0 100%/73% 31% no-repeat,
linear-gradient(#08fff9, #08fff9) 66% 0/20% 70% no-repeat,
+ radial-gradient(
+ 100% 100% at 100% 0,
+ transparent 0 58%,
+ #08fff9 58.5% 99%,
+ transparent
+ ) 100% 0/47% 41.8% no-repeat;
}
The effect diagram is as follows:
So far, one note has been drawn, only one step away from success
split
In our code just now, we wrote ::before
and ::after
together. In fact, two identical notes are now completely overlapping, and the colors of the two notes are now the same, we to transform
Color is obtained by variable
In order to prevent the code from being redundant, let's get all the #08fff9
in the code just now with variables, namely #08fff9 => var(--color)
.douyin::before,
.douyin::after {
content: '';
grid-area: 1/1; /* 居中展示 */
background:
radial-gradient(
100% 100% at 100% 100%,
transparent 0 50%,
var(--color) 50% 100%,
transparent
) left 52%/41% 36% no-repeat,
radial-gradient(
50% 100% at top,
transparent 44%,
var(--color) 45% 98%,
transparent
) 0 100%/73% 31% no-repeat,
linear-gradient(var(--color), var(--color)) 66% 0/20% 70% no-repeat,
radial-gradient(
100% 100% at 100% 0,
transparent 0 58%,
var(--color) 58.5% 99%,
transparent
) 100% 0/47% 41.8% no-repeat;
}
And set color variables for ::before
and ::after
separately
+ .douyin::before {
+ --color: #08fff9;
+ }
+ .douyin::after {
+ --color: #f00044;
+ }
In addition to that, we're going to move one of the notes so that the two no longer overlap
.douyin::before {
--color: #08fff9;
}
.douyin::after {
--color: #f00044;
+ transform: translate(3%, 3%);
}
see the effect
Ok, but the two notes are misplaced, but the color mixing effect does not seem to be there yet. At this time, the mix-blend-mode
attribute is used. The definition of MDN is to make the content and background of the current element and its parent element match a certain There are a lot of supported attributes. This article will not jump out to talk about too many other things. I tried them one by one on the console and found that lighten
, plus-lighter
, screen
can achieve our effect, but I don't know the specific function very well, I can learn it in the future
Please see the trial process👇
Finally, let's set it up mix-blend-mode: lighten
wow! Our Logo is ready!
add an animation
Why can't TikTok not shake?
We are now setting the red note to be offset to the right and upward 3%
, then we need to shake both notes now, which is actually to modify their respective offsets. Let's remake the code again!
.douyin::before {
--color: #08fff9;
transform: translate(calc(var(--x, 0%) - 3%), calc(var(--x, 0%) - 3%));
}
.douyin::after {
--color: #f00044;
transform: translate(calc(3% - var(--x, 0%)), calc(3% - var(--x, 0%)));
}
/* hover时,设置偏移变量 --x */
.douyin:hover::before,
.douyin:hover::after {
--x: 0.1%;
transition: transform cubic-bezier(.5,300,.5,-150) .3s;
}
Please see the effect:
Originally, I wanted to add the effect of a text glitch that I wrote to this Logo
. It must be cool, but I can't do anything about it, because to set the glitch effect for the note, we need to use pseudo-elements Yes, and now the note itself is a pseudo-element, I can't deviate from the title of my article "Use only one html tag to realize the animated Douyin Logo" , if you are interested, you can go down and add it yourself, remember when Aite me, I also want to see the effect
I can't think of any fancy animation. Finally, let's show you the "mutation" of the Douyin Logo.
Are you ready?
1~
2~
3~
Wow! I have to say, it's so pretty! Hahahaha, in fact, the implementation principle is not difficult, I just added an attribute of filter: invert(1);
to the element
At last
How, do I have no title party? It is indeed an animated Douyin Logo with only one HTML tag, right?
Finally, I hope that this article will be helpful to you. Zero-one has limited ability. If there are any mistakes in this article, please point them out in the comment area; if you have more ideas, you are also welcome to discuss with me in the comment area~
It is also considerate to prepare a complete sample code for you, and the friends who need it can view it by themselves
Full code : https://github.com/zero2one3/code-example/tree/master/css/write_tiktok_logo_with_one_html_tag.html
I am Zero One , sharing technology, not just the front end! See you next time~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。