《css揭秘》中讲了47个css技巧,其中有不少平常编码中并不会用到,本文除了将书中部分实用技巧罗列出来以外,还尝试用帮助读者搞明白background
、animation
等经常使用可是却掌握不牢固的知识点。因此阅读本文不只能够学习一些实用技巧,也能够巩固本身的 css 基础知识。css
全名Don't Repeat Yourself
,该原则适用于全部编程语言而不限于css。html
.expand-range {
position: relative;
}
.expand-range:after {
content: '';
position: absolute;
top: -10px; right: -10px; bottom: -10px; left: -10px;
}
复制代码
推荐使用scss:前端
@mixin expand-range($top: -10px, $right: $top, $bottom: $top, $left: $right, $position: relative) {
position: $position;
&:after {
content: '';
position: absolute;
top: $top;
right: $right;
bottom: $bottom;
left: $left;
}
}
//使用:.test { @include expand-range($top: -5px, $position: absolute) }
复制代码
z-index: -1
特性实现伪元素覆盖背景同时又不会遮挡文字(具体实现原理参考这里 )。这是一个很是经常使用又好用的技巧,善加利用能够达到不少意想不到的效果。地址position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
z-index: -1;
复制代码
clip-path
clip-path
能够实现区域裁剪,如今浏览器支持较好的有三个函数:clip-path: circle(50px at 50px 50px)
以 50px 50px
的地方为圆心裁剪一个半径 50px 的圆;clip-path: ellipse(30px 40px at 50px 50px)
以 50px 50px
的地方为圆心裁剪一个横向半径 30px,纵向半径 40px 的椭圆;clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%)
按照多个坐标剪裁一个多边形,此处是菱形。有了 clip-path
,就能够轻易的实现任意多边形了:地址border-radius
border-radius
居然能够设置 8 个角的半径~ 其中水平方向(对角线上下有弧度的地方)和垂直方向(对角线左右有弧度的地方)各四个,能够用 /
分割。若是水平或垂直方向指定的值少于四个,则会按照和 margin、padding
同样的规则重复。若是只指定来水平方向的,那么垂直方向的跟水平方向的同样。border-radius: 5em 1em; /*至关于border-radius: 5em 1em 5em 1em / 5em 1em 5em 1em;*/
复制代码
min-content
关键字display: inline-block
的包裹特性实现一个不彻底的版本:地址 这种方法的缺陷是文本脱离了文档流,高度未计入包含块。可是若是利用 min-content
关键字,能够一行代码实现且无反作用:地址width: min-content;
复制代码
box-shadow
的inset
box-shadow
能够模拟实现多重边框,可是因为阴影不占空间,因此没法触发点击事件,鼠标hover边框时没法出现小手,因此须要配合inset
关键字使用:地址height: 200px;
background: cyan;
box-shadow: 0 0 0 5px #000 inset,
0 0 0 10px #555 inset,
0 0 0 15px #999 inset;
复制代码
box-shadow
box-shadow
前两个参数指定阴影的x、y偏移量,注意若为正数时总体向右/向下偏移,那么相应的左方/上方会空出一部分来(能够用来隐藏模糊半径或扩张半径),负数相反;第三个参数是阴影模糊半径,即高斯模糊多增长出来的过分颜色;第四个参数是阴影扩张半径,表示阴影增长的尺寸,能够是负数,表示阴影缩短的尺寸:地址box-shadow: 0 5px 4px -4px black;
复制代码
第二个参数使阴影总体下移 5px ,第三个参数使阴影四周多了 4px 的高斯模糊(注意因为总体下移了 5px,因此此时上方仍是没有阴影露出的),第四个参数又把阴影总体缩小了 4px,,因此左右两边才没有出现模糊半径致使的高斯模糊阴影色,从而实现单侧投影。css3
还能够逗号分隔设置多个阴影色,好比下面的两侧投影效果:地址git
box-shadow: 5px 0 5px -5px black,
-5px 0 5px -5px black;
复制代码
filter: drop-shadow()
box-shadow
不能透过透明背景显示出来,不能越过伪元素/子元素显示出来,而这些drop-shadow
能作到。(但不管哪一种投影都会被clip-path
剪裁掉~~)地址filter: drop-shadow(2px 2px 10px rgba(0,0,0,.5));
复制代码
前端开发大都了解糊滤的高斯模镜效果是filter: blur()
实现的,可是却不多使用滤镜的其余几个调色效果。filter
的值有blur()
、drop-shadow()
、url()
、brightness()
、contrast()
、grayscale()
、hue-rotate()
、invert()
、opacity()
、saturate()
、sepia()
~~可使用复合形式如:filter: sepia(1) saturate(4)
等。下面是filter属性值大集合:地址github
饼图的 css 实现方案很是奇怪,因此我忽略之。推荐使用 svg 的实现方案,很是简单,先来个基本教学吧~面试
先画个圆:编程
<svg width="100" height="100">
<circle r="25" cx="50" cy="50" />
</svg>
复制代码
这里 r="25"
是半径25, cx cy
分别表示圆心的 x y
坐标。segmentfault
circle {
fill: yellowgreen;
stroke: #666;
stroke-width: 50;
}
复制代码
这里给圆形定义了一个宽度 40 的描边:浏览器
再把描边设为线段长度 20 间隔 10 的虚线:
circle {
...
stroke-dasharray: 20 10;
}
复制代码
当把虚线的间隔设定为大于等于圆周时,虚线的线段长度就是一个扇形区域(当线段长度等于圆周时扇区达到100%):
给 svg 设置圆角和背景色,并旋转 -90deg ,就能够实现一个饼图:地址(使用currentColor
关键字和color: inherit
是为了实现DRY原则。)
可是这样的饼图其扇区大小是不易计算的,为了方便计算,可让虚线的线段长度同时也是圆周无限接近100,这样就能够更方便的设置扇区的百分比。圆周是 2πr ,因此 100 = 2πr
,计算得出半径 r 近似值 16。再利用 svg 的 viewBox 属性,实现自适应容器大小的饼图:地址
这种方法有个弊端,就是当设置 stroke-dasharray: 100 100
时会有一条缝,这是取近似值没法避免的。
background
background
是咱们最经常使用的属性之一,但做为一个老前端,我也只能羞耻的说我目前并无彻底掌握这个属性。
background
是一个简写属性,能够包括多个属性:background-clip、background-color、background-image、background-origin、background-position、background-repeat、background-size、background-attachment
。接下来咱们一个个来看看这些属性的做用:
background-color
最经常使用的属性,默认不继承(background
的全部属性都默认不继承),初始值为 transparent
;有时候使用默认继承能够实现一些好玩的效果,好比倒影;backgroundo-image
背景图片,能够逗号分割设置多个,能够是图片url或者渐变色;background-clip
背景剪裁,能够逗号分割设置多个,值能够为 broder-box
(初始值)、padding-box
、content-box
、text
(新,将背景被文字剪裁);background-origin
设置背景起始点的相对区域,搭配 background-position
使用,能够逗号分割设置多个,值能够是border-box
、padding-box
(初始值)、content-box
;background-position
设置背景的起始点,能够逗号分割设置多个,值能够是 10px 20px
、center center
、left 10px bottom 20px
等等,很是灵活;background-size
设置背景的大小,能够逗号分割设置多个,值能够是数字值如30px 40px
、auto auto
(初始值)、conver
、contain
;background-repeat: repeat
就是根据这个尺寸大小来重复的。background-repeat
设置背景的重复方式,初始值为 repeat
,常使用值的还有no-repeat
;background-attachment
设置背景图像的位置是在视口内固定,仍是随着包含它的区块滚动。能够逗号分割设置多个,值有scroll
(初始值)、local
、fixed
。详情查看MDN简写时 background-size
只能紧接着 background-position
出现,以 / 分割,如: "center / 80%"。
background-clip
background
属性默认会覆盖整个盒模型包括边框border
,因此设置border-color: rgba(0, 0, 0, .5)
时会透出背景色,达不到半透明边框的效果。css3增长了background-clip
属性,定义背景填充的裁剪区域。设置padding-box
即可以实现半透明边框:地址border: 10px solid rgba(255, 255, 255, .5);
background: white;
background-clip: padding-box;
复制代码
backgrond-position
background-origin
background-position
能够定位背景图片等位置,可是都是相对padding-box
的左上角开始等。css3 容许这样写:background-position: right 10px bottom 20px
,同时 css3 还支持background-origin
,其默认值如同其表现border-box
,支持设为padding-box
和content-box
:地址height: 200px;
padding: 10px;
border: 5px solid cyan;
background: lightblue;
background: radial-gradient(#00a4fd, cyan) no-repeat right 100px bottom / 100px 100px;
background-origin: content-box;
复制代码
background-position
设为百分比值较为复杂。百分比值实际上执行了如下的计算公式:
(container width - image width) * (position x%) = (x offset value)
(container height - image height) * (position y%) = (y offset value)
复制代码
由计算公式可知:当值为0%时,实际偏移值为0px,此时图片的左边界(或上边界)和容器的左边界(或上边界)重合;当值为50%时,实际偏移值为容器减图片剩余空间的一半,图片左右边界(或上下边界)距离容器左右边界(或上下边界)相等,此时图片的中点和容器的中点重合。当值100%时,实际偏移值为容器减图片的剩余空间,因此此时图片的右边界(或下边界)和容器的右边界(或下边界)重合。两者之差为负值时一样有效。地址
background-image
lienar-gradient
的第一个参数是渐变的角度,能够是方向关键字to top
(初始值,可忽略不写)等,也能够是角度90deg
等;#fb3 50%
指的是色标和终点位置值;这里linear-gradient
的第二个位置值设置为0会被解析为前一个色标的位置值即50%,这样写更加符合DRY
原则。background: linear-gradient(#fb3 50%, #58a 0);
background-size: 100% 30px;
复制代码
也能够设置为垂直条纹背景:
background: linear-gradient(to right, #fb3 50%, #58a 0);
background-size: 100% 30px;
复制代码
还能够设置为斜向条纹:
background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
background-size: 30px 30px;
复制代码
斜向条纹须要设置四条条纹才能在平铺到时候作到无缝拼接。
更好的斜向条纹:(这里必须设置起始值#fb3 0
)
background: repeating-linear-gradient(60deg, #fb3 0, #fb3 15px, #58a 0, #58a 30px);
复制代码
background-image
、background-size
background: #58a;
background-image: linear-gradient(white 1px, transparent 0),
linear-gradient(to right, white 1px, transparent 0);
background-size: 30px 30px;
复制代码
更好的网格:
background: #58a;
background-image: linear-gradient(white 2px, transparent 0),
linear-gradient(to right, white 2px, transparent 0),
linear-gradient(rgba(255, 255, 255, .5) 1px, transparent 0),
linear-gradient(to right, rgba(255, 255, 255, .5) 1px, transparent 0);
background-size: 75px 75px, 75px 75px, 15px 15px, 15px 15px;
复制代码
background-image
、background-size
、background-position
background: #eee;
background-image:
linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 0, transparent 75%, rgba(0, 0, 0, .25) 0),
linear-gradient(45deg, rgba(0, 0, 0, .25) 25%, transparent 0, transparent 75%, rgba(0, 0, 0, .25) 0);
background-size: 30px 30px;
background-position: 0 0, 15px 15px;
复制代码
到这里 background
属性基本讲完了,光看无用,多动手实践吧。
background:
radial-gradient(tan 30%, transparent 0),
radial-gradient(tan 30%, transparent 0);
background-color: #666;
background-size: 30px 30px;
background-position: 0 0, 15px 15px;
复制代码
clip-path
、径向渐变clip-path
均可以轻松实现,可是对于圆形的切角,使用径向渐变是最好的选择。可是若是有弧形的切角呢?radial-linear
第一个参数指定渐变的起始点点(默认为中心点),同时可指定渐变类型是椭圆仍是圆;地址background:
radial-gradient(circle at top left, transparent 15px, blue 0) top left,
radial-gradient(circle at top right, transparent 15px, cyan 0) top right,
radial-gradient(circle at bottom right, transparent 15px, cyan 0) bottom right,
radial-gradient(circle at bottom left, transparent 15px, cyan 0) bottom left;
background-size: 50% 50%;
background-repeat: no-repeat;
复制代码
background: conic-gradient(lightblue 30%, yellowgreen 0, yellowgreen 50%, cyan 0);
复制代码
animation
animation
属性是 animation-name、animation-duration、 animation-timing-function、animation-delay、animation-iteration-count、animation-direction、animation-fill-mode、animation-play-state
属性的一个简写属性形式。
animation-name
指定动画的名称,能够逗号分割设置多个(如下皆可);animation-duration
指定动画运行的时间;animation-delay
指定动画执行前的延时;animation-timing-function
指定动画执行的速度函数,如linear
、ease
(默认)、ease-in-out
等,也可用贝塞尔函数cubic-bezier()
;animation-iteration-count
指定动画的运行的次数,默认为1,能够为Infinite
无限次;animation-direction
指定动画是否反方向播放,normal
正常的顺序,alternate
交替运行,reverse
反向运行,alternate-reverse
反向交替运行;animation-fill-mode
设置CSS动画在执行以前和以后的样式,none
不设置,forwards
保留最后一帧动画的样式,backwards
当即应用第一个关键帧中定义的值,并在animation-delay期间保留此值,both
同时应用forwards
和backwards
的规则;animation-play-state
定义一个动画是否运行或者暂停,值为running
、paused
。如何给动画加上回弹效果呢?这里介绍一种最便利的方法:
cubic-bezier(x1, y1, x2, y2)
上图图横轴为时间,纵轴为动画进度。图中贝塞尔曲线有两个控制手柄,x1, y1
控制第一个锚点,x2, y2
控制第二个锚点。其中 x1 、x2
不能大于/小于 1,可是y1, y2
能够。当 y2
大于 1 时,就会产生提早到达终点,而后超过终点,而后再返回终点的效果,像回弹同样。地址
animation: bounce 3s both cubic-bezier(.7, .1, .3, 2);
复制代码
transition
属性是 transition-property、transition-duration、transition-timing-function、transition-delay
的一个简写属性。使用 transition
一样能够实现回弹效果:地址
p {
transform-origin: 1.4em -.4em;
transition: transform .5s cubic-bezier(.25, .1, .3, 1.5);
}
input:not(:focus) + p {
transform: scale(0);
transition: transform 300ms; /*此处是为了缩小时重置transition-timing-function,不触发回弹*/
}
复制代码
animation
、background-position
background-position
设为100% 0%
,动画便会将背景位置从最初的0% 0%
向最后的100% 0%
过分:地址div {
width: 150px; height: 150px;
background: url('http://c3.staticflickr.com/3/2671/3904743709_74bc76d5ac_b.jpg');
background-size: auto 100%;
animation: panoramic 10s linear infinite alternate;
}
div:hover {
animation-play-state: paused;
}
@keyframes panoramic {
to { background-position: 100% 0; }
}
复制代码
animation
transform-origin
transform-origin
为大圆容器中心点,同时利用两个元素在向不一样方向旋转时旋转角度互相抵消的原理,实现图像沿环形路径旋转同时保持自身角度的不变。注意小圆距离大圆的距离由大圆的padding
属性控制,调整padding
时须要调整小圆的旋转原点transform-origin
以保持环形路径的正确:地址@keyframes spin {
to { transform: rotate(1turn); }
}
.avatar {
animation: spin 3s linear 2s infinite;
transform-origin: 110px 110px;
}
.avatar > img {
animation: inherit;
animation-direction: reverse;
}
复制代码
其实如今社区已经不乏介绍 css 技巧的好文,这里推荐几篇我以为写的极好的css技巧文章(固然可能你们也看过,很惭愧我其实如今也没看完):
整体来讲,《css揭秘》这本书并无给我带来太大惊喜,我的感受不如阅读《css世界》带来的收获多。固然了,这本书属于纯技巧型的,并无讲述不少原理知识,因此也不能苛责吧。有兴趣的同窗能够跟着我学习一波 css世界,相信确定会有更大的收获~