CSS Art – How to Make a Game Character – Kirby

Introduction

What’s significant about 2022? It’s Kirby’s 30th anniversary!

In this article, we’ll create this iconic video game character using CSS and SVG. Visit our CSS Art articles if you’re unfamiliar with the below CSS technologies.

Preview

Kirby

Our image will consist of these different parts:

  1. Eyes
  2. Cheek Marks
  3. Mouth
  4. Body
  5. Left and Right Arm
  6. Left and Right Foot

Prerequisites

We don’t assume prior knowledge of CSS or HTML, but it helps if you have some familiarity with how they work. Jump over to this article if you require an HTML and CSS primer.

We assume that you have set up tools to create CSS art. If you haven’t, this article will show you how to set them up.

HTML Structure

Here’s the HTML code for our image.

<div class="container">
  <div class="character">
    <div class="left-arm"></div>
    <div class="right-foot"></div>
    <div class="body"></div>
    <div class="cheek-mark"></div>
    <div class="right-arm"></div>
    <div class="right-eye"></div>
    <div class="left-eye"></div>
    <div class="mouth"></div>
    <div class="left-foot"></div>
  </div>
</div>

container is our outermost enclosure. This enables us to center the art and put a light gray border. The rest of the divs represent each of Kirby’s parts.

It’s important to keep the HTML structure as is for each part to display properly.

Color Palette

Here’s the CSS code for the color palette, body and container div.

/**************************************/
/* Color, Body and Container Settings */
/**************************************/
/* Color palette */
:root {
  /* Transparent */
  --t: transparent;

  /* Body */
  --body-1: hsla(322, 100%, 86%, 1);
  --body-2: hsla(329, 100%, 84%, 1);
  --body-3: hsla(340, 97%, 77%, 1);
  --body-4: hsla(341, 92%, 74%, 1);
  --body-5: hsla(328, 100%, 69%, 1);

  /* Eyes */
  --eye-1: hsla(300, 100%, 100%, 1);
  --eye-2: hsla(224, 78%, 51%, 1);
  --eye-3: hsla(226, 77%, 18%, 1);
  --eye-4: hsla(0, 0%, 0%, 1);

  /* Mouth */
  --mouth-1: hsla(357, 78%, 54%, 1);
  --mouth-2: hsla(353, 98%, 17%, 1);
  --mouth-3: hsla(0, 0%, 100%, 0.08);
  --mouth-4: hsla(356, 78%, 43%, 1);

  /* Feet */
  --feet-1: hsla(347, 97%, 59%, 1);
  --feet-2: hsla(342, 100%, 33%, 1);
  --feet-3: hsla(345, 95%, 29%, 1);
  --feet-4: hsla(347, 97%, 60%, 1);

  /* Shadow */
  --shadow: hsla(240, 0%, 26%, 0.5);
}

/* Center shapes */
body {
  margin: 0;
  padding: 0;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
}

/* Set container and optional light gray border */
.container {
  width: 500px;
  height: 500px;
  /*   border: 5px solid lightgray; */
  background: transparent;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 1px;
}

If you haven’t created a color palette before, you can check this article for an in-depth explanation.

Let’s start with Kirby’s right eye.

Right Eye

Right Eye

CSS Code:

.right-eye {
  position: absolute;
  width: 45px;
  height: 106px;
  top: 81px;
  left: 261.5px;
  background: var(--eye-4);
  border-radius: 50%;
  transform: rotate(-5deg);
}

This shape will be the base of Kirby’s right eye. It’s a vertically elongated ellipse. We give it a slight slant angle with transform: rotate(-5deg);.

Next, let’s make the gradient.

Right Eye - Gradient

CSS Code:

.right-eye::before {
  content: "";
  position: absolute;
  width: 32px;
  height: 67px;
  top: 34px;
  left: 6px;
  background: linear-gradient(to top, var(--eye-2) 10%, var(--eye-3) 30%);
  border-radius: 50%;
}

We use linear-gradient() function to create the gradient. It transitions from a light blue, var(--eye-2), to a navy-blue color, var(--eye-3). We’re using CSS custom properties (variables) to set our colors.

Check this article for a step-by-step tutorial on how to set up your own color palette with CSS variables.

Let’s finish our right eye in the following section.

Right Eye - Pupil

CSS Code:

