4lackof 4lackof - 3 months ago 7
CSS Question

Creating a "flat long shadow" for box in CSS with less CSS

I currently have the following "flat long shadow" (I've removed 3/4s of the code so as to not crash stackoverflow - in my text-editor, with each shadow its own line, it comes to about 600 lines of code) which I created based on Matt Lambert's tutorial.



body {
background-color: #ddd;
}
div {
min-height: 64px;
width: 64px;
text-align: center;
background-color: cyan;
border: 1px solid blue;
box-shadow: #8c8c8c 1px 1px, #8c8c8c 2px 2px, #8c8c8c 3px 3px, #8c8c8c 4px 4px, #8c8c8c 5px 5px, #8c8c8c 6px 6px, #8c8c8c 7px 7px, #8c8c8c 8px 8px, #8c8c8c 9px 9px, #8c8c8c 10px 10px, #8c8c8c 11px 11px, #8c8c8c 12px 12px, #8c8c8c 13px 13px, #8c8c8c 14px 14px, #8c8c8c 15px 15px, #8c8c8c 16px 16px, #8c8c8c 17px 17px, #8c8c8c 18px 18px, #8c8c8c 19px 19px, #8c8c8c 20px 20px, #8c8c8c 21px 21px, #8c8c8c 22px 22px, #8c8c8c 23px 23px, #8c8c8c 24px 24px, #8c8c8c 25px 25px, #8c8c8c 26px 26px, #8c8c8c 27px 27px, #8c8c8c 28px 28px, #8c8c8c 29px 29px, #8c8c8c 30px 30px, #8c8c8c 31px 31px, #8c8c8c 32px 32px, #8c8c8c 33px 33px, #8c8c8c 34px 34px, #8c8c8c 35px 35px, #8c8c8c 36px 36px, #8c8c8c 37px 37px, #8c8c8c 38px 38px, #8c8c8c 39px 39px, #8c8c8c 40px 40px, #8c8c8c 41px 41px, #8c8c8c 42px 42px, #8c8c8c 43px 43px, #8c8c8c 44px 44px, #8c8c8c 45px 45px, #8c8c8c 46px 46px, #8c8c8c 47px 47px, #8c8c8c 48px 48px, #8c8c8c 49px 49px, #8c8c8c 50px 50px, #8c8c8c 51px 51px, #8c8c8c 52px 52px, #8c8c8c 53px 53px, #8c8c8c 54px 54px, #8c8c8c 55px 55px, #8c8c8c 56px 56px, #8c8c8c 57px 57px, #8c8c8c 58px 58px, #8c8c8c 59px 59px, #8c8c8c 60px 60px, #8c8c8c 61px 61px, #8c8c8c 62px 62px, #8c8c8c 63px 63px, #8c8c8c 64px 64px, #8c8c8c 65px 65px, #8c8c8c 66px 66px, #8c8c8c 67px 67px, #8c8c8c 68px 68px, #8c8c8c 69px 69px, #8c8c8c 70px 70px, #8c8c8c 71px 71px, #8c8c8c 72px 72px, #8c8c8c 73px 73px, #8c8c8c 74px 74px, #8c8c8c 75px 75px, #8c8c8c 76px 76px, #8c8c8c 77px 77px, #8c8c8c 78px 78px, #8c8c8c 79px 79px, #8c8c8c 80px 80px, #8c8c8c 81px 81px, #8c8c8c 82px 82px, #8c8c8c 83px 83px, #8c8c8c 84px 84px, #8c8c8c 85px 85px, #8c8c8c 86px 86px, #8c8c8c 87px 87px, #8c8c8c 88px 88px, #8c8c8c 89px 89px, #8c8c8c 90px 90px, #8c8c8c 91px 91px, #8c8c8c 92px 92px, #8c8c8c 93px 93px, #8c8c8c 94px 94px, #8c8c8c 95px 95px, #8c8c8c 96px 96px, #8c8c8c 97px 97px, #8c8c8c 98px 98px, #8c8c8c 99px 99px, #8c8c8c 100px 100px, #8c8c8c 101px 101px, #8c8c8c 102px 102px;
}

<div>
wow that's a lot of CSS!
</div>





I want to include this in my site but am disheartened at the length of code it takes up (it doesn't work for me to use graphics in this case).

I've researched ways of writing less code but have not found a way with just plain CSS - AKA no SASS, etc.

Here's one of the things I've found - not very hopeful:


Your example above is pretty much the only way to do it with pure CSS, and while it does look pretty crazy - it will let you adjust those text-shadows using transitions and such. - @Lost Left Stack


I wanted to ask the stackoverflow community once again if there is a more compact way to do this.

Answer

You can use 2 pseudos with skew to simulate the same shadow

div {
  min-height: 64px;
  width: 64px;
  text-align: center;
  background-color: cyan;
  border: 1px solid blue;
  position: relative;
}

div:before, div:after {
  content: "";
  position: absolute;
  top: -1px;   /* compensate border in the root element */ 
  left: -1px;
  right: -1px;
  bottom: -1px;
  z-index: -1;
  transform-origin: right bottom;
}

div:before {
  transform: skewX(45deg);
  box-shadow: 1px 60px 0px 0px gray, 1px 120px 0px 0px lightgray;  /* 1px in x direction to avoid small gap between shadows */
}

div:after {
  transform: skewY(45deg);
  box-shadow: 60px 0px gray, 120px 0px lightgray;
}
<div>
  wow that's a lot of CSS!
</div>

one advantage of this method is that you can modyfing easily the angle of the shadow

body {
  background-color: #ddd;
}
div {
  min-height: 64px;
  width: 64px;
  text-align: center;
  background-color: cyan;
  border: 1px solid blue;
  position: relative;
}

div:before, div:after {
  content: "";
  position: absolute;
  top: -1px;   /* compensate border in the root element */ 
  left: -1px;
  right: -1px;
  bottom: -1px;
  z-index: -1;
  transform-origin: right bottom;
}

div:before {
  transform: skewX(60deg);
  box-shadow: 1px 34px 0px 0px gray;  /* 1px in x direction to avoid small gap between shadows */
}

div:after {
  transform: skewY(30deg);
  box-shadow: 60px 0px gray;
}
<div>
  wow that's a lot of CSS!
</div>

To achieve longer shadows, you can increase the pseudos size:

div {
  min-height: 64px;
  width: 64px;
  text-align: center;
  background-color: cyan;
  border: 1px solid blue;
  position: relative;
}

div:before, div:after {
  content: "";
  position: absolute;
  right: -1px;
  bottom: -1px;
  z-index: -1;
  transform-origin: right bottom;
}

div:before {
  height: 200px; /* increased height */
  left: -1px;
  transform: skewX(45deg);
  box-shadow: 1px 200px 0px 0px gray;  /* 1px in x direction to avoid small gap between shadows */
}

div:after {
  width: 200px;  /* increased width */
  top: -1px;
  transform: skewY(45deg);
  box-shadow: 200px 0px gray;
}
<div>
  wow that's a lot of CSS!
</div>

Comments