-4

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>

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
  • 1
    an element with a gradient and a blur filter maybe? – Temani Afif Nov 20 '19 at 15:47
  • Sorry I should state explicitly: without using hacks, ie a single element should only be needed to draw a box. – mikemaccana Nov 20 '19 at 15:48
  • 7
    Seems overly broad and verging on `"write my code for me". – Paulie_D Nov 20 '19 at 15:49
  • 2
    related (probably duplicate): https://stackoverflow.com/q/49620419/8620333 .. a single element is enough to use gradient and filter together – Temani Afif Nov 20 '19 at 15:49
  • @Paulie_D the question is asking about a specific technical problem. I've edited the question title to make it as specific as the question body though. Please remove your downvote if you think that fixes the issue or tell me what else I can do. – mikemaccana Nov 20 '19 at 15:50
  • @symlink Using two shadows on one element is already mentioned in the question. – mikemaccana Nov 20 '19 at 15:51
  • 1
    @symlink he's trying to avoid the overlap of the two shadows. – disinfor Nov 20 '19 at 15:51
  • 1
    the background itself use a gradient – Mister Jojo Nov 20 '19 at 15:52
  • 2
    My first instinct when I need some more control of shadows is usually to use pseudo-element(s). – matthew-e-brown Nov 20 '19 at 15:58
  • And implying that people aren't reading your question reading will also not help you and again: only one person voted to close as duplicate – Temani Afif Nov 20 '19 at 15:58
  • Also, perhaps [this question](https://stackoverflow.com/questions/11997032/how-to-get-box-shadow-on-left-right-sides-only), in which the user wants to get shadows on *only* the sides, can help you figure out how to get different shadows on different sides? Seems like you can do it with just a whooole lotta box-shadows masking each other out. – matthew-e-brown Nov 20 '19 at 16:02
  • 1
    may be with css `::before` / `::after` ? – Mister Jojo Nov 20 '19 at 16:03
  • 1
    You might try negative spreads: `div.two-shadows { width: 100px; height: 100px; box-shadow: 10px 0 5px -3px #008, -10px 0 5px -3px #800; }` (Check out answers in https://stackoverflow.com/questions/5115427/how-can-i-add-a-box-shadow-on-one-side-of-an-element ) – noomorph Nov 20 '19 at 16:05
  • for me to change my vote you must add the css of each shadow, there you ask for a complete css without any trial on your part – Mister Jojo Nov 20 '19 at 16:09
  • @MisterJojo I mentioned in the question that I tried multiple shadows but it doesn't work as they stack rather than being T/R/B/L. Do you still want me to paste my non-working CSS? – mikemaccana Nov 20 '19 at 16:18
  • Thanks @noomorph that looks good - if the question gets reopened I'll mark that as accepted. – mikemaccana Nov 20 '19 at 16:19
  • @MisterJojo What would you do with `::before`? That still wouldn't give me the ability to have a different shadow on one side, but maybe I;m missing something. – mikemaccana Nov 20 '19 at 16:21
  • 1
    Here's a super quick attempt that might help you out, using my good friends, pseudo-elements: https://jsfiddle.net/wmp8fsk7/. – matthew-e-brown Nov 20 '19 at 16:31
  • Thanks @matthew-e-brown - that works! It looks like we can do the same thing using two box shadows on one element, with the trick being to shift the offsets so one is bottom left and the other top right, like noomorph's answer above. Thanks though! – mikemaccana Nov 20 '19 at 16:34
  • as you can see the pseudo elements are the solution. If you had given the css code of your tests, even if they did not work, I would have given you at least a real track for a solution. You should add them now so **matthew-e-brown** can get your reputation. – Mister Jojo Nov 20 '19 at 17:04
  • mister jojo Already added. If the question gets reopened and @matthew-e-brown can add an answer I'll mark it as accepted. If you had answered I would have marked it as accepted too. – mikemaccana Nov 20 '19 at 17:11
  • " but creating additional HTML (ie, not using CSS) is not." what HTML *is* acceptable? You haven't included any in the question. – TylerH Nov 20 '19 at 20:33
  • @TylerH There's a button in the question, so a single button element. `` Not adding wrapper hacks. – mikemaccana Nov 20 '19 at 20:40
  • 2
    @mikemaccana It's probably a good idea to specify your HTML requirements explicitly, as there's not actually a button in the question. I see: a link to dribbble, an embedded image, a link to the MDN page to `box-shadow` and then a quote about `box-shadow`. – TylerH Nov 20 '19 at 20:51
  • @TylerH I have specified my HTML requirements explicitly. I am glad you can see the image. – mikemaccana Nov 21 '19 at 13:53
  • @mikemaccana I don't see any revisions after mine. Where in the question did you specify them, exactly? – TylerH Nov 21 '19 at 14:37
  • @tylerh the HTML requirements are specified in the image. Do you want me to tell other users how to create a button? – mikemaccana Nov 22 '19 at 15:49
  • @TylerH I've added a specification that the button in the image should be represented by a button, in case anyone on stack overflow thinks buttons should be represented by `img` `picture` or `div` tags as you specify, because as you note in your helpful comment, users would have to be telepathic to know that buttons in HTML are represented as buttons. – mikemaccana Nov 22 '19 at 16:13
  • 1
    @TylerH I have seen people make buttons out of other elements. I'm not sure why you'd think otherwise. I'm sure you're aware it's generally considered a poor practice and the normal default for buttons in HTML is to use buttons. However as I've edited my question to meet your requirements, to tell people on Stack Overflow who are already web developers that HTML buttons should be buttons, could we please end this conversation? Thanks. – mikemaccana Nov 22 '19 at 16:26

3 Answers3

0

As I suggested in the comments before this was re-opened, my suggestion is to use pseudo-elements to achieve the double shadow effect. You could probably achieve this with just one, but here's my quick-and-dirty exaple I've whipped up to show it off:

    body {
      background: #424242;
    }

    .button {
      box-sizing: border-box;
      display: flex; /* Just to center vertically */
      align-items: center;
      justify-content: center;
      width: 160px;
      height: 55px;
      border-radius: 1em;
      text-align: center;
      font-family: sans-serif;
      font-weight: 600;
      color: #2b2a2e;
      text-decoration: none;
      background: linear-gradient(48deg, #c4ccd1, #e1e5e8);
      position: relative;
      z-index: initial;
    }

    .button::before, .button::after {
      content: "";
      display: block;
      position: absolute;
      width: 160px;
      height: 35px;
      background: transparent;
      border-radius: 1em;
      z-index: -1;
      opacity: 0.65;
    }

    .button::before {
      top: -1px;
      left: -1px;
      background-color: #fff;
      box-shadow: 0 0 10px 5px #fff;
    }

    .button::after {
      bottom: -1px;
      right: -1px;
      background-color: #b6c7e7;
      box-shadow: 0 0 10px 5px #b6c7e7;
    }
<a href="#" class="button">Request</a>
matthew-e-brown
  • 2,837
  • 1
  • 10
  • 29
0

I got a very close answer to your question. Here is the https://jsfiddle.net/nuakbqe7/1/

<div class="button">
    <p>Request</p>
</div>

Here is the css:

    @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@500&display=swap");

* {
  font-family: "Poppins", sans-serif;
  transition: 0.5s;
}

body {
  background: #e1ebf5;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: 0.5s;
  min-height: 97vh;
}

.button {
  border-radius: 17px;
  cursor: pointer;
  background: #e1ebf5;
  box-shadow: 6px 6px 11px #d2dce6, -6px -6px 11px #edf2f7;
  width: 300px;
  text-align: center;
}

p {
  font-size: 18px;
  color: #202c3d;
  text-shadow: 2px 2px 2px #c3cfde;
}
EndoBotm
  • 1
  • 1
-4

This question was originally closed by a moderator in error. During the time the question was closed, and answers were not allowed, multiple users have contacted me with solutions. As the question has now been reopened, I'm posting their solutions, with credit to them, as as community wiki so I don't get karma.

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>
mikemaccana
  • 110,530
  • 99
  • 389
  • 494