cssbox-shadow

How can I make neumorphism-style element shadows using CSS?


I'm trying to recreate Alexander Plyuto's modern skeumorphic style (now called neumorphism) in CSS:

enter image description here

I'm attempting to do this by having a colored shadow on the top and left, and a differently colored shadow on the bottom and right.

I researched MDN for box-shadow and I can see box-shadow supports multiple values, but rather than being top-right-bottom-left like the rest of CSS, multiple values are actually full-size shadows for all sides that are stacked on top of each other:

The z-ordering of multiple box shadows is the same as multiple text shadows (the first specified shadow is on top).

Is it possible to create this effect in CSS?

Note that 'no' is an acceptable answer, but creating additional HTML (ie, not using CSS) is not. Buttons in HTML are normally represented by <button>A button</button>


Solution

  • In short: CSS itself doesn't provide a way to directly set different shadow colors on different sides. However there are ways to achieve a neumorphic look - see below:

    neumorphism.io CSS generator

    There is now an online Neumorphism CSS generator at https://neumorphism.io/

    enter image description here

    @noomorph's answer (provided as a comment when answers were closed)

    Use two shadows (as mentioned), but with the offsets arranged so that one covers the top and left, the other covers bottom and right. As commenters have noted the gradients can overlap. It's likely not possible to copy the demo, as the demo has a wide spread radius but no overlap, which cannot be achieved in CSS as the shadows stack on top of each other.

     
     body {
       background: lightgrey;
     }
     
     button {
       border: none;
       background-color: #efefef;
       color: black;
       font-size: 24px;
       text-transform: uppercase;
       padding: 20px;
       margin: 50px;
       position: relative;
       border-radius: 10px;
       box-shadow:  -2px -2px 8px 4px white, 2px 2px 8px 4px #222;
     } 
     
     
     
     <button>This is a button</button>
     
     

    @disinfor's answer (provided on chat when answers were closed)

    Use a pseudo element, that has a gradient background, and is itself blurred. It's likely not possible to copy the demo here either, as the higher amount of darkness in the start of the gradient means that the blurry shadow isn't uniform:

    body {
      background: lightgrey;
    }
    button {
      border: none;
      background-color: white;
      color: black;
      font-size: 24px;
      text-transform: uppercase;
      padding: 20px;
      margin: 50px;
      position: relative;
      border-radius: 5px;
    } 
    
    button::after {
      content: '';
      z-index: -1;
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: blue;
      background: linear-gradient(350deg, rgba(10,10,10,0.8) 0%, rgba(255,255,255,0.8) 100%);
      filter: blur(10px);
    }
    <button>This is a button</button>