在CSS中经常会用到对一个元素进行变换(Transform)但希望元素的内容保持不变的效果;但当我们对元素进行变换时,得到的效果是:不但背景被变换了,而且内容也被变换了;示例如下:
以skewX()变换为例,假设有以下元素:
HTML结构:
<p>
我是内容
</p>
css样式:
p {
display: inline-block;
border-color: red;
border-width:1px;
border-style: solid;
}
效果:
![](https://img.haomeiwen.com/i3987507/b332691057910e48.png)
如果对这个元素使用skewX()变换,则会得到如下效果:
CSS样式:
transform: skewX(45deg);
效果:
![](https://img.haomeiwen.com/i3987507/fbe4a07c656030d6.png)
从效果中可以看出,不仅元素的背景被变换了,而且里面的内容也被变换了,然而,在很多场景下我们只希望变换背景,内容保持不变;
若要解决这个问题,也有多种方案可选(推荐方案3哟),如下:
方案1:外套元素
原理:
在变换时,为了把背景样式与元素内容分离,可以把目标元素嵌入在一个容器元素内,比如div元素,然后把目标元素的背景样式移动到容器元素上,使容器元素仅负责背景样式(称仅负责样式的元素为样式元素),目标元素仅负责内容;然后对样式元素进行变换,再对目标元素进行反向变换,这样便实现了变换了背景样式,而又还原了内容;
原理演示:
-
给目标元素添加一个容器元素作为样式元素;
** HTML结构:**<div> <p> 我是内容 </p> </div>
-
把目标元素的背景样式移动到容器元素上;
示例效果:
外套元素.png
注意:
虚线框只是用来标识元素的存在,并不表示元素的样式; -
对容器元素应用变换;
CSS样式:transform: skewX(45deg);
示例效果:
外套元素-变换.png
-
对目标元素应用反向变换;
CSS样式:transform: skewX(-45deg);
示例效果:
外套元素-纠正.png
此方案优点:
- 原理直观,易理解;
- 可以实现任意多样式及内容的分离;
- 需要对目标内容再进行反向变换;(有此变换操作是不可逆的,所以反向变换会可能不能还原效果;)
此方案缺点:
- 添加了较多冗余的元素;
方案2:内嵌元素
原理:
与外套元素的方案类似,只是把样式元素插入到了目标元素里面,作为了目标元素的子元素;这样,在对样式元素进行变换时,不会影响到目标元素的内容,从而不用使用反向变换;
原理演示:
-
给目标元素添加一个子元素作为样式元素;
** HTML结构:**<p> <span></span> 我是内容 </p>
-
把目标元素的背景样式移动到样式元素上;
示例效果:
内嵌元素.png
注意:
- 虚线框只是用来标识元素的存在,并不表示元素的样式;
- 如果样式元素遮挡了目标元素的内容,则需要给样式元素设置合适的层叠级别z-index;
-
对样式元素应用变换;
CSS样式:transform: skewX(45deg);
示例效果:
内嵌元素-变换.png
此方案优点:
- 原理直观,易理解;
- 可以实现任意多样式及内容的分离;
- 不用对目标内容再进行反向变换;
此方案缺点:
- 添加了较多冗余的元素;
方案3:前后伪元素
原理:
与内嵌元素方案的原理一样,所不同的是:本方案采用伪元素::before或者::after来作为样式元素,而不是另外插入额外的元素;
原理演示:
以::before伪元素为例:
-
把目标元素的样式应用到其伪元素::before上;
** CSS样式:**p::before { border-color: red; border-width:1px; border-style: solid; }
-
调整::before伪元素的盒子使其与目标元素盒子重叠;
因为在::before和::after伪元素选择器中必须定义content属性,所以需要为::before选择器中设置值为空字符串的content属性;
另外,因为浏览器会为这2个伪元素选择器分别生成相应的盒子,并且这些盒子是作为元素的非主盒子,所以为了不影响主盒子(目标元素的内容)的布局,需要:- 让伪元素脱离正常文档流;
- 让目标元素的主盒子成伪元素盒子的包含块;
所以需要
- 给目标元素设置样式
position: relative;
- 给伪元素::before设置样式:
position: absolute; width: 100%; height: 100%;
最终,示例代码如下:
** HTML结构:**<p> 我是内容 </p>
CSS样式:
p { display: inline-block; position: relative; /*为::before伪元素生成包含*/ } p::before { content: ''; position: absolute; /*脱离文档流*/ width: 100%; height: 100%; /*目标元素的样式*/ border-color: red; border-width:1px; border-style: solid; }
示例效果:
伪元素.png
注意:
- 虚线框只是用来标识元素的存在,并不表示元素的样式;
- 如果样式元素遮挡了目标元素的内容,则需要给样式元素设置合适的层叠级别z-index;
-
对::before伪元素应用变换;
CSS样式:transform: skewX(45deg);
示例效果:
伪元素-变换.png
此方案优点:
- 原理直观,易理解;
- 不用对目标内容再进行反向变换;
- 不用添加冗余元素;
此方案缺点:
- 只能把样式及内容分离成2个独立的部分,不对分成3个或者更多的独立部分;
相关文章:《 CSS中特殊效果的实现方案》
网友评论