旋转时保持盒子阴影方向一致
Keep box-shadow direction consistent while rotating
当给例如<div>
盒子阴影以及旋转它都会导致盒子阴影方向的旋转 - 当盒子阴影应该产生照明幻觉时这是有问题的。
示例:https://jsfiddle.net/5h7z4swk/
div {
width: 50px;
height: 50px;
margin: 20px;
box-shadow: 10px 10px 10px #000;
display: inline-block;
}
#box1 {
background-color: #b00;
}
#box2 {
background-color: #0b0;
transform: rotate(30deg);
}
#box3 {
background-color: #00b;
transform: rotate(60deg);
}
#box4 {
background-color: #b0b;
transform: rotate(90deg);
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#box6 {
background-color: #0bb;
animation-name: spin;
animation-duration: 2s;
animation-iteration-count: infinite;
}
<div id="box1"></div>
<div id="box2"></div>
<div id="box3"></div>
<div id="box4"></div>
<div id="box6"></div>
这个问题的答案应该类似于这个模型:
我怎样才能旋转 <div>
并且仍然保持盒子阴影的方向相同?
溶液应该是纯的CSS...
注意:CSS中的动画用于演示目的。用例将使用 JavaScript 来设置旋转。但是 JavaScript 对盒子阴影一无所知,因为设计有责任定义一个(或许多...)阴影。这就是为什么它应该是一个纯粹的 CSS 解决方案。
在旋转期间保持偏移框阴影的方向一致 使用 CSS 变换很简单。
这种方法依赖于 transform origin 随转换一起移动的事实。这意味着当在同一个元素上设置多个变换时,每个变换的坐标系都会根据之前的坐标系发生变化。
在下面的例子中,蓝色元素是伪元素,阴影是div元素:
div {
width: 40px; height: 40px;
margin: 40px;
box-shadow: 0px 0px 10px 5px #000;
animation: spinShadow 2s infinite;
background-color: #000;
}
@keyframes spinShadow {
to { transform: rotate(360deg); }
}
div:before {
content: '';
position: absolute;
left:-5px; top:-5px;
width: 50px; height: 50px;
transform: rotate(0deg) translate(-10px, -10px) rotate(0deg);
animation:inherit;
animation-name: spinElt;
background-color: #0bb;
}
@keyframes spinElt {
to { transform: rotate(-360deg) translate(-10px, -10px) rotate(360deg); }
}
<div></div>
对伪元素的转换 属性 的解释(有关步骤的说明,请参阅以下代码片段):
transform: rotate(-360deg) translate(-10px, -10px) rotate(360deg)
rotate(-360deg)
反父元素旋转使伪元素静态
translate(-10px, -10px)
伪元素平移使阴影偏移
rotate(360deg)
伪元素旋转方向与父元素相同
div {
width: 40px; height: 40px;
margin: 40px;
box-shadow: 0px 0px 10px 5px #000;
animation: spinShadow 2s infinite;
background-color: #000;
}
@keyframes spinShadow {
to { transform: rotate(360deg); }
}
div:before {
content: '';
position: absolute;
left:-5px; top:-5px;
width: 50px; height: 50px;
animation:inherit;
background-color: #0bb;
}
#first:before{
transform: rotate(0deg);
animation-name: first;
}
@keyframes first {
to { transform: rotate(-360deg); }
}
#second:before{
transform: rotate(0deg) translate(-10px, -10px);
animation-name: second;
}
@keyframes second {
to { transform: rotate(-360deg) translate(-10px, -10px); }
}
#complete:before{
transform: rotate(0deg) translate(-10px, -10px) rotate(0deg);
animation-name: complete;
}
@keyframes complete {
to { transform: rotate(-360deg) translate(-10px, -10px) rotate(360deg); }
}
<ol>
<li>Counter rotate:<div id="first"></div></li>
<li>Translate :<div id="second"></div></li>
<li>Rotate:<div id="complete"></div></li>
<ol>
你也可以在动画帧中整合盒子阴影方向:
div {
display: inline-block;
margin: 1em ;
height: 50px;
width: 50px;
box-shadow: 15px 15px 15px 5px gray;
animation: rte 5s infinite linear;
}
.red {
background: red
}
.green {
background: green;
animation-delay:2s;
}
.blue {
background: blue;
animation-delay:4s;
}
.bob {
background: #b0b;
animation-delay:6s;
}
.cyan {
background: cyan;
animation-delay:8s;
}
@keyframes rte {
25% {
box-shadow: 15px -15px 15px 5px gray;
}
50% {
box-shadow: -15px -15px 15px 5px gray;
}
75% {
box-shadow: -15px 15px 15px 5px gray;
}
100% {
transform: rotate(360deg);
}
}
<div class="red"></div>
<div class="green"></div>
<div class="blue"></div>
<div class="bob"></div>
<div class="cyan"></div>
受其他答案的启发,我也创建了自己的答案:
https://jsfiddle.net/zoxgbcrg/1/
.shadow {
background-color: black !important;
width: 40px;
height: 40px;
box-shadow: 0px 0px 10px 5px #000;
margin-top: 35px;
margin-left: 35px;
position: absolute;
z-index: -1;
}
<div class="box1 shadow"></div><div class="box1"></div>
技巧还在于创建一个额外的 <div>
来处理阴影。在我的例子中,它不是 :before
,而是一个由 margin
移动的真实 DOM 元素。
注意:似乎今天 (31.01.2016) Firefox 和 Chrome 有细微的渲染差异。所以对于 Firefox https://jsfiddle.net/zoxgbcrg/ 正在创建所需的结果,对于 Chrome 我建议 https://jsfiddle.net/zoxgbcrg/1/
当给例如<div>
盒子阴影以及旋转它都会导致盒子阴影方向的旋转 - 当盒子阴影应该产生照明幻觉时这是有问题的。
示例:https://jsfiddle.net/5h7z4swk/
div {
width: 50px;
height: 50px;
margin: 20px;
box-shadow: 10px 10px 10px #000;
display: inline-block;
}
#box1 {
background-color: #b00;
}
#box2 {
background-color: #0b0;
transform: rotate(30deg);
}
#box3 {
background-color: #00b;
transform: rotate(60deg);
}
#box4 {
background-color: #b0b;
transform: rotate(90deg);
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#box6 {
background-color: #0bb;
animation-name: spin;
animation-duration: 2s;
animation-iteration-count: infinite;
}
<div id="box1"></div>
<div id="box2"></div>
<div id="box3"></div>
<div id="box4"></div>
<div id="box6"></div>
这个问题的答案应该类似于这个模型:
我怎样才能旋转 <div>
并且仍然保持盒子阴影的方向相同?
溶液应该是纯的CSS...
注意:CSS中的动画用于演示目的。用例将使用 JavaScript 来设置旋转。但是 JavaScript 对盒子阴影一无所知,因为设计有责任定义一个(或许多...)阴影。这就是为什么它应该是一个纯粹的 CSS 解决方案。
在旋转期间保持偏移框阴影的方向一致 使用 CSS 变换很简单。
这种方法依赖于 transform origin 随转换一起移动的事实。这意味着当在同一个元素上设置多个变换时,每个变换的坐标系都会根据之前的坐标系发生变化。
在下面的例子中,蓝色元素是伪元素,阴影是div元素:
div {
width: 40px; height: 40px;
margin: 40px;
box-shadow: 0px 0px 10px 5px #000;
animation: spinShadow 2s infinite;
background-color: #000;
}
@keyframes spinShadow {
to { transform: rotate(360deg); }
}
div:before {
content: '';
position: absolute;
left:-5px; top:-5px;
width: 50px; height: 50px;
transform: rotate(0deg) translate(-10px, -10px) rotate(0deg);
animation:inherit;
animation-name: spinElt;
background-color: #0bb;
}
@keyframes spinElt {
to { transform: rotate(-360deg) translate(-10px, -10px) rotate(360deg); }
}
<div></div>
对伪元素的转换 属性 的解释(有关步骤的说明,请参阅以下代码片段):
transform: rotate(-360deg) translate(-10px, -10px) rotate(360deg)
rotate(-360deg)
反父元素旋转使伪元素静态translate(-10px, -10px)
伪元素平移使阴影偏移rotate(360deg)
伪元素旋转方向与父元素相同
div {
width: 40px; height: 40px;
margin: 40px;
box-shadow: 0px 0px 10px 5px #000;
animation: spinShadow 2s infinite;
background-color: #000;
}
@keyframes spinShadow {
to { transform: rotate(360deg); }
}
div:before {
content: '';
position: absolute;
left:-5px; top:-5px;
width: 50px; height: 50px;
animation:inherit;
background-color: #0bb;
}
#first:before{
transform: rotate(0deg);
animation-name: first;
}
@keyframes first {
to { transform: rotate(-360deg); }
}
#second:before{
transform: rotate(0deg) translate(-10px, -10px);
animation-name: second;
}
@keyframes second {
to { transform: rotate(-360deg) translate(-10px, -10px); }
}
#complete:before{
transform: rotate(0deg) translate(-10px, -10px) rotate(0deg);
animation-name: complete;
}
@keyframes complete {
to { transform: rotate(-360deg) translate(-10px, -10px) rotate(360deg); }
}
<ol>
<li>Counter rotate:<div id="first"></div></li>
<li>Translate :<div id="second"></div></li>
<li>Rotate:<div id="complete"></div></li>
<ol>
你也可以在动画帧中整合盒子阴影方向:
div {
display: inline-block;
margin: 1em ;
height: 50px;
width: 50px;
box-shadow: 15px 15px 15px 5px gray;
animation: rte 5s infinite linear;
}
.red {
background: red
}
.green {
background: green;
animation-delay:2s;
}
.blue {
background: blue;
animation-delay:4s;
}
.bob {
background: #b0b;
animation-delay:6s;
}
.cyan {
background: cyan;
animation-delay:8s;
}
@keyframes rte {
25% {
box-shadow: 15px -15px 15px 5px gray;
}
50% {
box-shadow: -15px -15px 15px 5px gray;
}
75% {
box-shadow: -15px 15px 15px 5px gray;
}
100% {
transform: rotate(360deg);
}
}
<div class="red"></div>
<div class="green"></div>
<div class="blue"></div>
<div class="bob"></div>
<div class="cyan"></div>
受其他答案的启发,我也创建了自己的答案: https://jsfiddle.net/zoxgbcrg/1/
.shadow {
background-color: black !important;
width: 40px;
height: 40px;
box-shadow: 0px 0px 10px 5px #000;
margin-top: 35px;
margin-left: 35px;
position: absolute;
z-index: -1;
}
<div class="box1 shadow"></div><div class="box1"></div>
技巧还在于创建一个额外的 <div>
来处理阴影。在我的例子中,它不是 :before
,而是一个由 margin
移动的真实 DOM 元素。
注意:似乎今天 (31.01.2016) Firefox 和 Chrome 有细微的渲染差异。所以对于 Firefox https://jsfiddle.net/zoxgbcrg/ 正在创建所需的结果,对于 Chrome 我建议 https://jsfiddle.net/zoxgbcrg/1/