.right-eye::after {
  content: "";
  position: absolute;
  width: inherit;
  height: inherit;
  background: /* Pupil - White */ radial-gradient(
        100% 100% at 50% 50%,
        var(--eye-1) 49%,
        var(--t) 50%
      )
      50% 11% / 24px 37px,
    /* Iris - Light Blue */
      radial-gradient(100% 100% at 50% 50%, var(--eye-2) 49%, var(--t) 50%) 50%
      7% / 31px 44px,
    /* Base Color */
      radial-gradient(100% 100% at 50% 50%, var(--eye-4) 49%, var(--t) 50%) 50%
      58% / 35px 45px;
  background-repeat: no-repeat;
  filter: blur(0.5px);
  border-radius: 50%;
}

Let’s break down our background code.

We’re using multiple radial-gradients() to simulate both Iris and Pupil shape.

We’re creating three ellipses:

  • Base color
  • Iris
  • Pupil

Take note that the placement of each radial-gradient() code is important. The first radial-gradient() will show on top, the last gradient will show at the very bottom of the shape stack.

Make sure you put background-repeat: no-repeat; after the radial-gradient() code, this ensures that background doesn’t repeat.

1. Base color

Right Eye - Iris Base

CSS Code:

/* Base Color */
radial-gradient(
	100% 100% at 50% 50%, 
	var(--eye-4) 49%, 
	var(--t) 50%
	) 
	50% 58% / 35px 45px;

This is our base color. It covers a portion of the gradient we made in the previous section. We use a black shade with a transparent outer layer to make the ellipse shape.

2. Iris – Light Blue

Right Eye - Iris

CSS Code:

/* Iris - Light Blue */
radial-gradient(
	100% 100% at 50% 50%, 
	var(--eye-2) 49%, 
	var(--t) 50%
	) 
	50% 7% / 31px 44px,

On top of the base color, we place the Iris shape. It’s a light blue ellipse.

3. Pupil – White

Right Eye - Pupil

CSS Code:

/* Pupil - White */ 
radial-gradient(
	100% 100% at 50% 50%, 
	var(--eye-1) 49%, 
	var(--t) 50%
	) 
	50% 11% / 24px 37px,

We put the Pupil shape, a white ellipse on top of the Iris, completing our right eye.

Before we proceed to create the Left Eye, let’s take a short detour. Let’s learn how to control the size and placement of multiple radial gradients.

Controlling Gradient Size and Placement

First, let’s look at a straightforward radial-gradient() code.

Syntax:

background: radial-gradient(shape size at position, start-color, ..., last-color); 

Sample code:

radial-gradient(
    circle at 50% 50%, 
	red 0% 50%, 
	orange 50% 100% 
  );

Let’s compare our sample code with the Pupil code.

/* Pupil - White */ 
radial-gradient(
	100% 100% at 50% 50%, 
	var(--eye-1) 49%, 
	var(--t) 50%
	) 
	50% 11% / 24px 37px,

We used this syntax:

radial-gradient(
	100% 100% at x-in-bounding-box y-in-bounding-box, 
	start color, 
	last color
	) 
	x-position y-position / width height

We modify the x-position and y-position to control the placement of the shape. The width and height lets you control the size of the shape.

Play around with the position, width and height argument values, see how the shape changes. For an in-depth explanation, check this article.

Ok, let’s move on to the Left Eye.

Left Eye

The Left Eye is almost a mirror image of the Right Eye; hence, we won’t provide an in-depth explanation for this section.

Left Eye - Base

CSS Code:

.left-eye {
  position: absolute;
  width: 44px;
  height: 102px;
  top: 88px;
  left: 176px;
  background: var(--eye-4);
  border-radius: 50%;
  background-repeat: no-repeat;
  transform: rotate(0deg);
}
Left Eye - Gradient

CSS Code:

.left-eye::before {
  content: "";
  position: absolute;
  width: 32px;
  height: 67px;
  top: 31px;
  left: 5px;
  background: linear-gradient(to top, var(--eye-2) 10%, var(--eye-3) 30%);
  border-radius: 50%;
  transform: rotate(-3deg);
}
Left Eye - Iris and Pupil

CSS Code:

