标题几乎说明了一切,但这是一个示例。
假设我有一个CSS“加载微调器”,如下所示:
.spinner { height: 50px; width: 50px; position: relative; animation: rotate .6s infinite linear; border-left: 6px solid #222; border-right: 6px solid #222; border-bottom: 6px solid #222;; border-top: 6px solid #ccc; border-radius: 100%; } @keyframes rotation { from { transform: rotate(0deg); } to { transform: rotate(359deg); } }
我想为此添加一个伪元素-例如,content: 'loading...'在before或after之后.spinner。
content: 'loading...'
.spinner
是否可以确保伪元素不会继承动画.spinner,或者伪元素必须 始终 采用父元素所拥有的动画?
由于伪元素是父元素的子元素,因此只要父元素具有动画,它将继续旋转。即使animation: none在伪元素上进行设置也无效。
animation: none
使其看起来好像孩子没有动画的唯一方法是反转效果,如下面的代码片段所示。正在执行的操作是将完全相同的动画添加到伪元素,但是将animation- direction设置为reverse。这意味着伪对象将获得精确的反向变换效果,因此将其保留在相同位置。
animation- direction
reverse
.spinner { height: 50px; width: 50px; position: relative; animation: rotation .6s infinite linear; border-left: 6px solid #222; border-right: 6px solid #222; border-bottom: 6px solid #222; border-top: 6px solid #ccc; border-radius: 100%; } .spinner:after { position: absolute; content: 'Loading..'; top: 0px; left: 0px; height: 100%; width: 100%; animation: rotation .6s infinite linear reverse; /* added this line */ } @keyframes rotation { from { transform: rotate(0deg); } to { transform: rotate(359deg); } } <div class='spinner'></div>
上面的代码段使用的默认设置transform-origin是,50% 50%但如果子伪元素具有padding和/或margin则transform- origin必须相应地调整该设置,以避免伪元素产生类似发抖的效果。下面的代码段提供了计算逻辑。
transform-origin
50% 50%
padding
margin
transform- origin
.spinner { height: 50px; width: 50px; position: relative; animation: rotation .6s infinite linear; border-left: 6px solid #222; border-right: 6px solid #222; border-bottom: 6px solid #222; border-top: 6px solid #ccc; border-radius: 100%; } .spinner.parent-padded-margin { padding: 10px; margin: 10px; } .spinner:after { position: absolute; content: 'Loading..'; top: 0px; left: 0px; height: 100%; width: 100%; animation: rotation .6s infinite linear reverse; /* added this line */ } .spinner.child-padded-margin:after { padding: 10px 8px; margin: 5px 4px; transform-origin: calc(50% - 12px) calc(50% - 15px); /* calc(50% - ((padding-left + padding-right)/2 + margin-left)) calc(50% - ((padding-top + padding-bottom)/2 + margin-top)) */ } .spinner.child-padded-margin-2:after { padding: 10px 6px 16px 14px; margin: 7px 12px 5px 10px; transform-origin: calc(50% - 20px) calc(50% - 20px); /* calc(50% - ((padding-left + padding-right)/2 + margin-left)) calc(50% - ((padding-top + padding-bottom)/2 + margin-top)) */ } @keyframes rotation { from { transform: rotate(0deg); } to { transform: rotate(359deg); } } <div class='spinner'></div> <div class='spinner parent-padded-margin'></div> <div class='spinner child-padded-margin'></div> <div class='spinner child-padded-margin-2'></div>
定位所述伪元件(使用top,left,bottom,right)也具有影响动画。transform- origin为了使动画正常工作,还需要对其进行相应的修改。以下代码段提供了一个示例。
top
left
bottom
right
.spinner { height: 50px; width: 50px; position: relative; animation: rotation .6s infinite linear; border-left: 6px solid #222; border-right: 6px solid #222; border-bottom: 6px solid #222; border-top: 6px solid #ccc; border-radius: 100%; } .spinner.parent-padded-margin { padding: 10px; margin: 10px; } .spinner:after { position: absolute; content: 'Loading..'; height: 100%; width: 100%; animation: rotation .6s infinite linear reverse; /* added this line */ } .spinner.child-positioned{ margin-bottom: 40px; } .spinner.child-positioned:after { top: 120%; left: 2%; transform-origin: calc(50% - 2%) calc(50% - 120%); /* basically need to subtract the distance from the left and top of the container */ } .spinner.child-positioned-negative:after { bottom: -120%; right: -2%; transform-origin: calc(50% - 2%) calc(50% - 120%); /* basically need to subtract the distance from the left and top of the container */ } @keyframes rotation { from { transform: rotate(0deg); } to { transform: rotate(359deg); } } <div class='spinner child-positioned'></div> <div class='spinner child-positioned-negative'></div>
注意: 以上两种解决方案在最新版本的Chrome,Opera和Safari中都可以正常工作,但会导致文本在IE 11,Edge和Firefox中显示倾斜。Firefox似乎需要一个单独的动画,该动画从FF的rotate(-10deg)变为旋转(-370deg),而在IE中变得更加复杂。
没有在伪(子)元素上设置反向动画的唯一替代 方法是利用Chris 在其评论中 提到 的 方法 。这将意味着直接将边框和动画设置为伪元素。这将意味着父级的内容不会受到影响,因为父级不会受到子级转换的影响。
.spinner { height: 50px; width: 50px; position: relative; } .spinner:after { position: absolute; content: ''; top: 0px; left: 0px; height: 100%; width: 100%; animation: rotation .6s infinite linear; border-left: 6px solid #222; border-right: 6px solid #222; border-bottom: 6px solid #222; border-top: 6px solid #ccc; border-radius: 100%; } @keyframes rotation { from { transform: rotate(0deg); } to { transform: rotate(359deg); } } <div class='spinner'>Loading...</div>