DEV Community

loading...
Cover image for Pure CSS lamp: step-by-step

Pure CSS lamp: step-by-step

poulamic profile image Poulami Chakraborty ・3 min read

I wrote about the basic concepts for CSS art in the first part of the series. In this part, we will create a lamp from scratch.

Before starting, let's break down the objects into the component shapes. Here we have three - the shader, the leg and the foot are the basic parts. So, let's create the markup.

<div class = "lamp">
  <div class = "shade"></div>
  <div class = "leg"></div>
  <div class = "foot"></div>
</div>

Now, we will start with CSS.
First, we will set up the document to take complete span the complete window, and to prevent any scroll. Also we want the lamp to be in the center - we can achieve that with grid and place-items.

Within the lamp, we want the components center-aligned. We can achieve that with flex-box.

body{
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  display: grid;
  place-items: center;
}
.lamp{
  display: flex;
  flex-direction: column;
  align-items: center;
}

Now, let us create the basic shapes for the components

.shade{
  width: 30vh; 
  height: 20vh;
  background: #EEE4CF;
  border: 1px solid black;
}
.leg{
  width: 2vh; 
  height: 50vh;  
  background: #995136;
  border: 1px solid black;
}
.foot{
  width: 22vh; 
  height: 5vh;
  background: #995136;
  border: 1px solid black;
}

This is the result:
Boxes for the elements
(Border used here to show overlaps of the shape in the next step)
I am using vh as the unit for both height & width to make it responsive and preserve aspect ratios.

Now, we will use positioning for minor adjustments - move the leg and the foot a bit higher for perspective. For slight adjustments from an elements default position, we can use relative postioning.

In addition the leg needs to be in the front of the stand - we will change that with z-index. (Note: in simple cases such as this, what appears on top can also be adjusted through markup - the later the element appears, higher it will be in the stacking context. Using it here just as a demo use for more complex cases ).

*{
  position:relative;
}

.shade{
  width: 30vh; 
  height: 20vh;
  background: #EEE4CF;
  border: 1px solid black;

  z-index: 3;
}
.leg{
  width: 2vh; 
  height: 50vh;  
  background: #995136;
  border: 1px solid black;

  top: -2vh; 
  z-index:2;
}
.foot{
  width: 22vh; 
  height: 5vh;
  background: #995136;
  border: 1px solid black;

  top: -4vh; 
}

Result:
Boxes with positioning

Next, we will move to detailing each shape.

For the shade, we want rounded corners and a trapezium - we will create those with border-radius and clip-path.

For a 3d effect, we will use gradients. We can set the gradients on either background or background-image. In cases, where the gradients are used only to show shadows, I prefer to set the primary color as background, and add the shadows with black/white with alpha value in combination with transparent.

Also, as gradients are applied from bottom to top, we need to be conscious of the order.

In case of the shade, we are applying four layers (from bottom to top) - along the right slanted side, along the left slanted side, left to right, ellipse at the top.
Figuring out the opacity and angles for each may be through trial and error.

.shade{
  width: 30vh; 
  height: 20vh;
  background: #EEE4CF;
  z-index: 3;

  border-radius: 50% / 10%;
  clip-path: polygon(20% 0, 80% 0, 100% 100%, 0 100%);
  background-image: 
    radial-gradient(closest-corner at 50% 2%, #EEE4CF 70%, transparent 78%),
    linear-gradient(to right, transparent 48%, #ffffff66 58% 75%, transparent 88%),
     linear-gradient(-253deg, #ffffffcc, #E5CB9A 15%, #DBB97C 20%, #EDDBB7 36%, #ffffff33 54%, transparent 95%),
    linear-gradient(253deg, #F8EFDD 20%, transparent)    
}

Shade styled

Similar for the leg: shadows to create a 3d effect

.leg{
  width: 2vh; 
  height: 50vh;  
  background: #995136;
  top: -2vh; 
  z-index:2;

  background-image: 
    linear-gradient(#00000044, transparent 20% 99.8%, #00000033 100%),
    linear-gradient(to right, transparent 15%, #00000055 36% 44%,  #00000011 60%, #ffffff4f 78% 95%, #9B5539 95%)
}

Alt Text

For the foot, we will use radius to make it an oval, use gradients and shadow to give it dimension.

.foot{
  width: 22vh; 
  height: 5vh;
  background: #995136;  
  top: -4vh; 
  border-radius: 50%;
  box-shadow: 0 0.4vh #773321;

  background-image: 
    linear-gradient(to right, transparent 11vh, transparent 12vh, transparent 13vh),
    linear-gradient( 40deg, transparent 5% 24%, #0000001f 28% 36%, #00000011 37% 44%, transparent 50%, #ffffff1c 56%, #ffffff44 68%, #ffffff1c 92%, transparent)
}

completed

That's it!
You can find the pen here:

Discussion (9)

Collapse
ayabongaqwabi profile image
Ayabonga Qwabi

CSS is witchcraft 😂, At first I thought I could just create this on the fly but now I see I would have struggled to achieve that nice smooth bend on the shade with just the border-radius. Learnt a lot from you today. Please write more.

Collapse
harrisgeo88 profile image
Harris Geo 👨🏻‍💻

really useful article! thanks for sharing

Collapse
poulamic profile image
Poulami Chakraborty Author

Glad you found it useful :)

Collapse
hyftar profile image
Simon Landry

Amazing work! I thought you were done after the first picture and then I realized the picture in the preview wasn't a stock photo but the result. Wow!

Collapse
poulamic profile image
Collapse
valentinaperic profile image
Valentina Peric

AWESOME! loved this.

Collapse
poulamic profile image
Poulami Chakraborty Author

Thanks! I am glad you enjoyed it :)

Collapse
vaibhavkhulbe profile image
Vaibhav Khulbe

Great art and explanation! Waiting for your next art. Keep it up. 😁

Collapse
poulamic profile image
Forem Open with the Forem app