你所不知道的 CSS 负值技巧与细节

写本文的起因是,一天在群里有同学说误打误撞下,使用负的outline-offset实现了加号。嗯?好奇的我马上也动手尝试了下,到底是如何使用负的 outline-offset 实现加号呢?

使用负值 outline-offset 实现加号

假设我们有这样一个简单的结构:

<div></div>

div {

    width: 200px; height: 200px;

    outline: 20px solid #000;

    outline-offset: 10px;

}

修改outline-offset到一个合适的负值 ,那么在恰当的时候,outline 边框就会向内缩进为一个加号。

经过一番尝试,修改上述 div 的outline-offset为 -118px。

div {

    width: 200px; height: 200px;

    outline: 20px solid #000;

    outline-offset: -118px;

}

加个动画效果,大概是这样:

CodePen Demo -- 使用outline实现加号

很有意思,我尝试了很多不同的情况,最后总结了一个简单的规律,要使用负的 outline-offset 生成一个加号有一些简单的限制:

容器得是个正方形

outline 边框本身的宽度不能太小

outline-offset 负值 x 的取值范围为:

-(容器宽度的一半 + outline宽度的一半) < x < -(容器宽度的一半 + outline宽度)

在这个例子后,我又想,CSS 属性可以取负值的地方有很多。大家最为熟知的就是负margin,使用负的 marign,可以用来实现类似多列等高布局、垂直居中等等。那还有没有其他一些有意思的负值使用技巧呢?

下文就再介绍一些 CSS 负值有意思的使用场景。

单侧投影

先说单侧投影,关于box-shadow,大部分时候,我们使用它都是用来生成一个两侧的投影,或者一个四侧的投影。如下:

OK,那如果要生成一个单侧的投影呢?

我们来看看 box-shadow 的用法定义:

{

    box-shadow: none | [inset? && [ <offset-x> <offset-y> <blur-radius>? <spread-radius>? <color>? ] ]#

}

以box-shadow: 1px 2px 3px 4px #333为例,4 个数值的含义分别是,x 方向偏移值、y 方向偏移值 、模糊半径、扩张半径。

这里有一个小技巧,扩张半径可以为负值

继续,如果阴影的模糊半径,与负的扩张半径一致,那么我们将看不到任何阴影,因为生成的阴影将被包含在原来的元素之下,除非给它设定一个方向的偏移量。所以这个时候,我们给定一个方向的偏移值,即可实现单侧投影:

CodePen Demo -- css单侧投影

使用 scale(-1) 实现翻转

通常,我们要实现一个元素的 180° 翻转,我们会使用transform: rotate(180deg),这里有个小技巧,使用transform: scale(-1)可以达到同样的效果。看个 Demo:

<p class="scale">CSS Nagative Scale(-1)</p>

.scale {

    transform: scale(1);

    animation: scale 10s infinite linear;

}

@keyframes scale{

    50% {

        transform: scale(-1);

    } 

    100% {

        transform: scale(-1);

    }

}

看看效果:

GIF 中第一行是使用了transform: rotate(180deg)的效果

CodePen Demo -- 使用 scale(-1) 实现元素的翻转

使用负 letter-spacing 倒序排列文字

与上面 scale(-1) 有异曲同工之妙的是负的letter-spacing。

letter-spacing属性明确了文字的间距行为,通常而言,除了关键字normal,我们还可以指定一个大小,表示文字的间距。像这样:

<p class="letter_spacing">倒序排列文字</p>

.letter_spacing {

    font-size: 36px;

    letter-spacing: 0px;

    animation: move 10s infinite;

}

@keyframes move {

    40% {

        letter-spacing: 36px;

    }

    80% {

        letter-spacing: -72px;

    }

    100% {

        letter-spacing: -72px;

    }

}

我们设置文字的letter-spacing从 0 -> 36px -> -72px,观察不同的变化:

CodePen Demo -- 负letter-spacing倒序排列文字

然而,受到中英文混排或者不同字体的影响,以及倒序后的排列方式,不建议使用这种方式来倒序排列文字。

transition-delay 及 animation-delay 的负值使用,立刻开始动画

我们知道,CSS 动画及过渡提供了一个 delay 属性,可以延迟动画的进行。

考虑下面这个动画:

简单的代码大概是这样:

<div class="g-container">

    <div class="item"></div>

    <div class="item"></div>

    <div class="item"></div>

