Have you heard of the css daily challenge? I had signed up for it a while ago, but never actually took it. Instead, it inspired me to challenge myself to recreate an illustration using only css. It is this challenge I want to share with you in this post.
When I design, I often use freepik.com as my images resource. Therefore it was only natural that I search there for a set of illustrations to create in css. It was a week before my family vacation, and so it was no coincidence that I picked this image:

I started with what seemed to be the simplest object, the glasses. In retrospect and after working on several other objects, I realized that there were simpler objects that I could have started with, such as the suitcase, but the glasses were certainly a nice start. While recreating the illustrations, I had a few guidelines: First of all, I tried to use as few divs as possible and to use pseudo-elements like :before and :after instead. Secondly, I tried to target responsiveness but gave it up along the way: At first I tried using dynamic sizes (usually percentages), however somewhere along the way it got too tedious, and since I had no vision (or need) for resizing, I decided to let go. My work was only for “playing in the sandbox”, so pixels weren’t a dirty word. I was encountering enough challenges as it was, so I preferred concentrating on them rather than creating responsive illustrations. Maybe one day I'll go back and make my illustration responsive.

Challenges encountered ...

The First Challenge - css variables

After easily picking my desired illustration set and starting writing css, it was clear to me that I was going to use this opportunity to experiment with css variables, hence I declare them as my first challenge. In case you’re not familiar with css variables you can read or watch the following interesting lectures:

I don’t think I got even close to utilizing the full power of css variables, but for a first time use it was good enough for me. The illustration I’d picked had only several colors in it, and that suited me perfectly in using variables for color names - it’s so much easier to remember ‘pink’ and ‘dark pink’ rather than their hexadecimal code. It came in the most handy when creating gradients or complex box-shadows, where the color values are sometimes repeated:

:root {
 --very-dark-pink: #b2184e;
 --dark-pink: #ca325b;
 --pink: #e55171;
 --orange: #f68f19;
 --yellow: #fcbb21;
 --dark-blue: #139da7;
background-image: linear-gradient(
 to bottom,
 var(--white) 50%,
 var(--dark-pink) 50%,
 var(--dark-pink) 65%,
 var(--pink) 65%,
 var(--pink) 100%

While writing my scss I found a very handy aspect of css variables - the ability to declare a new value for a variable within a css class. I’ll illustrate with an example: I defined the --size variable under the :root selector, giving it the value of 1px. Now, many of my elements were squares - that is, their width and height were the same. In order to avoid repeating the same value of pixels twice (when defining their width, and when defining their height) and hence needing to make a change in two places if the sizes change, I set the height and width values as --size. So far no news here. However, when a certain element needed a different size (but was still square), I changed the --size variable within that element selector, and the new value applied only to that selector. If none of this makes sense yet, I hope this will surely clarify it:

:root {
--size: 1px;
.lens:before {
 --size: 12px;
 width: var(--size);
 height: var(--size);

The Second Challenge - Shapes

In my day to day work I don’t usually encounter the need to create shapes using scss. Yes, I do often set border-radius: 50%; in order to create a circle (especially for images), or use borders to create different kinds of triangles, but that’s more or less it. In the illustration set, however, there was hardly any illustration that was a simple square. I used the border-radius a lot, sometimes using percentage values and sometimes fixed pixels. In some shapes I defined the same value of border-radius for all of the corners, and in others I defined a different value for each corner. I had totally forgotten how rich border-radius could be - this sent me back in time to three years ago, when I sat, fascinated, watching a youtube video of The Humble Border-Radius by Lea Verou. I strongly recommend watching that video. Even though it’s been a few years, everything there is still relevant (except, perhaps ,for the perifix :-)

I also created many triangles using a CSS triangle generator, and created other shapes as well, such as the trapezoid. I have learned, for example, that a trapezoid can be created either by using triangles - you can read about it here - or by using transform: perspective() rotateX();. You can read the explanation here.

In some complex shapes, like the plane on the pink flight ticket or the globe icon, I ditched css and used inline svg.

The Third Challenge - use as few divs as possible

Why? To be honest, there was no practical reason: I already created something that was obviously inaccessible and lacked any semantic significance, so why should I be ‘div-stingy’? The answer, I think, is that it's inherent in me to refrain from adding html elements that only serve the design and have no semantic meaning. I love using :before and :after anyway, and the challenge in creating as few divs as possible was fun! Some of the divs I had added were necessary because of the capacity of elements I needed to create, and some of the divs were utterly unnecessary, but they solved a z-index problem I encountered. Funny, I'd thought I'd had a fairly good grasp of z-index, but apparently I was wrong. If I fully understood what was going on there, I would have written a nice explanation here, but unfortunately I don’t. Those of you who are interested can read this excellent post about z-index.

Another trick I used to simulate several elements using only one selector, was to define a multiple-box-shadow. Box-shadow gets the width and / or height of the element (depending on where it is shifted to), which means that if, for example, my element is 20 pixels wide and I shift the box-shadow by 20 pixels on the X axis (to the right or to the left), I will get a duplication of the element. Using this method, I created the stripes on the pink ticket.

.flying-ticket:before {
 width: 20px;
 height: 3px;
 color: var(--dark-pink);
 box-shadow: inset 0 4px 0 0, 0 5px 0 0, 
                   20px 5px 0 0, 0 10px 0 0, 
                   20px 10px 0 0, 63px 0px 0 0, 
                   63px 3px 0 0, 63px 6px 0 0, 
                   63px 9px 0 0;

Another way of avoiding adding html elements when creating stripes is to use a linear-gradient. There are two ways to do so: The first is by setting a repetitive gradient (can be seen used in the top of the compass) and the second is by using a background-size setting to define the sizes of each color of the gradient.

/*first option (used to make the vertical lines in the top part of the compass):*/
background-image: repeating-linear-gradient( to left,
                                             transparent, transparent 5px, 
                                             var(--very-dark-blue) 7px, var(--very-dark-blue) 8px);

/*second option (used to make the dashed lines in the airline ticket):*/
 background-image: linear-gradient( to bottom, var(--dark-pink) 50%, transparent 50% );
 background-size: 100% 8px;

External Resources

Throughout my work on the illustrations, I used css generators to create triangles, gradients and more, and I Googled a lot. Many of the solutions were found thanks to questions and answers on StackOverflow (for example, in my quest for a way to create the shine on the lens in the camera, I came across code to create a smile). Various codepens helped me, such as this pen to create a hot-balloon. I obviously always first tried to cope with each challenge on my own, but whenever I exhausted my creativity and succumbed to search, the Internet never disappointed me.

To Summarize

To be honest, there really is no need for all these scss-illustrations. You may raise your eyebrows in wonder and ask - then why did you make them? Well, there are several reasons:

First - I had fun, and it's important to do things for fun!

Second - is was challenging, and I like css challenges.

Third - even though there is no "useful" purpose for what I did, I believe that it’s important to practice css. It’s important for me to experiment and test new properties that are not always used and not necessarily supported in every browser. I enjoyed using css variables, filters, transforms and other features.

Fourth and last - hey, I got a post out of it, so why not? :)

It's really fun to stop for a minute (or rather, for a few hours every day for a few days) and do something for fun, for practice, to challenge the mind with new things. I'm sure it improved my ability to write code. I warmly recommend it to you all :)

If you’re a Hebrew speaker- you can read the whole post here.

I thank Lea Cohen for refining my english in the post.

2,041 0 20