πŸ“œ ⬆️ ⬇️

The magic of one div. Masterclass from the creator of a.singlediv.com

Why single div?

In May 2013, I attended CSSConf and heard Lia Vera talking about taming the border-radius property. It was instructive and allowed me to understand something about CSS that I did not understand before. It reminded me of the times when I studied the fine arts, when I was constantly striving to improve my professional level. My level of CSS can be called average, so I challenged myself to find out everything I could by researching and experimenting with properties.

But why exactly one div?
')
When I learned to draw, my class did an exercise in which we received colors by mixing the three main ones: red, yellow, and blue. The purpose of this lesson was to study the behavior of materials and an understanding of the strength of the combination. Of course, you can buy green paint, but you can also get it by mixing blue and yellow colors. The greater number of available solutions to the problem forces us to reconsider our usual solutions.

I decided to launch the a.singlediv.com project, where I intended to post something new every few days, created with CSS. I set a limit on using only one DIV.

Tools

It may seem that the use of only one element and the properties supported by browsers is too limited a tool. But this is not the case, unless you limit yourself to their basic purpose.

Pseudo-elements

One DIV in HTML allows you to work with three elements, thanks to the use of pseudo-elements. So with div, div: before, and div: after, we can get something like this:

image


div { background: red; } div:before { background: yellow; } div:after { background: blue; } 


For simplicity, you can think of these elements as three layers. It looks like this:

image


Forms

With CSS and one element we got three basic forms. We can use the width and height properties to create squares / rectangles, as well as border-radius to create circles / ellipses, and the border to create triangles / trapezoids.

image


There are other forms that we can create using CSS, but most things can be simplified to some combination of basic forms. In this form, complex forms are much easier to manage.

The multiplicity of the form

With multiple box-shadows, we can create multiple versions of the same shape, in a particular size, color, or use blur. Using the x and y axes gives us almost infinite variations.

image


 div { box-shadow: 170px 0 10px yellow, 330px 0 0 -20px blue, 330px 5px 5px -20px black; } 


We can use box-shadows for box-shadows. Pay attention to the order of the announcement. The image of the layers is also appropriate here.

Gradients

Gradients can be used to add shading and depth, meaning the light source. This makes simple, flat shapes more realistic. The background-images property allows you to use several kinds of gradient to get a more complex element.

image


 div { background-image : linear-gradient (to right, gray, white, gray, black), } div :after { background-image : radial-gradient (circle, yellow 50%, transparent 50%), linear-gradient (to right, blue, red), } 


Visualization

The most difficult part is the visualization of how to put all these parts together, into a recognizable drawing. This part of the process is crucial. To help me in this, I often look at a photograph of an object, and mentally divide it into components, all forms and all colors. I break the big picture into smaller shapes or color blocks that I can create with CSS.

Example

Let's take a closer look at the two figures and select some of the parts that make up large objects.

First, take a green pencil:

A pencil consists of two basic shapes: a rectangular body and a triangular tip.

image


I had to implement the following things in order to achieve realism:

multi-colored wrapper;
graphics and words on the wrapper;
illusion of roundness;
Glossiness, which emphasizes the shape and imitates the influence of the light source.

So, first I created the main body of the pencil:

image


