• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar
  • Skip to footer

The Coding Couple

Pair programming is a lifetime commitment.

  • Home
  • Categories
    • Arduino
    • JavaScript
    • Python
    • Raspberry Pi
  • About Us
    • Privacy Policy
  • Contact

CSS Magic with a Single Div

May 19, 2021 by Ashley

In this tutorial, you’ll learn the basic building blocks of single div drawing with CSS, putting them all together at the end to draw a lollipop.

Single Div Lollipop Drawing

The goal of this blog post is to introduce you to the world of single div drawing. Hopefully by the time you reach the end of it, you will be motivated to express your artistic creativity using CSS as your medium.

I didn’t know single div drawing was a thing until about two years ago when I came across a tweet from @lynnandtonic. It took me to this codepen she wrote and I was impressed. Then I realized she created the animated drawing using pure CSS. No JavaScript and the only HTML element on the page was a div with no content! This was both a humbling and a mind-blowing experience.

I made a mental note to give this a try, and here I am two years later with something to finally share.

I will walk you through how I created my first single div drawing: a lollipop.

However, before I jump into the steps I took to create the lollipop, there are several basics to single div drawing I want to cover first.

The Basics of Single Div Drawing

At it’s core, single div drawing is just drawing in layers. Many, many layers for the more complex and intricate drawings.

There are three main techniques commonly used for building up the layers in a single div drawing.

::before and ::after pseudo-elements

Selectors have a ::before pseudo-element that inserts content before the selector’s content, and an ::after pseudo-element that appends content after the selector’s content. By default, the pseudo-elements are added inline.

Here’s a simple example of how that works with a paragraph element:

<p>Some fancy quote</p>

And this corresponding CSS:

p::before {
    content: open-quote;
}

p::after {
    content: '!';
}

The p::before pseudo-element is going to add an open quote before the paragraph’s content, and the p::after will append an exclamation point after the paragraph’s content.

The final result will look like this:

"Some fancy quote!

::before and ::after example in Codepen.

In the context of single div drawing, the ::before and ::after pseudo-elements give us two additional elements to draw with. It’s like a 3 for 1 deal.

Let’s visualize this with 3 basic squares starting with the single div below:

<div>div</div>

The div is styled as a basic red square. The div::before is styled as a green square with an offset, and finally the div::after is styled as a blue square with an offset from the div::before so we can see how everything overlaps.

div {
  background: red;
  color: white;
  box-sizing: border-box;
  padding: 5px;
  height: 100px;
  width: 100px;
  position: relative;
  margin-top: 50px;
}

div::before {
  content: 'div::before';
  position: absolute;
  background: green;
  color: white;
  box-sizing: border-box;
  padding: 5px;
  height: 100px;
  width: 100px;
  top: 25px;
  left: 25px;
}

div::after {
  content: 'div::after';
  position: absolute;
  background: blue;
  color: white;
  box-sizing: border-box;
  padding: 5px;
  height: 100px;
  width: 100px;
  top: 55px;
  left: 55px;
}

body {
  display: flex;
  justify-content: center;
}

A couple of notes:

  • You must set the content of the pseudo-elements or there is nothing to draw. If you don’t want to display text, and empty string will suffice.
  • By default, the pseudo-elements are added as inline elements, so you’ll need to either change the display property or set the position of the element to absolute to change where the element is drawn.

With the CSS above we get the following result:

Pseudo-element example with div
Pseudo-element example with div

The div is the base layer. On top of that the ::before pseudo-element is drawn, and on top of that element the ::after pseudo-element is drawn. This is a really useful technique to employ for single div drawings, as you’ll soon see later in this tutorial.

div::before and div::after example in Codepen.

box-shadow

The next single div drawing technique is leveraging the box-shadow property. I’m sure many of us have used the box-shadow property to add a simple drop shadow to an element so appears to float off the page as seen in the example below.

HTML:

<div></div>

CSS:

div {
  background: red;
  height: 100px;
  width: 100px;
  margin-top: 50px;
  border-radius: 50%;
  box-shadow: 5px 5px 10px dimgray;
}

body {
  display: flex;
  justify-content: center;
}

Result:

Basic box-shadow example
Basic box-shadow example

But, don’t let the typical use case for the box-shadow limit the possibilities of your imagination. You can manipulate the box-shadow of an element to create multiple variations of the original element.

Say you want three circles of differing colors, just add more box-shadows.

CSS:

div {
  background: red;
  height: 100px;
  width: 100px;
  margin-top: 50px;
  border-radius: 50%;
  box-shadow: 5px 5px 10px gray, 
              0px 110px gold, 
              5px 115px 10px gray, 
              0px 220px limegreen,
              5px 225px 10px gray;
}

Result:

box-shadow example with multiple shadows
box-shadow example with multiple shadows

Multiple box-shadow example in Codepen.

You can pile up box-shadows to create some fun pixel art, too!

CSS:

div {
  background: darkslategray;
  height: 50px;
  width: 50px;
  margin-top: 50px;
  margin-right: 50px;
  box-shadow: 100px 0px darkslategray, 
              0px 150px darkslategray, 
              50px 150px darkslategray, 
              100px 150px darkslategray,
              -50px 100px darkslategray, 
              150px 100px darkslategray;
}

Result:

box-shadow pixel art example
box-shadow pixel art example

Multiple box-shadows as pixel art example on Codepen.

Gradients

The final technique I will cover is using gradients with the background-image property. Like box-shadow, you can layer multiple gradients.

The most commonly used gradients are the radial-gradient and the linear-gradient. Additional gradients include the conical-gradient, the repeating-radial-gradient, repeating-linear-gradient and repeating-conical-gradient.

Paired with the background-image property, you can set the size and the position of your gradient using the background-size and background-position properties.

In the following example, I used three linear gradients to create three squares within a single div.

HTML:

<div></div>

CSS:

div {
  height: 500px;
  width: 500px;
  margin-top: 50px;
  background-image: 
     linear-gradient(white, red, darkred), 
     linear-gradient(orangered, orange, yellow, orangered), 
     linear-gradient(darkgreen, white, green);
  background-size: 
     100px 100px, 
     100px 100px, 
     100px 100px;
  background-position: 
     25% 0%, 
     50% 0%, 
     75% 0%;
  background-repeat: no-repeat;
}

body {
  display: flex;
  justify-content: center;
}

A few notes:

  • The first gradient in the list, is the topmost gradient. You can think of it as the gradient with the highest z-order index.
  • The background-size and background-position items correspond to the order of gradients in the background-image property

With the CSS above we get the following result:

Multiple linear gradients example
Multiple linear gradients example

Multiple gradients example on Codepen.

Putting it all together

Now that I’ve covered the basics, let’s draw a lollipop.

It’s helpful to break down the object you plan on drawing into basic shapes. In the case of the lollipop, we have three:

  • a circle for the candy
  • a rectangle for the candy stick
  • for a Dum Dum style lollipop, another rectangle for the band around the candy

Step 1: Create the basic shapes of the lollipop

With the three basic shapes in mind, the first thing we’ll do is draw them. Since we only have three shapes to draw, most of our work is cut out for us if we use the ::before and ::after pseudo-elements.

HTML:

<div></div>

CSS:

body {
  background: limegreen;
  display: flex;
  justify-content: center;
}

div {
  height: 100px;
  width: 100px;
  border-radius: 50%;
  margin-top: 5%;
  position: relative;
  background: red;
}

div::before {
  height: 250px;
  width: 12px;
  content: '';
  position: absolute;
  top: 100px;
  left: 44px;
  background: white;
}

div::after {
  height: 16px;
  width: 104px;
  content: '';
  position: absolute;
  background: red;
  top: 42px;
  left: -2px;
  background: red;
}

The div draws the circle for candy. The ::before pseudo-element draws the rectangle for the candy stick, and the ::after pseudo-element draws the rectangle for the band around the candy.

Result:

Basic lollipop shape
Basic lollipop shape

While our result does look like a lollipop, it also looks pretty bland.

Step 2: Add some dimensions

We can make our lollipop look more realistic with the use of gradients.

Start with adding a radial gradient to the circle for the lollipop. By default, the origin of the radial gradient puts it in the middle of the circle. That looks a little off for our lollipop, so use the farthest-corner at setting to adjust the position of the origin.

Updated CSS:

div {
  height: 100px;
  width: 100px;
  border-radius: 50%;
  margin-top: 5%;
  position: relative;
  background-image: radial-gradient(farthest-corner at 35px 25px, white, red, darkred);
}

Lollipop with the radial gradient:

Lollipop with radial gradient added
Lollipop with radial gradient added

Let’s not stop here. Add a linear gradient to the rectangle for the lollipop stick, and one for the rectangle representing the band around the lollipop.

CSS with more gradients:

div::before {
  height: 250px;
  width: 12px;
  content: '';
  position: absolute;
  top: 100px;
  left: 44px;
  background-image: linear-gradient(90deg, lightgray, white 25%, darkgray);
}

div::after {
  height: 16px;
  width: 104px;
  content: '';
  position: absolute;
  background: red;
  top: 42px;
  left: -2px;
  background-image: linear-gradient(darkred, white 2%, transparent 15%, transparent 90%, darkred),
  linear-gradient(90deg, red, white 15%, red 50%, darkred);
}

Result with additional gradients:

Lollipop with linear gradients added
Lollipop with linear gradients added

In this example, two linear gradients were used for the the rectangle on the lollipop. One that goes from top to bottom and another that goes from left the right. With the use of two, we’re able to capture a more realistic lighting effect for the lollipop.

Step 3: Add some final touches

The last thing we’ll add to our lollipop is a drop shadow so it pops a little off the lime background.

Final CSS:

body {
  background: limegreen;
  display: flex;
  justify-content: center;
}

div {
  height: 100px;
  width: 100px;
  border-radius: 50%;
  margin-top: 5%;
  position: relative;
  box-shadow: 5px 5px 15px darkslategray;
  background-image: radial-gradient(farthest-corner at 35px 25px, white, red, darkred);
}

