How I Make CSS Art

How I Make CSS Art

ยท

10 min read

Featured on Hashnode
Featured on daily.dev

Motivation

On the third of June 2021, I created my very first CSS art. I had so much fun building this, and I continued building more and experiencing different methods to create them. My CSS art became better the more I practiced, and I got to know CSS better because of it. In fact, CodePen picked two (out of four) of my CSS arts to feature before. I decided to write this blog post to illustrate my thought process from the very beginning up until publishing the art on codepen. Hopefully, this will attract more people into creating CSS art and have fun with it,

Table of Content

cute ghost image

In this blog post, I will explain how I made this cute ghost CSS art from scratch. My thought process is split up into the following sections:

  • Finding Inspiration
  • Sketching
    • Basic Sketch
    • Splitting the sketch into layers
  • Code
    • HTML
    • Positioning
    • Responsiveness
    • CSS

Finding Inspiration

This is the part that requires A LOT of time to settle on an idea. There are two ways, I try to find inspiration with:

  • Scrolling through Pinterest
  • Looking around the place I'm in and sketching random things I find.

For the CSS art I'm showing here, I obviously was scrolling through Pinterest (or maybe I have ghosts around the house, maybe I AM a ghost, y'all can't know for sure lol). I usually search for art and doodles and see if I like something, I don't copy anything and draw things in my own style, I just get inspiration from Pinterest.

Other times, like in this egg CSS art, I got my inspiration simply because mum was making Eggs for herself and I thought "cool, I'll draw this with a face on it and make it with CSS". So, you can literally get inspiration from everyday things and that's the beauty of art, right?

It's not all fun and games though. I do get stuck about making decisions on what I should implement with CSS. In that case, friends come to the rescue! Don't be afraid to ask your friends about what you should do, and they could give you some solid ideas!

Sketching

This is a CRUCIAL step. Do not jump straight to code if you have an idea.

sketch ๐Ÿ‘๐Ÿป it ๐Ÿ‘๐Ÿป first ๐Ÿ‘๐Ÿป

Why? Simply because it's so hard to code something that you can't see. Developers in their day-to-day jobs don't come up with designs on the spot while coding. The design is given to them by the designers and they implement that design.

Basic Sketch

I use procreate for sketching. However, you can use pen and paper for sketching! You don't have to be an artist to sketch; just draw roughly how you want your art to look.

image.png

This is the sketch I drew on procreate. It took me 10 mins to make without colors. The lines aren't perfect, but I could make out what I want to draw from this sketch. It took me more time to pick out the colors because I overthink way too much.

If you're using pen and paper, color picking will be more complicated. What you can do is pick colors during coding with an online color picker. The most important thing about this stage is getting the structure and lines of your art, the colors come second.

P.S. I know I didn't do the little crown in the CSS art, I decided against it because I didn't like how it looked :/

Splitting your Sketch into layers

Congrats! You got your basic sketch! Now, it's time to plan how your sketch will be split into layers (divs). You can think of every part of your sketch as a sticker that goes on top other parts (stickers).

stickers

Basically, it's planning how your HTML div tags will be structured to fit your needs for this CSS art.

I like to simply add arrows on top of the sketch with the name of the layer, like this:

sketch with arrows

I know it looks ugly; at the end of the day this is just an asset to help you build the actual thing. There is no right or wrong way of layering your CSS art. I usually go with the following rules:

  • the root div is called "canva"
  • A "circle" layer behind the main CSS art to make it pop.
  • Any two layers that are next to each other (not stacked on top of each other) I separate them by adding each one in its own "bubble" (look at ghost and legs layers, the ghost layer is the main body of the ghost and the legs layer is the ghost's legs, they are next to each other; they don't overlap, so I added each one in a bubble to make that clear.)
  • if something is too simple to have its own layer, I don't name it. (See the eyes layer, there is a pupil inside the eye that I didn't name because it will be easier to create using eyes:before or eyes:after instead of having it on a div of its own.)

Code

HTML

Remember the way we split our sketch to layers? those layers are our divs. Any layer that is on top of another layer will be a div inside the opening and closing tags of the layer below it.

Example: the "circle" layer is on top of the "canva" layer and the "ghost" and "legs" layers are on top of the "circle" layer but next to each other, so the HTML code will be as follows:

<div class="canva">
    <div class="circle">
        <div class="ghost"></div>
        <div class="legs"></div>
    </div>
</div>

Notice how the ghost and legs layers are under each other in the code. This is because they are next each other, not on top of each other

Full HTML code:

<div class="canva">
  <div class="circle">
    <div class="ghost">
      <div class="heart"></div>
      <div class="eyes"></div>
      <div class="mouth"></div>
      <div class="left-hand"></div>
      <div class="right-hand"></div>
    </div>
    <div class="legs">
      <div class="circle1"></div>
      <div class="circle2"></div>
      <div class="circle3"></div>
      <div class="circle4"></div>
    </div>
  </div>
</div>

Positioning

To make good CSS art, you must understand positioning very well.

if you're not sure how CSS positions work, try out this article:

CSS Layout - The position Property

The rule in CSS art is simple, if a div need to be in a certain (using top, bottom, left or right properties) position relative to its parent div then the parent div has position: relative and the child div has position: absolute

Responsiveness

There are several ways to make a CSS art responsive. My preferrable way though is to use vmin in all places where I need sizing units. vmin is the lesser of vw and vh. You can check out here for more information.

CSS

In this section, I will explain the code in detail and how I think while writing the CSS.

