1

I want to create an element with a 3D-like effect: it should appear to recess into the background.

Throughout this question I'm going to be referring to the Z-axis diagrams from https://neumorphism.io.

Most CSS for 'sunken' elements I've seen create a hard boundary between the sunken area and the non-sunken area. For example using an inset box-shadow:

div {
  padding: 1rem;
  width: 10rem;
  box-shadow: inset 0px 3px 10px #bbb;
  background-color: #bbb1;
}
<div>Hello!</div>

Using neumorphism.io's Z-axis diagram, the above would look like this:

diagram

The vertical lines represent a hard visual boundary between the inside and the outside of the element.

By adding a further shadow on the outside of the element, I can smooth the top edges of the Z-axis diagram:

div {
  padding: 1rem;
  width: 10rem;
  box-shadow: inset 0px 3px 10px #bbb, 0px -3px 10px #bbb;
  background-color: #bbb1;
  border-radius: 1rem;
}
<div>Hello!</div>

The above is represented by the following:

smoother diagram

That's not quite what I'm going for, though, because those hard edges are still present (and in fact the element is starting to resemble a 3D object placed onto the page and lit from below rather than a 3D recession).

My ideal element should resemble a lunch tray (image), with the recession creating 3D space for other objects to be in, and would be represented by the following:

very smooth diagram

Is it possible to create an element with this sort of boundary differential in CSS?


I'm well aware of the concerns surrounding the neumorphism style, especially those regarding contrast. In this case that's not a problem - I want to use this style to create a recession for higher-contrast elements to sit in.

snazzybouche
  • 2,241
  • 3
  • 21
  • 51
  • Does any of [these search results](//www.google.com/search?q=css+curved+tab+shape&tbm=isch) help? Possible duplicate of [Is it possible to create the Firefox tab using CSS ?](/q/33376922/4642212). – Sebastian Simon Jun 15 '21 at 23:50
  • Hi @SebastianSimon, no, the results you've linked refer to curves in the X and Y axes. I am discussing curves in the Z axis. – snazzybouche Jun 15 '21 at 23:52

1 Answers1

2

You could utilize the box-shadows on positioned pseudo elements to get close to what I think you're looking for:

* {
  box-sizing: border-box; margin: 0; padding: 0;
}
html, body {
  height: 100%; font-family: Arial;
}
body, div {
  display: flex; justify-content: center; align-items: center;
  background-color: #ddc;
}
body::before, body::after, div {
  content: ''; position: absolute;
  border-radius: 1.5rem;
  width: 5rem; height: 5rem;
  background-color: rgba( 0,0,0,0.25 );
}
div {
  z-index: 1; box-shadow: 0rem 0rem 1rem 1rem #ddc;  
  background-color: #ddc; color: rgba( 0,0,0,0.05 );  
  font-size: 2rem; font-weight: bold;
}
div::after {
  content: 'x'; transform: scaleY( 0.875 );
}
body::before {
  transform: translate( -0.5rem, -0.5rem );
  box-shadow: 0rem 0rem 1rem 0.5rem rgba( 0,0,0,0.5 );
  background-color: rgba( 0,0,0,0.5 );    
}
body::after {
  transform: translate( 0.5rem, 0.5rem );
  box-shadow: 0rem 0rem 1rem 0.5rem #fff; background-color: #fff;    
}
<div></div>

The issue you appear to be having is blurring the edges of the shadow and highlight sections. Making these sections elements themselves and then adding box-shadows directly to them creates a 'feather' effect softening the edges.

You should be able to scale this down to your projects needs.

Lynel Hudson
  • 2,335
  • 1
  • 18
  • 34