Notice, I use a mix of black (a) and white (a) instead of RGBA

 div { background : #237449, background-image : linear-gradient (to bottom, transparent 62%, black (.3) 100%), box-shadow : 2px 2px 3px black (.3), } 


Then I added a linear gradient at both ends to create a wrapper. It has an alpha value of 0.6, so the bottom fill looks slightly out.

image


 div { background-image : linear-gradient (to right, transparent 12px, rgba (41, 237, 133, .6) 12px, rgba (41, 237, 133, .6) 235px, transparent 235px), } 


Next, I used the same gradient technique to create stripes on a pencil.

image


 div { background-image : linear-gradient (to right, transparent 25px, black (.6) 25px, black (.6) 30px, transparent 30px, transparent 35px, black (.6) 35px, black (.6) 40px, transparent 40px, transparent 210px, black (.6) 210px, black (.6) 215px, transparent 215px, transparent 220px, black (.6) 220px, black (.6) 225px, transparent 225px), } 

And for drawing an ellipse a radial gradient works great!

image

 div { background-image: radial-gradient(ellipse at top, black(.6) 50px, transparent 54px); } 


I split the code to demonstrate each element, but keep in mind: the image will actually look like this:
 div { //  background-image: radial-gradient(ellipse at top, black(.6) 50px, transparent 54px), //  linear-gradient(to right, transparent 25px, black(.6) 25px, black(.6) 30px, transparent 30px, transparent 35px, black(.6) 35px, black(.6) 40px, transparent 40px, transparent 210px, black(.6) 210px, black(.6) 215px, transparent 215px, transparent 220px, black(.6) 220px, black(.6) 225px, transparent 225px), //  linear-gradient(to right, transparent 12px, rgba(41,237,133,.6) 12px, rgba(41,237,133,.6) 235px, transparent 235px), //  linear-gradient(to bottom, transparent 62%, black(.3) 100%) } 


So after completing the div, I used the before pseudo-element to create a three-sided tip. Using the properties solid and transparent, I created a triangle and placed it next to the div

image


 div :before { height : 10px, border-right : 48px solid #237449, border-bottom : 13px solid transparent, border-top : 13px solid transparent, } 

It looks a bit flat, but it will be fixed by the after pseudo-element. At the same time, I added a linear gradient to create a shine effect that spans the entire width of the pencil.

image


 div :after { background-image : linear-gradient (to bottom, white (0) 12px, white (.2) 17px, white (.2) 19px, white (0) 24px), } 


As a final touch, I added text using after, and placed it on a pencil:

image


 div :after { content : 'green', font-family : Arial, sans-serif, font-size : 12px, font-weight : bold, color : black (.3), text-align : right, padding-right : 47px, padding-top : 17px, } 


Another example (camera) :

Here is the camera body, created using background-image and border-image.

image


Here is a GIF illustrating some of the elements that will be added using pseudo-elements and box-shadows.

image


 div :before { background : #333, box-shadow : 0 0 0 2px #eee, -1px -1px 1px 3px #333, -95px 6px 0 0 #ccc, 30px 3px 0 12px #ccc, -18px 37px 0 46px #ccc, -96px -6px 0 -6px #555, -96px -9px 0 -6px #ddd, -155px -10px 1px 3px #888, -165px -10px 1px 3px #999, -170px -10px 1px 3px #666, -162px -8px 0 5px #555, 85px -4px 1px -3px #ccc, 79px -4px 1px -3px #888, 82px 1px 0 -4px #555, } 


Next stage:

image


 div :after { background : linear-gradient (45deg, #ccc 40%, #ddd 100%), border-radius : 50%, box-shadow : 0 3px 2px #999, 1px -2px 0 white, -1px -3px 2px #555, 0 0 0 15px #c2c2c2, 0 -2px 0 15px white, -2px -5px 1px 17px #666, 0 10px 10px 15px black (.3), -90px -51px 1px -43px #aaa, -90px -50px 1px -40px #888, -90px -51px 0 -34px #ccc, -90px -50px 0 -30px #aaa, -90px -48px 1px -28px black (.2), -124px -73px 1px -48px #eee, -125px -72px 0 -46px #666, -85px -73px 1px -48px #eee, -86px -72px 0 -46px #666, 42px -82px 1px -48px #eee, 41px -81px 0 -46px #777, 67px -73px 1px -48px #eee, 66px -72px 0 -46px #666, -46px -86px 1px -45px #444, -44px -87px 0 -38px #333, -44px -86px 0 -37px #ccc, -44px -85px 0 -34px #999, 14px -89px 1px -48px #eee, 12px -84px 1px -48px #999, 23px -85px 0 -47px #444, 23px -87px 0 -46px #888, } 


It’s a bit tricky, but as you can see, several box-shadows can add many details to a single element.

Serious challenges

The two biggest obstacles I encountered were the constraints on creating a triangle and the behavior of the gradients.

Problem with triangles

The method of creating triangles limits the possible actions. Adding a gradient using border-image affects all object borders, not just one specific side. Box-shadows applies to the shape of the block, and not to its borders. All this makes it difficult to create several triangles using a single object. Here is an example of what this looks like:

image


  div { border-left : 80px solid transparent, border-right : 80px solid transparent, border-bottom : 80px solid red, } div :before { border-left : 80px solid transparent, border-right : 80px solid transparent, border-bottom : 80px solid red, border-image : linear-gradient (to right, red, blue), } div :after { border-left : 80px solid transparent, border-right : 80px solid transparent, border-bottom : 80px solid red, box-shadow : 5px 5px 5px gray, } 


Gradient stratification

The gradient tends to fill the entire element. This is solved by overlapping several gradients. It will take a little time to think about transparency and Z-index, as well as to understand what will be visible and what is not. But the effective use of this technique will give your drawings a high level of detail.

Here is a drawing in the making process, showing gradients that span the entire width of the container.

image


Using left-to-right and right-to-left gradients, I can hide part of the gradient:

image


As a result, an illusion is created that the object is made of a multitude of elements.

Theory in action

The beautiful thing that became a side effect of this project is an extension for hrome, which is called the CSS Gradient Inspector. It allows you to turn on and off the display of each of the gradients by analogy with the visibility of layers in Photoshop.

Source: https://habr.com/ru/post/251933/


All Articles