Search code examples
htmlcsscss-animationsbox-shadow

How to rotate box shadow around a text?


I'm studying HTML/CSS and I found a very interesting example of rotating box shadows. I thought I'd try to use it, but I can't get my head around rotating the shadows around my text.

The example I found has a like <div class="rotate-shadows"></div> and CSS like this:

body {
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}
.rotate-shadows {
  width: 220px;
  height: 220px;
  position: relative;
}
.rotate-shadows:after,
.rotate-shadows:before {
  content: "";
  border-radius: 50%;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  transform-origin: center center;
}
.rotate-shadows:before {
  box-shadow: inset 0 20px 0 rgba(0, 250, 250, 0.6), inset 20px 0 0 rgba(0, 200, 200, 0.6), inset 0 -20px 0 rgba(0, 150, 200, 0.6), inset -20px 0 0 rgba(0, 200, 250, 0.6);
  animation: rotate-before 2s -0.5s linear infinite;
}
.rotate-shadows:after {
  box-shadow: inset 0 20px 0 rgba(250, 250, 0, 0.6), inset 20px 0 0 rgba(250, 200, 0, 0.6), inset 0 -20px 0 rgba(250, 150, 0, 0.6), inset -20px 0 0 rgba(250, 100, 0, 0.6);
  animation: rotate-after 2s -0.5s linear infinite;
}
@keyframes rotate-after {
  0% {transform: rotateZ(0deg) scaleX(1) scaleY(1);}
  50% {transform: rotateZ(180deg) scaleX(0.82) scaleY(0.95);}
  100% {transform: rotateZ(360deg) scaleX(1) scaleY(1);}
}
@keyframes rotate-before {
  0% {transform: rotateZ(0deg) scaleX(1) scaleY(1);}
  50% {transform: rotateZ(-180deg) scaleX(0.95) scaleY(0.85);}
  100% {transform: rotateZ(-360deg) scaleX(1) scaleY(1);}
}
<div class="rotate-shadows"></div>

I figured out that I don't need body {}, figured out where I can change the color of the shadows, scale, etc. But I can't get which part is responsible for the shape of the shadows.

Can I make the shadows go around my text like an animated frame:

Классная шляпная шляпа с широкими полями всего за два куська. Да-да! Это не опечатка! Всего два динозаврических укуса и шляпа ваша!

Where do I need to put my text to have shadows rotating around it? And how can I change the shape of shadows?

I just want to understand.


Solution

  • If I understood your requirement correctly is this what you need?

    I added an extra div inside to wrap the text if that is not an issue? this div acts based on the parent's position. making it in the middle.

    body {
      margin: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      position: relative;
    }
    
    .rotate-shadows {
      width: 220px;
      height: 220px;
      position: relative;
    }
    
    #text {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      justify-content: center;
      align-items: center;
    }
    
    .rotate-shadows:after,
    .rotate-shadows:before {
      content: "";
      border-radius: 50%;
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      transform-origin: center center;
    }
    
    .rotate-shadows:before {
      box-shadow: inset 0 20px 0 rgba(0, 250, 250, 0.6), inset 20px 0 0 rgba(0, 200, 200, 0.6), inset 0 -20px 0 rgba(0, 150, 200, 0.6), inset -20px 0 0 rgba(0, 200, 250, 0.6);
      animation: rotate-before 2s -0.5s linear infinite;
    }
    
    .rotate-shadows:after {
      box-shadow: inset 0 20px 0 rgba(250, 250, 0, 0.6), inset 20px 0 0 rgba(250, 200, 0, 0.6), inset 0 -20px 0 rgba(250, 150, 0, 0.6), inset -20px 0 0 rgba(250, 100, 0, 0.6);
      animation: rotate-after 2s -0.5s linear infinite;
    }
    
    @keyframes rotate-after {
      0% {
        transform: rotateZ(0deg) scaleX(1) scaleY(1);
      }
      50% {
        transform: rotateZ(180deg) scaleX(0.82) scaleY(0.95);
      }
      100% {
        transform: rotateZ(360deg) scaleX(1) scaleY(1);
      }
    }
    
    @keyframes rotate-before {
      0% {
        transform: rotateZ(0deg) scaleX(1) scaleY(1);
      }
      50% {
        transform: rotateZ(-180deg) scaleX(0.95) scaleY(0.85);
      }
      100% {
        transform: rotateZ(-360deg) scaleX(1) scaleY(1);
      }
    }
    <div class="rotate-shadows">
      <div id="text">
        Once upon a time in Stackoverflow!!
      </div>
    </div>

    If you need the content in the single Div then:

    body {
      height: 100vh;
    }
    
    .rotate-shadows {
      width: 220px;
      height: 220px;
      position: absolute;
      transform: translate(-50%, -50%);
      justify-content: center;
      align-items: center;
      display: flex;
      text-align: center;
      vertical-align: middle;
      top: 50%;
      left: 50%;
    }
    
    .rotate-shadows:after,
    .rotate-shadows:before {
      content: "";
      border-radius: 50%;
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      transform-origin: center center;
    }
    
    .rotate-shadows:before {
      box-shadow: inset 0 20px 0 rgba(0, 250, 250, 0.6), inset 20px 0 0 rgba(0, 200, 200, 0.6), inset 0 -20px 0 rgba(0, 150, 200, 0.6), inset -20px 0 0 rgba(0, 200, 250, 0.6);
      animation: rotate-before 2s -0.5s linear infinite;
    }
    
    .rotate-shadows:after {
      box-shadow: inset 0 20px 0 rgba(250, 250, 0, 0.6), inset 20px 0 0 rgba(250, 200, 0, 0.6), inset 0 -20px 0 rgba(250, 150, 0, 0.6), inset -20px 0 0 rgba(250, 100, 0, 0.6);
      animation: rotate-after 2s -0.5s linear infinite;
    }
    
    @keyframes rotate-after {
      0% {
        transform: rotateZ(0deg) scaleX(1) scaleY(1);
      }
      50% {
        transform: rotateZ(180deg) scaleX(0.82) scaleY(0.95);
      }
      100% {
        transform: rotateZ(360deg) scaleX(1) scaleY(1);
      }
    }
    
    @keyframes rotate-before {
      0% {
        transform: rotateZ(0deg) scaleX(1) scaleY(1);
      }
      50% {
        transform: rotateZ(-180deg) scaleX(0.95) scaleY(0.85);
      }
      100% {
        transform: rotateZ(-360deg) scaleX(1) scaleY(1);
      }
    }
    <div class="rotate-shadows"> Once upon a time in Stackoverflow!!
    </div>