当前位置: 首页 > 科技观察

你可能不知道的CSS负值技巧和细节

时间:2023-03-14 08:52:37 科技观察

写这篇文章的原因是有一天在群里,一位同学说错了,用负值outline-offset来实现加号。嗯?很好奇,我立即尝试了一下。如何使用negativeoutline-offset来实现加号?使用负的outline-offset实现加号假设我们有这样一个简单的结构:

div{width:200px;height:200px;outline:20pxsolid#000;outline-offset:10px;}修改outline-偏移到一个合适的负值,然后在适当的时候,轮廓边框将缩进到一个加号。经过一番尝试,将上述div的outline-offset修改为-118px。div{width:200px;height:200px;outline:20pxsolid#000;outline-offset:-118px;}加个动画效果,大概是这样的:CodePenDemo——用outline实现加号[1]很有意思,我尝试在讨论了很多不同的情况后,最终得出了一个简单的规则。要使用负的outline-offset来生成加号,有一些简单的限制:容器必须是正方形轮廓border本身的宽度不能太小outline-offset负值x取值范围是:-(容器宽度的一半+轮廓宽度的一半)???]]]#}以box-shadow:1px2px3px4px#333为例,四个值的含义分别是x方向的偏移值和y方向的偏移值、BlurRa??dius、Dilation半径。这里有个小技巧,展开半径可以为负。继续,如果阴影的模糊半径与负扩散半径重合,那么我们将看不到任何阴影,因为生成的阴影将包含在原始元素下,除非它被赋予方向偏移。所以这时候,我们可以通过给一个方向的偏移值来实现单边投影:imageCodePenDemo--cssone-sidedprojection[2]使用scale(-1)实现翻转。通常,我们想要实现一个元素的180°翻转,我们会使用transform:rotate(180deg),这里有一个小技巧,使用transform:scale(-1)可以达到同样的效果。看一个演示:CSSNagativeScale(-1)

.scale{transform:scale(1);animation:scale10sinfinitelinear;}@keyframessscale{50%{transform:scale(-1);}100%{transform:scale(-1);}}看效果:(GIF中第一行是使用transform:rotate(180deg)的效果)CodePenDemo--使用scale(-1)实现元素的翻转[3]使用负字母间距以相反??的顺序排列文本。它类似于上面的scale(-1),它与负字母间距具有相同的效果。letter-spacing属性定义文本的间距行为。一般来说,除了关键字normal,我们还可以指定一个size来表示文字的间距。像这样:倒序排列文本

.letter_spacing{font-size:36px;letter-spacing:0px;animation:move10sinfinite;}@keyframesmove{40%{letter-spacing:36px;}80%{letter-spacing:-72px;}100%{letter-spacing:-72px;}}我们将文本的字母间距设置为0->36px->-72px,观察不同的变化:CodePenDemo--Negativeletter-spacingArrangetextinreverseorder[4]但由于中英文混用或不同字体的影响,以及倒序,不建议使用此方法来倒序排列文字命令。transition-delay和animation-delay的负值用于立即开始动画。我们知道cssanimation和transition提供了一个delay属性,可以延迟动画。考虑以下动画:简单代码如下所示:
.item{transform:rotate(0)translate(-80px,0);}.item:nth-child(1){animation:rotate3sinfinitelinear;}.item:nth-child(2){animation:rotate3sinfinite1slinear;}.item:nth-child(3){animation:rotate3sinfinite2slinear;}@keyframesrotate{100%{transform:rotate(360deg)translate(-80px,0);}}如果我们要移除这个延迟,希望在进入页面的时候,三个小球同时移动。这时候只需要将正向的animation-delay改为负向即可。.item:nth-child(1){animation:rotate3sinfinitelinear;}.item:nth-child(2){animation:rotate3sinfinite-1slinear;}.item:nth-child(3){animation:rotate3sinfinite-2slinear;}这里,有个小技巧,animation-dealy设置为负值的动画会立即执行,起始位置是它的其中一个动画阶段。因此,动画的开始是这样的:以上面的动画为例,定义了执行3s的动画,如果animation-delay为-1s,则起点相当于正常执行,在第2(3-1)次位置。CodePenDemo--使用negativeanimation-delay提前执行动画[5]Negativemargin负边距在CSS中被广泛使用,元素的外边距可以设置为负值。在flexbox布局规范流行之前,要实现多行等高布局还是花了不少功夫。其中一种方法是使用positivepadding和negativemargin来抵消。有这样一种布局:左右两列内容不确定,即高度未知。但是我希望不管左边内容多还是右边内容多,两列的高度永远是一样的。OK,其中一种Hack方法是用较大的正填充和相同的负边距填充左右列:.g-left{...padding-bottom:9999px;margin-bottom:-9999px;}.g-right{...padding-bottom:9999px;margin-bottom:-9999px;}可以使得不管左右两列的高度如何变化,高度较低的列会随着另一列变化.具体代码可以看这里:CodePenDemo--Positivepaddingandnegativemargin实现多列等高布局[6]总结另外还有一些比较知名的就不单独列出了,比如:使用negativemarign实现元素的层次使用negativemarign将列表li隐藏在垂直居中。使用负文本缩进隐藏文本。使用负z-index参与级联上下文排序。在CSS中使用negativeopacity实现伪条件判断,配合CSS自定义属性,使用纯CSS实现360°饼图效果:第五届CSS大会主题分享的CSS创意与视觉表现[7],虽然有些CSS负值的使用场景确实有用,但同时可能带来代码可读性的下降。有的时候看到这些代码,不得不好好的看一眼,才能平复心情,再次感叹,原来如此。如果还有其他更好更容易理解的实现,在使用实现时要慎重权衡。好了,本文到此结束,希望对你有所帮助:)更多精彩的CSS技术文章汇总在我的Github——iCSS[8],持续更新中。欢迎点个星订阅收藏。有什么问题或者建议可以多交流。原创文章文笔有限,知识匮乏。如果文章中有任何不准确的地方,请告诉我。参考资料[1]CodePenDemo——使用outline实现加号:https://codepen.io/Chokcoco/pen/PrrLaP[2]CodePenDemo——css单边投影:https://codepen.io/Chokcoco/pen/pergRb[3]CodePenDemo--使用scale(-1)翻转元素:https://codepen.io/Chokcoco/pen/VoQXVq[4]CodePenDemo--用负号字母逆序排列文本-spacing:https://codepen.io/Chokcoco/pen/QeQXpW[5]CodePenDemo--使用negativeanimation-delay提前执行动画:https://codepen.io/Chokcoco/pen/ymvjez[6]CodePenDemo--PositiveNegativepaddingmargin实现多栏等高布局:https://codepen.io/Chokcoco/pen/ZgrmVy[7]第五届CSS大会主题分享的CSS创意与视觉表现:https://www.zhangxinxu.com/wordpress/2019/06/cssconf-css-idea/[8]Github——iCSS:https://github.com/chokcoco/iCSS