*

* {
  margin: 0;
  padding: 0;
}

I like to start off by disabling the default margin and padding of the browser to have a clear canva.

Canva

.canva {
  background: #f7f5ff;
  height: 100vh;
  width: 100vw;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

This is the background of the CSS art (very light, almost white, purple). I set the background, stretched the canva take the whole width and height of the screen and made the canva's children centered.

There are several ways to center children but I prefer the flexbox way because it is so intuitive for me.

I made the position of the canva relative because I will not manually position it. You can remove that line of code though because the canva div has only one child and its position isn't absolute, so it wouldn't matter in this particular case.

Circle

.circle {
  width: 70vmin;
  height: 70vmin;
  background: #e8e0ff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}

The circle is just for decoration purposes so there isn't much to say about it here, It's a basic circle using CSS. You can see that I'm using vmin to assign the width and the height. I also used flexbox to center its children.

Ghost

.ghost {
  position: relative;
  border: 0.5vmin solid black;
  width: 30vmin;
  height: 30vmin;
  border-top-left-radius: 100px;
  border-top-right-radius: 100px;
  border-bottom: 0;
  box-sizing: border-box;
  background: #FFDCDF;
}

This is the ghost's body. I wanted a semi-circle like shape with a border and a background. so I only assigned the top left and top right border radii and removed the bottom border.

Legs

.legs {
  display: flex;
  width: 30vmin;
}

.legs div {
  width: 7.5vmin;
  height: 6vmin;
  border: 0.5vmin solid black;
  border-bottom-left-radius: 100px;
  border-bottom-right-radius: 100px;
  border-top: 0;
  background: #FFDCDF;
}

The legs part is simply four semi-circles next to each other. I used flexbox to make the semi-circle in a row and gave it the same width as the ghost. Each semi-circle has a width = 30vmin/4 = 7.5vmin. I created the semi-circles by assigning the bottom left and bottom right radii and removed the top border.

Heart

.heart {
  position: relative;
  width: 5vmin;
  height: 5vmin;
  background-color: #FF3737;
  transform: translate(22vmin, 6vmin) rotate(25deg) scale(0.5);
}

.heart:before {
  position: absolute;
  bottom: 0px;
  left: -2.5vmin;
  width: 5vmin;
  height: 5vmin;
  content: '';
  -webkit-border-radius: 50%;
  -moz-border-radius: 50%;
  -o-border-radius: 50%;
  border-radius: 50%;
  background-color: #FF3737;
}

.heart:after {
  position: absolute;
  top: -2.5vmin;
  right: 0px;
  width: 5vmin;
  height: 5vmin;
  content: '';

  -webkit-border-radius: 50%;
  -moz-border-radius: 50%;
  -o-border-radius: 50%;
  border-radius: 50%;

  background-color: #FF3737;
}

The heart is a square and two circles. I followed this tutorial to create a heart shape then added my preferences to it. I also added a rotate transform to make it fit my needs.

The heart had to be a relative position in order to make the before and after selectors work. However, I needed to change its location. There were two options in front of me:

  1. Wrapping the heart div with another div and making that div's position absolute
  2. Use translate transform.

I went for the second option because it was faster, but nothing is wrong with the first option as well.

Eyes

.eyes {
  position: absolute;
  width: 5vmin;
  height: 5vmin;
  background: #000;
  border-radius: 50%;
  top: 13vmin;
  left: 5vmin;
  box-shadow: 14vmin 0;
}

.eyes:before{
  content: "";
  position: absolute;
  background: white;
  width: 2.5vmin;
  height: 2.5vmin;
  border-radius: 50%;
  left: 2vmin;
  box-shadow: 14vmin 0 white;
}

Notice how it is called "eyes" but it is only one div? That's because I will create both eyes in one div using box-shadow property. The eye consists of two parts: the eye itself and the highlight over it.

Let's start with the eye.

I created a normal black circle and positioned it in the place I found suitable with the left and top properties. These properties won't work unless you have declared position: absolute .

To create the other eye, I used the box-shadow property to replicate this eye and changed the x-axis position the way I found suitable.

Now on to the highlight.

I used the :before selector to create this one. It is exactly like the eye but with different color and size. I also used the box-shadow property with the same x-axis value to make sure everything aligns perfectly.

Mouth

.mouth {
  position: absolute;
  width: 4vmin;
  height: 2vmin;
  border: 0.7vmin solid black;
  border-bottom-left-radius: 100px;
  border-bottom-right-radius: 100px;
  border-top: 0;
  top: 16vmin;
  left: 12vmin;
}

The mouth is just a semi-circle with an absolute position. Nothing much here.

Hands

.left-hand, .right-hand {
  position: absolute;
  width: 4vmin;
  height: 4vmin;
  border: 0.5vmin solid black;
  border-bottom-left-radius: 100px;
  border-bottom-right-radius: 100px;
  border-top: 0;
}

.left-hand {
  top: 22vmin;
  left: 6vmin;
  transform: rotate(-45deg)
}

.right-hand{
  top: 22vmin;
  left: 18vmin;
  transform: rotate(45deg)
}

The hands are also just semi-circles but with rotate transform. Notice I didn't use box-shadow here because I wanted every hand with a different rotate value.

Conclusion

CSS art is enjoyable to make but it requires some knowledge to keep in mind while making it. Hopefully, this blog post inspired you to try and play around with some CSS and cleared up any confusion you had about CSS! I'd love to hear your thoughts and if you'd like to add more tips that would be awesome!