你所不知道的 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;
}
加个动画效果,大概是这样:
很有意思,我尝试了很多不同的情况,最后总结了一个简单的规律,要使用负的 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 方向偏移值 、模糊半径、扩张半径。
这里有一个小技巧,扩张半径可以为负值。
继续,如果阴影的模糊半径,与负的扩张半径一致,那么我们将看不到任何阴影,因为生成的阴影将被包含在原来的元素之下,除非给它设定一个方向的偏移量。所以这个时候,我们给定一个方向的偏移值,即可实现单侧投影:
使用 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 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。
如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
你所不知道的 CSS 负值技巧与细节的更多相关文章
- 你所不知道的 CSS 阴影技巧与细节
关于 CSS 阴影,之前已经有写过一篇,box-shadow 与 filter:drop-shadow 详解及奇技淫巧,介绍了一些关于 box-shadow 的用法. 最近一个新的项目,CSS-Ins ...
- 你所不知道的 CSS 阴影技巧与细节 滚动视差?CSS 不在话下 神奇的选择器 :focus-within 当角色转换为面试官之后 NPOI 教程 - 3.2 打印相关设置 前端XSS相关整理 委托入门案例
你所不知道的 CSS 阴影技巧与细节 关于 CSS 阴影,之前已经有写过一篇,box-shadow 与 filter:drop-shadow 详解及奇技淫巧,介绍了一些关于 box-shadow ...
- 你所不知道的 CSS 滤镜技巧与细节
承接上一篇你所不知道的 CSS 动画技巧与细节,本文主要介绍 CSS 滤镜的不常用用法,希望能给读者带来一些干货! OK,下面直接进入正文.本文所描述的滤镜,指的是 CSS3 出来后的滤镜,不是 IE ...
- 你所不知道的 CSS 动画技巧与细节
怕标题起的有点大,下述技巧如果你已经掌握了看看就好,欢迎斧正,本文希望通过介绍一些 CSS 不太常用的技巧,辅以一些实践,让读者可以更加深入的理解掌握 CSS 动画. 废话少说,直接进入正题,本文提到 ...
- 【CSS】346- 你所不知道的 CSS 阴影技巧与细节
偷懒了1个多礼拜,在工作饱和的情况下,怎么坚持学习?今天的分享来自@Coco国服第一切图仔,我们聊聊CSS属性box-shadow- 关于 CSS 阴影,之前已经有写过一篇,box-shadow 与 ...
- 你所不知道的CSS
1.用FONT-SIZE:0来清除间距 inline-block的元素之间会受空白区域的影响,也就是元素之间差不多会有一个字符的间隙.如果在同一行内有4个25%相同宽度的元素,会导致最后一个元素掉下来 ...
- 你所不知道的Spring的@Autowired实现细节
前言 相信很多Java开发都遇到过一个面试题:Resource和Autowired的区别是什么?这个问题的答案相信基本都清楚,但是这两者在Spring中是如何实现的呢?这就要分析Spring源码才能知 ...
- 你可能不知道的Animation动画技巧与细节
引言 在web应用中,前端同学在实现动画效果时往往常用的几种方案: css3 transition / animation - 实现过渡动画 setInterval / setTimeout - 通过 ...
- Android Context完全解析,你所不知道的Context的各种细节
Context相信所有的Android开发人员基本上每天都在接触,因为它太常见了.但是这并不代表Context没有什么东西好讲的,实际上Context有太多小的细节并不被大家所关注,那么今天我们就来学 ...
随机推荐
- Codeforces 776D:The Door Problem(DFS染色)
http://codeforces.com/problemset/problem/776/D 题意:有n个门,m个开关,每个门有一个当前的状态(0表示关闭,1表示打开),每个开关控制k个门,但是每个门 ...
- Linux中修改远程地址
首先跳转到本地用户root,如果不是的话可能没有权限 第一步:安装ssh服务 执行命令:yum install openssh-server (因为我已经安装过了,所以显示的是已安装) 第二步:修改S ...
- c++学习书籍推荐《C++ Primer(中文版)(第5版)》下载
百度云及其他网盘下载地址:点我 编辑推荐 <C++ Primer(中文版)(第5版)>编辑推荐:一书在手,架构无忧:三十位一线架构师真知实践:百位架构师献计献策:十万文字尽显架构精华. 媒 ...
- 神奇的Invsqrt函数
float InvSqrt(float x) { float xhalf = 0.5f*x; int i = *(int*)&x; // get bits for floating VALUE ...
- I/O:DataInput
DataInput: boolean readBoolean() :读取一个输入字节,如果该字节不是零,则返回 true,如果是零,则返回 false. byte readByte() :读取并返回一 ...
- something good
CF292A CF304B CF383A CF409D CF409F CF632A CF652B CF656A CF656B CF656D CF659A CF678A CF697A CF735D CF ...
- HTTPS协议学习笔记
在前一段时间准备面试的时候,面试官反复提到了HTTPS这个协议.我只是单纯的知道,HTTPS是安全的应用层协议 是HTTP更安全的版本,通过对称密钥加密.但是具体的其他的,可能我不太了解.今天就专门抽 ...
- 个人永久性免费-Excel催化剂功能第99波-手机号码归属地批量查询
高潮过往趋于平静,送上简单的手机号码归属地查询,因接口有数量限制,仅能满足少量数据需求,如有大规模数据却又想免费获得,这就成为无解了,数据有价,且用且珍惜. 业务使用场景 除了日常自带的手机各种管家为 ...
- SpringBoot学习笔记3
十六:自定义拦截器 参考文档 16.1 编写拦截器类 extends WebMvcConfigurerAdapter 并重写WebMvcConfigurerAdapter,如下: package co ...
- Java IO部分面试题
1.什么是比特(Bit),什么是字节(Byte),什么是字符(Char),它们长度是多少,各有什么区别 1. Bit最小的二进制单位 ,是计算机的操作部分 取值0或者1 2. Byte是计算机操作数据 ...