.left-eye::after {
  content: "";
  position: absolute;
  width: inherit;
  height: inherit;
  background: /* Pupil - White */ radial-gradient(
        100% 100% at 50% 50%,
        var(--eye-1) 49%,
        var(--t) 50%
      )
      50% 11% / 24px 37px,
    /* Iris - Light Blue */
      radial-gradient(100% 100% at 50% 50%, var(--eye-2) 49%, var(--t) 50%) 50%
      7% / 31px 44px,
    /* Base Color */
      radial-gradient(100% 100% at 50% 50%, var(--eye-4) 49%, var(--t) 50%) 50%
      58% / 39px 45px;
  background-repeat: no-repeat;
  filter: blur(0.5px);
  border-radius: 50%;
}

Next up is our pink Cheek Marks.

Cheek Marks

Cheek Mark - Left

CSS Code:

.cheek-mark {
  position: absolute;
  width: 54px;
  height: 41px;
  top: 175px;
  left: 109px;
  background: var(--body-5);
  border-radius: 50%;
  filter: blur(2px);
  box-shadow: 217px -10px 2px 0 var(--body-5);
}

We use filter: blur(2px); to give our cheek marks a blur effect. For more information about blur() check this article.

Cheek Mark - Right

CSS Code:

box-shadow: 217px -10px 2px 0 var(--body-5);

Right cheek mark is created with box-shadow. Very handy tool when creating shapes of the same size and color.

In the next section, we’ll create Kirby’s mouth using SVG and radial-gradient().


Pyxofy Membership Sign Up

Mouth

Mouth

CSS Code:

.mouth {
  position: absolute;
  width: 62px;
  height: 53px;
  top: 193px;
  left: 214px;
  background: var(--mouth-2);
  clip-path: path(
    "M 32,1 C 57,2 70,12 50,39 C 48,41 34,60 17,44 C -12,15 3,2 32,1"
  );
}

We use CSS path() and SVG commands to create the mouth shape. Check this article for more details about path() and SVG commands.

Tongue

Tongue

CSS Code:

.mouth::after {
  content: "";
  position: absolute;
  width: 62px;
  height: 53px;
  background: 
     /* Tongue */ radial-gradient(
      100% 100% at 50% 50%,
      var(--mouth-4),
      var(--mouth-1) 49%,
      var(--t) 50%
    )
    50% 93% / 61px 30px;
  background-repeat: no-repeat;
  transform: rotate(-2deg);
  filter: blur(0.5px);
}

Our radial-gradient() fades from wine red, var(--mouth-4), to a light red hue, var(--mouth-1).

We give it a slight blur effect with filter: blur(0.5px);.

Body

Body

CSS Code:

.body {
  position: absolute;
  width: 365px;
  height: 358px;
  top: 25px;
  left: 64px;
  background: radial-gradient(
      100% 100% at 50% 50%,
      var(--body-1) 25%,
      var(--body-2),
      var(--body-4) 49%,
      var(--t) 50%
    )
    80% 83% / 355px 358px;
  background-repeat: no-repeat;
  filter: drop-shadow(2px 15px 5px var(--shadow));
}

We use gradient and drop-shadow() to give Kirby’s body a more rounded shape.

Gradient transitions from a light pink shade, var(--body-1) and var(--body-2) to a more dark pink, var(--body-4).

We set the shadow with filter: drop-shadow(2px 15px 5px var(--shadow));.

Check this article to learn the difference between box-shadow and drop-shadow().

Let’s work on Kirby’s arms in the next sections.

Left Arm

Left Arm

CSS Code:

.left-arm {
  position: absolute;
  width: 140px;
  height: 110px;
  top: 154px;
  left: 17px;
  background: radial-gradient(
    at 20% 30%,
    var(--body-2) 5%,
    var(--body-3),
    var(--body-5)
  );
  border-radius: 50%;
  transform: rotate(-32deg);
}

Similar to the body, we use a light pink to dark pink gradient. To point the arm slightly downwards, we use transform: rotate(-32deg);.

Right Arm

Right Arm

CSS Code:

.right-arm {
  position: absolute;
  width: 125px;
  height: 135px;
  top: 87px;
  left: 356px;
  background: radial-gradient(
    at 50% 30%,
    var(--body-1) 5%,
    var(--body-2),
    var(--body-4) 60%
  );
  border-radius: 50%;
  filter: drop-shadow(0px 5px 10px var(--shadow));
}

The right arm is a simple circle. To give it a more 3D effect, we use gradients.

This code, at 50% 30%, controls the radial gradient starting point. X-axis or vertical axis is 50% and Y-axis or horizontal axis is 30%. Modify the percentages to see how the gradient starting position changes.

With filter: drop-shadow(0px 5px 10px var(--shadow));, we give the right arm a slight drop shadow.

