I have always wanted to try out this #cssart thing. It's been on my list of things for a while and I recently thought it's time I officially checked that box!
It seems befitting to kick things off with a regular cup of coffee. Our final pen should look something like:
Keep scrolling to see how I made this or explore the pen.
Let's start by laying out our html page then build the individual pieces with css one at a time.
html
<body class="main">
<div class="section">
<div class="saucer"></div>
<div class="cup">
<div class="cup-center">
<div class="coffee"></div>
<div class="froth"></div>
<div class="coffee-dark-top"></div>
<div class="hot-steam steam-move"></div>
</div>
<div class="cup-handle"></div>
</div>
<div class="teaspoon">
<div class="spoon-center"></div>
<div class="spoon-handle"></div>
</div>
</div>
<div class="text"></div>
</body>
The background and graphic container
We will style the layout of the page and set the boundaries for our graphic. We do this by targeting the main
and section
classes. The layout of the page is given by the main
class (You may notice the grid-template has 2 rows, the second row is for the text inside the div with the text
class. For purposes of keeping this tutorial to the point, I have removed the inner text, however it is still available in the pen).
css
.main {
background-color: #dc9a00;
display: grid;
grid-template: 70% 30% / 100%;
justify-items: center;
margin: 5px;
}
Next, we define the boundaries of the graphic. You can add a border to visualize just how much space the graphic will take, just remember to delete it when you are done.
css
.section {
max-height: 700px;
max-width: 700px;
min-width: 350px;
min-height: 350px;
width: 100vmin;
height: 100vmin;
overflow: hidden;
border: 2px solid red;
}
The Saucer
To create a saucer, we will style the div with the saucer
class by making it into a circle. We do this by creating a square then adding a border-radius.
css
.saucer {
width: 80%;
height: 80%;
position: relative;
top: 10%;
left: 10%;
border-radius: 50%;
background-color: #f1f1f1;
background: radial-gradient(circle, #f1f1f1 0%, #e8e8e8 39%, #b1b1b1 42%, #e8e8e8 44%, #d2d2d2 68%, #eaeaea 70%, #dadada 100%);
}
You can play around with the radial-gradient property to get an almost realistic looking saucer.
Now we can add an empty cup.
The Cup
The cup is made up of 2 nested divs, the center of the cup and the handle. The cup needs to sit at the center of the saucer, therefore we will give it a relative positioning. The center portion of the cup will take up about half the entire cup space.
css
.cup {
width: 100%;
height: 100%;
position: relative;
top: -54%;
left: 25%;
z-index: 1;
}
.cup-center {
width: 48%;
height: 48%;
border-radius: 50%;
border: 1px solid #fdfdfd;
background: radial-gradient(circle,rgba(241,241,241,1) 0%, rgb(232, 232, 232) 44%, rgb(199, 199, 199) 54%, rgb(189, 189, 189) 62%, rgb(199, 199, 199) 62%, rgb(232, 232, 232) 65%,rgb(241, 241, 241) 100%);
filter: drop-shadow(17px 10px 11px #979797);
}
We now have a cup with no handle! Let's remedy that by adding a handle using the cup-handle
class. The handle shall be at the bottom-right. You can play around with this until you get the position you want.
css
.cup-handle {
width: 12%;
height: 6%;
position: relative;
top: -6%;
left: 39%;
background-color: #e9e9e9;
border: 2px solid #e9e9e9;
border-radius: 0% 20% 20% 0%;
border-left-color: #cacaca;
border-right-width: 5px;
transform: rotate(45deg);
filter: drop-shadow(24px 14px 15px #979797);
}
You should have a nice white-ish cup and saucer at this point.
Next up, let's add some coffee!
The Coffee
We will draw the coffee by styling the coffee
, froth
and coffee-dark-top
classes.
Starting with the coffee
class, we will create the illusion of coffee stains around the inner edge of the cup using a gradient background that has a light outer edge. We will then size the coffee
div to almost the same size as the cup center.
We then style the froth
background with a pattern of dots to mock cream with coffee bubbles. For this, we will use a customized svg background (You can play around with the original pattern, Polka Dots by Matt Lipman to create your own version).
.coffee {
width: 86%;
height: 86%;
position: relative;
top: 7%;
left: 7%;
border-radius: 50%;
border: 1px solid #a5a5a5;
background: radial-gradient(circle,rgb(45, 27, 0) 0%, rgb(53, 31, 1) 44%, rgb(54, 32, 0) 54%, rgb(60, 35, 0) 62%, rgb(154, 129, 103) 62%, rgba(158, 95, 29, 0.38) 65%,rgba(95, 65, 53, 0.33) 100%);
}
.froth {
width: 76%;
height: 76%;
position: relative;
top: -74.2%;
left: 12%;
border-radius: 50%;
border: 1px solid #a28143d9;
background: radial-gradient(circle,rgb(125, 88, 32) 0%, rgb(130, 92, 34) 44%, rgb(128, 91, 33) 62%, rgb(187, 140, 70) 100%);
background-color: #9e7b3a;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 90 90'%3E%3Ccircle fill-opacity='0.94' fill='%23362000' cx='45' cy='45' r='5'/%3E%3Cg fill='%23362000' fill-opacity='0.94'%3E%3Ccircle cx='0' cy='90' r='12'/%3E%3Ccircle cx='90' cy='90' r='12'/%3E%3Ccircle cx='90' cy='0' r='12'/%3E%3Ccircle cx='0' cy='0' r='12'/%3E%3C/g%3E%3C/svg%3E");
}
To finish off the coffee illusion, we will style the coffee-top-dark
class and then clip out a section of it to reveal the froth. To generate the clipping path, I used the online CSS clip-path maker. You can customize your own clipping as well.
.coffee-dark-top {
width: 76%;
height: 76%;
position: relative;
bottom: 150%;
left: 12%;
border-radius: 50%;
background: radial-gradient(circle,rgb(47, 29, 3) 0%,rgb(47, 29, 3) 42%, rgb(46, 28, 3) 49%, rgb(51, 34, 9) 59%, rgb(39, 23, 2) 65%, rgb(25, 15, 1) 68%,rgb(51, 30, 0) 100%);
clip-path: polygon(11% 29%, 14% 27%,18% 22%, 21% 18%, 24% 16%, 33% 12%, 37% 9%, 41% 7%, 43% 6%, 49% 5%, 53% 5%, 56% 6%, 62% 8%, 66% 9%, 70% 12%, 72% 14%, 74% 17%, 75% 22%, 76% 23%, 77% 24%, 80% 25%, 82% 27%, 86% 32%, 87% 36%, 88% 40%, 90% 42%, 92% 43%, 93% 52%, 93% 56%, 94% 61%, 93% 65%, 92% 68%, 89% 70%, 87% 74%, 73% 86%, 67% 89%, 62% 92%, 57% 94%, 53% 94%, 52% 94%, 48% 91%, 45% 90%, 39% 87%, 29% 84%, 21% 79%, 19% 76%, 12% 70%, 8% 68%, 5% 67%, 1% 56%, 1% 46%, 4% 36%);
box-shadow: inset 8px 10px 17px 5px #020100;
}
The Smoke or steam
Lastly, let's make the coffee seem hot by adding some moving steam. For this we will use the hot-steam
class to define the initial state and the steam-move
class to animate from one clip-path to another (You can animate between the clip-path property by ensuring the same number of points are used when clipping).
css
.hot-steam {
width: 100%;
height: 100%;
position: relative;
bottom: 240%;
left: 23%;
background: linear-gradient(70deg,rgba(187, 164, 129, 0.29) 0%, rgba(111, 97, 84, 0.42) 44%, rgba(169, 157, 134, 0.25) 54%, rgba(173, 166, 150, 0.46) 65%, rgba(226, 220, 220, 0.19) 74%,rgba(220, 220, 220, 0.23) 100%);
clip-path: polygon(12% 17%, 14% 16%, 16% 15%, 20% 14%, 26% 13%, 29% 13%, 34% 14%, 36% 14%, 39% 14%, 41% 14%, 43% 15%, 45% 16%, 49% 17%, 56% 18%, 60% 20%, 65% 21%, 68% 23%, 78% 25%, 80% 27%, 83% 30%, 88% 38%, 92% 41%, 94% 44%, 94% 46%, 92% 50%, 92% 52%, 92% 56%, 89% 59%, 87% 60%, 85% 60%, 83% 59%, 81% 58%, 79% 58%, 78% 59%, 77% 62%, 77% 66%, 76% 69%, 74% 74%, 73% 75%, 72% 76%, 69% 77%, 68% 79%, 66% 82%, 64% 83%, 60% 84%, 58% 84%, 56% 84%, 52% 85%, 50% 86%, 47% 87%, 44% 88%, 40% 89%, 37% 90%, 35% 90%, 29% 90%, 28% 90%, 20% 89%, 17% 88%, 10% 84%, 4% 79%, 2% 75%, 3% 71%, 3% 63%, 5% 59%, 5% 50%, 2% 45%, 1% 41%, 2% 34%, 5% 27%, 8% 24%, 9% 22%, 10% 19%);
}
.steam-move {
animation-name: steam-fade;
animation-duration: 10s;
animation-timing-function: ease-in-out;
animation-iteration-count: 20;
animation-direction: alternate;
}
@keyframes steam-fade {
50% {
left: 23%;
clip-path: polygon(12% 17%, 14% 16%, 16% 15%, 20% 14%, 27% 15%, 29% 17%, 32% 19%, 36% 19%, 39% 20%, 41% 21%, 43% 22%, 45% 22%, 49% 21%, 56% 16%, 58% 15%, 60% 14%, 66% 14%, 72% 12%, 78% 6%, 82% 4%, 89% 4%, 95% 3%, 96% 3%, 97% 8%, 99% 15%, 100% 20%, 100% 26%, 97% 34%, 96% 44%, 95% 46%, 94% 48%, 92% 50%, 87% 51%, 86% 51%, 84% 51%, 83% 51%, 82% 51%, 80% 52%, 79% 57%, 77% 59%, 75% 60%, 74% 61%, 72% 64%, 71% 65%, 70% 70%, 69% 73%, 67% 75%, 65% 77%, 56% 83%, 54% 84%, 51% 85%, 48% 86%, 40% 87%, 36% 88%, 32% 88%, 25% 88%, 20% 87%, 17% 84%, 15% 79%, 13% 75%, 12% 72%, 12% 64%, 16% 59%, 18% 56%, 22% 54%, 23% 53%, 25% 49%, 25% 44%, 24% 39%, 20% 33%, 12% 26%, 9% 20%);
}
}
Looks like coffee to me! Good job on getting this far! It was tough for me so I know how you feel especially if you are a newbie.
You may have noticed, my pen has a spoon that we haven't styled. I am hoping to leave that part out to keep this brief. We set out to create coffee in a cup and we did just that! However, if you are a css art newbie, like me, try styling the spoon as an optional challenge. If you get stuck you can always check out the pen or ask questions in the comments section.
Hope you enjoyed that cup of coffee. Let me know what you think in the comments section.
This post is part of an upcoming series: 15 things in CSS. I am not a css artist but I'm hoping to polish my css by making things in css and teaching said things.
All "things" will be available on codepen! If you are inspired to remix and make your own, fantastic! I'd love to see what you get up to, tag me here or on twitter.
Top comments (0)