</div>


.item {

    transform: rotate(0) translate(-80px, 0) ;

}

.item:nth-child(1) {

    animation: rotate 3s infinite linear;

}

.item:nth-child(2) {

    animation: rotate 3s infinite 1s linear;

}

.item:nth-child(3) {

    animation: rotate 3s infinite 2s linear;

}

@keyframes rotate {

    100% {

        transform: rotate(360deg) translate(-80px, 0) ;

    }

}

如果,我们想去掉这个延迟,希望在一进入页面的时候,3 个球就是同时运动的。这个时候,只需要把正向的 animation-delay 改成负向的即可。

.item:nth-child(1) {

    animation: rotate 3s infinite linear;

}

.item:nth-child(2) {

    animation: rotate 3s infinite -1s linear;

}

.item:nth-child(3) {

    animation: rotate 3s infinite -2s linear;

}

这里,有个小技巧,被设置了animation-dealy为负值的动画会立刻执行,开始的位置是其动画阶段中的一个阶段。所以,动画在一开始的时刻就是下面这样:

以上述动画为例,一个被定义执行 3s 的动画,如果animation-delay为 -1s,起点相当于正常执行时,第2s(3-1)时的位置。

CodePen Demo -- 使用负值 animation-delay 提前执行动画

负值 margin

负值 margin 在 CSS 中算是运用的比较多的,元素的外边距可以设置为负值。

在 flexbox 布局规范还没流行之前,实现多行等高布局还是需要下一番功夫的。其中一种方法便是使用正 padding 负 margin 相消的方法。

有如下一个布局:


左右两栏的内容都是不确定的,也就是高度未知。但是希望无论左侧内容较多还是右侧内容较多,两栏的高度始终保持一致。

OK,其中一种 Hack 办法便是使用一个很大的正 padding 和相同的负 margin 相消的方法填充左右两栏:

.g-left {  ...  padding-bottom: 9999px;  margin-bottom: -9999px;}.g-right {  ...  padding-bottom: 9999px;  margin-bottom: -9999px;}复制代码

可以做到无论左右两栏高度如何变化,高度较低的那一栏都会随着另外一栏变化。

具体的代码可以看看这里:CodePen Demo -- 正padding负margin实现多列等高布局

总结一下

另外,还有一些大家熟知的没有单独列出来的,譬如:

使用负 marign 实现元素的水平垂直居中

使用负 marign隐藏列表 li 首尾多余的边框

使用负 text-indent 实现文字的隐藏

使用负的 z-index 参与层叠上下文排序

还有一些很深奥的,譬如张鑫旭大大在今年的 CSS 大会上分享的,利用负的 opacity 在 CSS 中实现了伪条件判断,配合 CSS 自定义属性,使用纯 CSS 实现 360° 的饼图效果:

第五届CSS大会主题分享之CSS创意与视觉表现

最后

额,虽然 CSS 负值的一些使用场景的确有有用之处,但是与此同时有可能带来的是代码可读性的下降。有的时候看到这些代码不得不好好捋一捋才能缓过神来,再感叹一句,原来如此。

如果有其他更好的更易理解的实现方式,具体使用实现的时候应该好好权衡一下。

好了,本文到此结束,希望对你有帮助 :)

来源:https://juejin.im/post/5d4b8707f265da03a65302bd

声明:著作权归作者所有,文章及图片均来自互联网,如有侵权请联系小编删除!!!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • 1.CSS3 边框 border-radius CSS属性用来设置边框圆角。当使用一个半径时确定一个圆形;当使用两...
    garble阅读 629评论 0 0
  • CSS要点记录 CSS 指层叠样式表 (Cascading Style Sheets) 多种样式时的优先级问题 数...
    Tony__Hu阅读 1,092评论 0 0
  • 选择qi:是表达式 标签选择器 类选择器 属性选择器 继承属性: color,font,text-align,li...
    love2013阅读 2,301评论 0 11
  • 一、CSS入门 1、css选择器 选择器的作用是“用于确定(选定)要进行样式设定的标签(元素)”。 有若干种形式的...
    宠辱不惊丶岁月静好阅读 1,583评论 0 6
  • CSS参考手册 一、初识CSS3 1.1 CSS是什么 CSS3在CSS2.1的基础上增加了很多强大的新功能。目前...
    没汁帅阅读 3,552评论 1 13