Get started with CSS art - make a sheep! Step by step
Tags: css, html, codenewbie, codepen
Published: 2020-07-19 13:06:13

I recently hit the halfway point in my 100 days of CSS art journey - I've learned a lot since I started - you can read about it in my last post:

{% link https://dev.to/s_aitchison/5-lessons-from-50-days-of-css-art-2ae1 %}

I know first-hand it can be intimidating getting started with CSS art, and hopefully in this post I'll show you it's totally achievable, as we make this cute wee sheep, step by step.

## What you'll learn by making this sheep

- Some key positioning techniques
- Making use of `::before` and `::after` pseudo elements
- Utilising [CSS custom properties (variables)](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties)
- One way [clip-path](https://developer.mozilla.org/en-US/docs/Web/CSS/clip-path) can help you create shapes

## Checkpoints after each step

At the end of each of the 5 steps there is a CodePen showing you both the code and result of what we've covered up til the end of that step, so you won't get left behind!

If there is anything unclear in the instructions, do skip to that CodePen and take a closer look; hopefully all will become clear.

## Step 1: Set up your canvas

Start a new pen in [CodePen](https://codepen.io/) (or wherever you like to create your code!). The first step is to get ready with your "canvas" - i.e. the area of the page you will create your image inside.

### Choose a background color

First we'll set the `body` element's background color - I chose a nice grass green, but feel free to use whatever funky color you like!

```css
body {
  background: #54a865;
}
```

### Create a box and position center

I've created a `div` with the classname "sheep" to act as our canvas. Width and height has been set to 180px, and we'll give it some margin too so it looks nice on the page.

```html
<body>
  <div class="sheep"></div>
</body>
```
```css
.sheep {
  position: relative;
  margin: auto;
  display: block;
  margin-top: 8%;
  margin-bottom: 8%;
  width: 180px;
  height: 180px;
}
```

Note the property `position: relative`. This is important, as inside the canvas we will be using [absolute positioning](https://developer.mozilla.org/en-US/docs/Web/CSS/position). By setting the position to 'relative' here, the content of our canvas will be positioned relative to this canvas.

### Give yourself a guide by adding a temporary canvas background

I've set the background of the 'sheep' to `pink` for now, purely so I can see exactly where the canvas is, and check it's positioned correctly. Choose whatever color stands out to you!

### Work in progress - end of step 1:

Check what you should have so far:

{% codepen https://codepen.io/aitchiss/pen/JjGempB %}

## Step 2 - Make some fluff

The most important part of a sheep? The fluff! 

The fluff on this sheep is going to be made in two halves - left side and right side. On each side we will have three overlapping circles, like so:

![Diagram showing the 3 fluff parts on left and right sides, divided by lines](https://dev-to-uploads.s3.amazonaws.com/i/kg7hlpss9gisldsg3diy.png)

### Add a CSS variable for the fluff size

As we can see above, we'll have six total fluff pieces, all of which will be the same size. When you have a property that is going to be shared across multiple CSS selectors, it's a good idea to create a CSS property/variable for them.

This allows you to easily access and change the property in one place, without having to go through multiple places in your code.

We can create this fluff size variable at the root of the document like so:

```css
:root {
  --fluff-size: 70px;
}
```

Now whenever we want to access the fluff size (e.g. for the width and height of all the fluff pieces) we can use `var(--fluff-size)` to get it!

### Create the middle fluff pieces

The middle fluff pieces will be created with div elements:
`<div class="fluff left"></div>`
`<div class="fluff right"></div>`

The shared `fluff` class will contain the majority of our styles:

```css
.fluff {
  position: absolute;
  width: var(--fluff-size);
  height: var(--fluff-size);
  border-radius: 50%;
  background: white;
  top: 50px;
}
```

Then we can use the extra `left`/`right` class names to position each side correctly. 

The **left side** is going to be positioned at `left: 0`. Since this is the default for an absolute-positioned element, we don't need to add anything - yay!

The **right side** is going to be positioned at the right, which we can do as so:

```css
.fluff.right {
  right: 0;
}
```

### Create the upper fluff sections

To do this, we're going to use the `::before` pseudo element. I'm using this purely to cut down on the amount of HTML code. Using `.fluff::before` will place an element as the first child of any element with the `.fluff` class - e.g.

```html
<div class="fluff left">
  <!--  ::before fluff appears as if entered here      -->
</div>
```

We want to position the upper fluff elements slightly higher than the parent `.fluff` divs, and also more towards the center. 

We can use the shared `fluff` class to do most of the work:

```css
.fluff::before {
  content: "";
  position: absolute;
  width: var(--fluff-size);
  height: var(--fluff-size);
  border-radius: 50%;
  background: white;
  top: -35px;
}
```

And then once again we can make use of the `left`/`right` classes to move each side closer to the center, as so:

```css
.fluff.left::before {
  left: 35px;
}

.fluff.right::before {
  left: -35px;
}
```

### Create the lower fluff sections

This is very similar to the previous step. This time we'll use the `::after` pseudo element. Using `.fluff::after` will place an element as the last child of any element with the `.fluff` class - e.g.

```html
<div class="fluff left">
  <!--  ::before fluff appears as if entered here      -->
  <!--  ::after fluff appears as if entered here      -->
</div>
```

Similar to the above step, we'll use main `fluff` class to specify the majority of styles, and the left/right classes to push each lower fluff piece into the center.

### Work in progress - end of step 2:

With that - our fluff is created - see what we have so far:

{% codepen https://codepen.io/aitchiss/pen/KKVrGeW %}

## Step 3 - Add a head with ears

Now we have some fluff, but we need a head! We'll use a div with class name `head` to create this, and style it as round and black.

```css
.head {
  position: absolute;
  width: 70px;
  height: 70px;
  background: black;
  border-radius: 50%;
}
```

We'll also once again use `::before` and `::after` pseudo elements - this time to make the ears.

The ears are ovals with a black background color. To make sure we keep the width and height the exact same on both, let's make some more variables for them:

```css
:root {
  --fluff-size: 70px;
  --ear-width: 15px;
  --ear-height: 20px;
}
```

### Position the head

We want to make sure that the head is positioned in the center of the body. One way do that would be to crunch some numbers and work out exactly how many pixels to the left we want to place it.

An easier way (in my opinion) would be to use the following:

```css
left: 50%;
transform: translateX(-50%);
```

What this does is:

- Use the `left` property to set the start position of the head to 50% of the parent div (i.e. the canvas we created in step 1). Our canvas is 180px wide, so this would be the same as `left: 90px`
- Use the `translateX` transform to move the head to the left. The amount it moves to the left is 50% of the head's width. Our head is 70px wide, so this is the same as `translateX(-35px)`
- The combination of the two places the **center** of the head (i.e. 35px) in the **center** of the parent

### Work in progress - end of step 3:

You can check the ear positioning and sizes in the CodePen below, or try choosing your own first! After this step you should have something like:

{% codepen https://codepen.io/aitchiss/pen/dyGQggr %}

## Step 4: Add some face features!

We want a happy smiley sheep, so lets add some eyes first. We'll use very similar style as before, creating two HTML elements inside the head:

```html
<div class="head">
  <div class="eye left"></div>
  <div class="eye right"></div>
</div>
```

We'll use a border to help it look like a dark pupil inside of a white eye:

```css
.eye {
  position: absolute;
  background: black;
  border: 5px solid white;
  height: 10px;
  width: 10px;
  border-radius: 50%;
  top: 15px;
}
```

You can then use the `left` and `right` classes to position each eye how you like (check the work in progress CodePen below if you're not sure though!)

### Use clip-path to create the mouth

`clip-path` can be a very useful CSS property. It effectively creates a mask for your HTML element, allowing only a portion of it to be shown.

In this case, we're going to use it to turn a block into a semi-circle.

Let's start with an HTML element `<div class="mouth"></div>` inside the head. We'll style it as a white block, and position in the center of the head just like we did with the in Step 3.

```css
.mouth {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  background: white;
  width: 30px;
  height: 30px;
}
```

### Use Clippy to create your mouth shape

[Clippy](https://bennettfeely.com/clippy/) is an awesome tool for creating clip-path code easily. Visit the site, select the circle option from the right, and drag the element around to create the semi circle shape you want.

The code it generates should look a bit like:

`clip-path: circle(50% at 50% 0);`

Feel free to choose another shape for the mouth and play around with Clippy to your heart's content!

Once you're ready, add the `clip-path` property to the CSS for `.mouth`, and adjust the vertical positioning to suit. Here's what I have now:

```css
.mouth {
  position: absolute;
  bottom: -10px;
  left: 50%;
  transform: translateX(-50%);
  background: white;
  width: 30px;
  height: 30px;
  clip-path: circle(50% at 50% 0);
}
```
### Work in progress - end of step 4

You're nearly at the finish line! So far, you should have something like this:

{% codepen https://codepen.io/aitchiss/pen/NWxEOob %}

## Step 5: Add the legs and finish up!

There's no new techniques here, and the code for the legs should look fairly familiar by now. You'll need to create two new HTML elements:

```html
<div class="leg left"></div>
<div class="leg right"></div>
```

Make sure you place these **before** the fluff elements and the rest of the code you created. This makes sure they sit behind everything else.

Each leg is a black rectangle, with a slight border radius to remove any sharp corners:

```css
.leg {
  position: absolute;
  top: 120px;
  height: 50px;
  width: 15px;
  background: black;
  border-radius: 30%;
}
```

We can then use the `left`/`right` classes to position each leg. I've used the same positioning trick we looked at in step 3 to make the legs sit at 30% in from each side, i.e.

```css
.leg.left {
  left: 30%;
  transform: translateX(-30%);
}

.leg.right {
  right: 30%;
  transform: translateX(30%);
}
```

### Tidy up

Now you have all your elements in place, it's time to clean up by removing that pink background we added to the canvas in step 1, and deleting any extra code comments you don't want any more!

## Ta da! 

You should now have a finished sheep, a little bit like this:

{% codepen https://codepen.io/aitchiss/pen/QWyJZPv %}

Congratulations! If this is your first piece of CSS art, seriously - WELL DONE!

### Round up

Let's take a look at what techniques you can now re-use in your CSS art to come:

- Positioning items vertically and horizontally, including with % values
- Using clip-path to make shapes
- Using `::before` and `::after` to save lots of extra HTML elements
- Using CSS variables

Awesome!

Thanks for following along to the end - if you do create a wee sheep through this tutorial I would absolutely **love** to see it! Drop your codepen link in the comments so we can all revel in its glory 😃🐑