div::before {
  height: 250px;
  width: 12px;
  content: '';
  position: absolute;
  top: 100px;
  left: 44px;
  box-shadow: 5px 5px 15px darkslategray;
  background-image: linear-gradient(90deg, lightgray, white 25%, darkgray);
}

div::after {
  height: 16px;
  width: 104px;
  content: '';
  position: absolute;
  background: red;
  top: 42px;
  left: -2px;
  background-image: linear-gradient(darkred, white 2%, transparent 15%, transparent 90%, darkred),
  linear-gradient(90deg, red, white 15%, red 50%, darkred);
}

Final Result:

Single Div CSS Lollipop Drawing
Single Div CSS Lollipop Drawing

And there you have it, we’ve made our first single div drawing. Lollipop example on Codepen.

Additional Single Div Drawing Resources

  • https://a.singlediv.com/
  • https://hacks.mozilla.org/2014/09/single-div-drawings-with-css/
  • https://www.educative.io/edpresso/3-secrets-behind-single-div-css-art

Let’s be friends!

  • Instagram: @thecodingcouple
  • Twitter: @thecodingcouple
  • GitHub: @thecodingcouple
  • Other Blog Posts

Related Posts

  • Pokéball Single DIV CSS Drawing | TutorialPokéball Single DIV CSS Drawing | Tutorial
  • Pokémon Color Picker | A web app built with HTML/CSS + JavaScriptPokémon Color Picker | A web app built with HTML/CSS + JavaScript
  • Trijam #261 Game Jam Diary: One Wrong MoveTrijam #261 Game Jam Diary: One Wrong Move
  • Snow Globe Single DIV CSS Drawing with Animating Snowflakes | TutorialSnow Globe Single DIV CSS Drawing with Animating Snowflakes | Tutorial
  • Surviving the Hackathon:  Angular Attack 2016Surviving the Hackathon: Angular Attack 2016
  • Creation Crate Month 1: An Arduino powered Mood LampCreation Crate Month 1: An Arduino powered Mood Lamp

Filed Under: HTML and CSS, Programming Languages Tagged With: html, single div, single div drawing

Previous Post: « Southeastern Technical Conferences (2020 Edition)
Next Post: Snow Globe Single DIV CSS Drawing with Animating Snowflakes | Tutorial »

Primary Sidebar

Social Media

  • GitHub
  • Instagram
  • Twitter
  • YouTube

Recent Posts

  • Pokémon Color Picker | A web app built with HTML/CSS + JavaScript
  • Pokéball Single DIV CSS Drawing | Tutorial
  • Error: [🍍]: “getActivePinia()” was called but there was no active Pinia
  • Trijam #261 Game Jam Diary: One Wrong Move
  • Using WSL on Corporate VPN

Recent Comments

  • Lizzy on Creation Crate Month 2: An Arduino Powered Memory Game
  • Ashley Grenon on Creation Crate Month 2: An Arduino Powered Memory Game
  • Lizzy on Creation Crate Month 2: An Arduino Powered Memory Game
  • kelly on Creation Crate Month 2: An Arduino Powered Memory Game
  • Ashley on Creation Crate Month 3: An Arduino Powered Distance Detector

Follow us on Instagram!

This error message is only visible to WordPress admins

Error: No feed found.

Please go to the Instagram Feed settings page to create a feed.

Categories

  • Arduino
  • Conferences
  • Debugging
  • Game Jams
  • HTML and CSS
  • JavaScript
  • Programming Languages
  • Python
  • Raspberry Pi
  • Today I Learned

Archives

  • May 2024
  • April 2024
  • March 2024
  • May 2022
  • December 2021
  • May 2021
  • March 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • June 2019
  • April 2019
  • September 2017
  • April 2017
  • August 2016
  • July 2016
  • June 2016
  • May 2016
  • April 2016
  • March 2016
  • April 2015
  • January 2015

Tags

adafruit arduino brackets c# code smell codestock coding standards conventions creation crate debugging developer devspace electronics es6 es2015 game development game jam gotcha hackathon hoisting html html5 javascript led naming conventions nintendo phaser pluralsight pokemon programmer python raspberry pi retro retropie scope self improvement single div single div drawing subscription box TIL today I learned troubleshooting vue vuejs windbg

Footer

About Us

We are the Coding Couple.  Two people who met in college and decided they wanted to pair program for the rest of their ...

Read More »

Most Recent Posts

Pokémon Color Picker | A web app built with HTML/CSS + JavaScript

Pokéball Single DIV CSS Drawing | Tutorial

Error: [🍍]: “getActivePinia()” was called but there was no active Pinia

Trijam #261 Game Jam Diary: One Wrong Move

Social Media

  • GitHub
  • Instagram
  • Twitter
  • YouTube

Copyright Notice

© The Coding Couple, 2015 – 2023. Excerpts and links may be used, provided that full and clear credit is given to The Coding Couple with appropriate and specific direction to the original content.

Copyright © 2025 · Foodie Pro Theme by Shay Bocks · Built on the Genesis Framework · Powered by WordPress