We’re finished with the arms. Let’s move to the foot section.

Right Foot

Right Foot

CSS Code:

.right-foot {
  position: absolute;
  width: 153px;
  height: 234px;
  top: 240px;
  left: 251px;
  background: radial-gradient(
    circle at 50% 75%,
    var(--feet-1) 10%,
    var(--feet-2) 50%
  );
  border-radius: 50%;
  background-repeat: no-repeat;
  transform: rotate(12deg);
}

Using gradients, we give the right foot’s simple ellipse shape a more rounded shape.

Similar to the right arm, we set the gradient starting position. Instead of the default ellipse gradient shape, we set the gradient to a circle shape and position it with this code, circle at 50% 75%.

Left Foot

This is our last section. Compared to the right foot, the left foot is slightly more complex, consisting of a base gradient, shadow, and a highlight.

1. Base Gradient

Left Foot - Base Gradient

CSS Code:

.left-foot {
  position: absolute;
  width: 213px;
  height: 151px;
  top: 252px;
  left: 40px;
  background: radial-gradient(at 45% 50%, var(--feet-2), var(--feet-1));
  border-radius: 50%;
  transform: rotate(41deg);
  filter: drop-shadow(2px -1px 5px var(--shadow));
}

This is our base gradient.

We fade dark red to light red. We give it a drop shadow to push it slightly away from the body section.

2. Base Shadow

Left Foot - Base Shadow

CSS Code:

.left-foot::before {
  content: "";
  position: absolute;
  width: 213px;
  height: 151px;
  background: 
 /* Highlight */ radial-gradient(
        100% 100% at 50% 50%,
        var(--feet-4) 49%,
        var(--t) 50%
      )
      27% 21% / 80px 25px,
    /* Base Shadow */
      radial-gradient(100% 100% at 50% 50%, var(--feet-3) 49%, var(--t) 50%) 55%
      80% / 185px 96px;
  background-repeat: no-repeat;
  border-radius: 50%;
  filter: blur(10px);
}

We create the base shadow with this code

/* Base Shadow */
radial-gradient(
	100% 100% at 50% 50%, 
	var(--feet-3) 49%, 
	var(--t) 50%
	) 55% 80% / 185px 96px;

We can change the base shadow size and position by modifying 55% 80% / 185px 96px. Furthermore, we give it a 10px blur effect with filter: blur(10px);.

3. Highlight

Left Foot - Highlight

CSS Code:

/* Highlight */ 
radial-gradient(
      100% 100% at 50% 50%,
      var(--feet-4) 49%,
      var(--t) 50%
     )
     27% 21% / 80px 25px,

The last part is the highlight.

Instead of using a white color, we use a lighter shade of red. Change the position and size of the highlight by modifying 27% 21% / 80px 25px.

We’re all done! How’s your version of Kirby? Does it look like the reference image?

You can see and play with the code at Pyxofy’s CodePen page.

See the Pen CSS Art - Kirby by Pyxofy (@pyxofy) on CodePen.

Conclusion

By combining basic shapes such as ellipses and circles, we created an iconic video game character.

We used CSS blur() to give our shapes softer tones. We learned how to use multiple radial gradients to make complex shapes.

Box shadow, drop shadow, radial and linear gradients gives our basic shapes a more 3D feel.

What will you create using the techniques you learned from this article? Share your awesome art with us on Twitter @pyxofy, on LinkedIn, or Facebook.

We hope you liked this article. Kindly share it with your network. We really appreciate it.

CSS Art - How to Make a Game Character - Super Mario
A plumber jumping in and out of pipes, throwing fireballs while rescuing a princess. Step-by-step article to create a world renowned game character.
CSS Art – How to Make a Game Character – Bowser (King Koopa)
Large golden horns, spiky turtle back and a fiery breath. Let’s make Super Mario’s famous nemesis in this article, step-by-step.
CSS Art – How to Make a Space Shuttle – Orbiter
Space shuttle orbiters are amazing machines. Can we make it with CSS? You bet! Join us making it step-by-step.
CSS Art
Articles for creating CSS Art.
スクラッチプログラミング - くるまをうんてんするゲームのつくりかた
車(くるま)をうごかして駐車場(ちゅうしゃじょう)にとめるゲームをつくってみましょう。やじるしキーで車(くるま)を操作(そうさ)して、失敗(しっぱい)しても、くりかえしやりなおせるようにプログラミングします。