Eleftheria Batsou
Posted on March 12, 2023
Introduction
In this article, I'm describing how to create the flush emoji with only 3 HTML classes. 😳
The emoji will have a head, eyes, cheeks, and a mouth. In the end, we'll add some animations for the eyes too!
Tools and resources:
I'm using
codepen
.Great source for animations animista.net
CSS gradient color generator cssgradient.io
CSS box shadow generator cssgenerator.org
You'll learn:
How to create circles
How to use
inne
r andouter
shadow-ban
How to write pseudo-classes, and specifically we'll use
::before
,::after
and:hover
How to write a
hover
condition for abefore
&afte
r pseudo-classHow to add simple animations
For practice, you can:
Add brows to this emoji
Create a new, different emoji
The final result:
And this image is my inspiration.
Note : If you're curious about what CSS art is, in this article I have a short explanation.
Why did I choose the flushed emoji?
The flush emoji is one of my favorite emojis, I use it a lot and sometimes I even feel my face looks like it. So I thought "why not coding it?!" 😅
The flushed emoji is used for surprise, confusion, or even embarrassment.
Ok, let's start!
The base 🖼
The html code is very simple.
<div class="container">
</div>
I'll start with creating the background in CSS. To do so, I'll use the body.
/* CSS Custom Properties */
:root { --bg-color: pink }
body {
background-color: var(--bg-color);
height: 100vh;
display: grid;
place-items: center;
margin: 0;
}
Here is what I did:
The first line sets the background color of the entire page to a variable named
--bg-color
. Variables in CSS are declared using thevar()
function and can be used to store values that will be reused throughout the stylesheet. In this case, the variable is used to set the background color of the entire page.The second line sets the height of the
body
element to 100% of the viewport height using thevh
unit (1vh is equal to 1% of the height of the viewport).The third line sets the
display
property of thebody
element togrid
. This tells the browser to lay out the child elements of thebody
element as a grid.The fourth line sets the
place-items
property of thegrid
container tocenter
. This tells the browser to align the grid items along the horizontal and vertical center of the grid container.The fifth line sets the margin of the
body
element to 0, this will remove any default margin that the browser may have added to the body
After the body
, I have the .container
.container {
display: flex;
justify-content: center;
position: relative;
}
This block of code is a class selector for an element with the class .container
.
The first line sets the
display
property of the.container
element toflex
. This tells the browser to lay out the child elements of the.container
element as a flex container.The second line sets the
justify-content
property of the flex container tocenter
. This tells the browser to align the flex items along the horizontal center of the flex container.The third line sets the
position
property of the.container
element torelative
. This allows you to position the container relatively to its initial position, for example, you can usetop
,right
,bottom
,left
properties to move it around.
Note : body
and container
are 2 classes I love to use as templates. I usually copy-paste them from previous projects. 😉
Create the head 🫥
Let's start our CSS art by creating a round head
.
<div class="container">
<div class="head">
</div>
</div>
We will create:
a circle
add color to it
position it relative
.head {
/* create a circle */
width: 300px;
height: 300px;
border-radius: 50%;
/* add some color so you can see it */
border: 6px solid #e9960f;
background: radial-gradient(circle, rgba(255,230,53,1) 0%, rgba(233,150,15,1) 100%);
box-shadow: 4px 4px 36px 24px rgba(244,126,28,0.7) inset;
/* we need the position 'relative' b/s we're going to have a few elements inside the head. The elements will be positioned "absolutely" in releationship with the parent class (which is .head) */
position: relative;
/* we also need these 3 lines for the elements that are coming inside the .head */
justify-content: center;
display:flex;
align-items: baseline;
}
For the background
, I used the cssgradient.io.
background: radial-gradient(circle, rgba(255,230,53,1) 0%, rgba(233,150,15,1) 100%);
For the inner box-shadow
, I used cssgenerator.org
box-shadow: 4px 4px 36px 24px rgba(244,126,28,0.7) inset;
The box-shadow
property applies a drop shadow effect to the .head
element. The specific value used 4px 4px 36px 24px rgba(244,126,28,0.7) inset
creates an inner shadow effect with the inset
keyword.
The shadow is 4px
horizontally and vertically from the element, with a blur radius of 36px
and spread distance of 24px
.
The color is rgba(244,126,28,0.7)
.
Reminder : The "a
" value in rgba
stands for "alpha" and it specifies the opacity of the color, with 0 being completely transparent and 1 being completely opaque.
Here is an image of the result:
Create the mouth 👄
To create the mouth, we will not add a new class, instead, we'll use the pseudo-class ::before
. Here is how the code looks:
.head::after {
content: "";
position: absolute;
/* add mouth */
width: 60px;
height: 16px;
background: #834905;
margin-top: 230px;
border-radius: 40%;
border: 1px solid black;
box-shadow: -1px 2px 4px 4px rgba(98,47,2,0.5) inset;
}
If you want to simplify your version you can remove the box-shadow
.
Let's examine the first two lines of .head::before
:
.head::after{
content: "";
position: absolute;
}
This CSS code targets an element with the class of .head
, and it uses the ::after
pseudo-element to insert some content after the element (in our case this is going to be a shadow).
The
content: ""
property sets the content of the pseudo-element to an empty string, which means it will not display any content.The
position: absolute
sets the position of the pseudo-element to be absolute, which means it will be positioned relative to the nearest positioned ancestor element instead of the viewport.
💡 Tip : Feel free to experiment with the colors and the sizes in width
, height
, margin-top
, etc.
Here is an image of the result:
Create the eyes 👀
And now we have some cool stuff to explore! We'll add the last two classes in HTML (one for left
eye and one for the right
eye):
<div class="container">
<div class="head">
<div class="left"></div>
<div class="right"></div>
</div>
</div>
More interesting though is the CSS code. I will start by writing the 2 classes .left
and .right
where I basically create a circle with some color and a border.
.left, .right {
background: white;
border-radius: 50%;
border: 1px solid rgba(0, 0, 0, 0.7);
width: 110px;
height: 110px;
position: absolute;
margin-top: 80px;
/* the eyes are centered b/s of the last 3 lines in the .head */
So far so good! Eyes are ready but we're definitely not done! In this phase, the eyes are on top of each other. We need to separate them, and here is how it's done:
.left {
margin-left: -150px;
}
.right {
margin-left: 150px;
}
Perfect!
To make them look even better I'll add an inner shadow using the .left::before
and .right::before
pseudo-classes:
.left::before, .right::before {
content: "";
position: absolute;
/* add the inner shadow (the shadow inside the eyes) */
width: 110px;
height: 110px;
border-radius: 50%;
box-shadow: 1px 2px 8px 8px rgba(144,127,87,0.8) inset;
}
Note : If you wanted to simply your version of emoji, you could add the box-shadow
to the .left
and .right
classes, and not use the pseudo-classes at all.
The pupils:
In the eyes, we need to add the pupils... The pupils will be black circles (we'll do this inside the eyes, which for us these are the classes .left
and .right
):
So firstly, I need to add this block of code in the classes .left
and .right
:
.left, .right {
...
/* we also need the 3 lines b/s we are going to add the pupils inside the class .left, .right */
display: flex;
justify-content: center;
align-items: center;
}
Then, I'll create the pseudo-classes .left::after
and .right::after
:
.left::after, .right::after {
content: "";
position: absolute;
/* Create the pupils */
width: 40px;
height: 40px;
background: black;
border-radius: 50%;
}
Yes! Eyes are completed!
Here is an image of the result:
Create the cheeks 🌸
To make the emoji look even better, we all the cheeks. This is fairly simply as we don't need any new classes or many lines of code.
The cheeks will actually be a shadow!
Let's return to the .left
and .right
classes, here is what we need to add:
/* add cheeks as an outer shadow (the shadow outside the eyes) */
box-shadow: 0px 50px 19px -4px rgba(242,122,24,0.9);
Here is an image of the result:
And actually, we're done with creating a basic flushed emoji!
You can experiment by adding eyebrows, changing the colors, the sizes, and more!
Bonus: Add animation to the eyes
If you want something extra in your CSS art why not add adding an animation?! I decided to use an animation for the eyes.
There're two things we are going to do:
Animation for the pupils when the CSS loads
Animation when you hover into the eyes
We don't need any extra classes on the HTML part. We'll just add a few lines in the CSS part.
Let's start with case no.1 - Animation for the pupils when the CSS loads.
The pupils are done with the pseudo-classes .left::after
and.right::after
so here is where we'll the code:
.left::after, .right::after {
content: "";
position: absolute;
/* Create the pupils */
width: 40px;
height: 40px;
background: black;
border-radius: 50%;
animation: zoom-in-zoom-out 1s ease 4;
}
In the last line, I'm adding an animation with the name zoom-in-zoom-out
with a duration of 1s
, an easing effect of ease
, and 4 iterations.
💡 Tip : You can find many more animations in animista.net
I'll continue by defining the animation:
@keyframes zoom-in-zoom-out {
0% {
transform: scale(1, 1);
}
50% {
transform: scale(1.5, 1.5);
}
100% {
transform: scale(1, 1);
}
}
This block of code creates a keyframe animation named zoom-in-zoom-out
.
It has three stages:
0% of the animation: the transform property is set to
scale(1, 1)
, meaning that the element will be scaled normally with no change in size.50% of the animation: the transform property is set to
scale(1.5, 1.5)
, meaning that the element will be scaled to 150% of its original size along both the X and Y axis.100% of the animation: the transform property is set to
scale(1, 1)
again, so the element will return to its normal size at the end of the animation.
The animation
property will use the keyframe animation, and will run for 1 second with an ease-out effect, repeating 4 times.
💡 Tip : To see this effect, reload your page!
Now, let's go to case no.2 - Animation when you hover into the eyes.
We'll cover this case with just one line of CSS code. Here it goes:
.left:hover, .right:hover { animation: zoom-in-zoom-out 1s ease 2; }
Now everytime you hover
the left or right eye you will see the animation as defined in zoom-in-zoom-out
, with a duration of 1 second, an easing effect of "ease" and 2 iterations.
💡 Tip : To see this effect, hover with your mouse over the eyes!
https://codepen.io/EleftheriaBatsou/pen/eYjPYxW?editors=0100
Sum up💫
In this article, I described how to create an emoji using only CSS and HTML. More specifically, we created the emoji with just 3 classes (.head
, .left
and .right
). We used the pseudo-classes ::before and ::after to achieve things such as the mouth, the pupils, etc. Many of the emoji's characteristics, such as the cheeks, have been created with inner or outer shadows. Last but not least, there is an enlarged effect (animation) in the eyes.
If you have any questions feel free to ask them in the comments!
Before you start creating something similar, it'd be good to know how:
positions work (mainly position absolute, relative)
some basic flex-box properties work
to play around with
box-shadow
to use the
::before
and::after
Extra: animations
Feel free to tag me if you try something similar. I'd love to see your art!
Thank you for reading! Find the code on Codepen.
👋 Hello, I'm Eleftheria, developer & public speaker.
🥰 If you liked this article consider sharing it.
Posted on March 12, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.