《CSS揭秘》读书笔记

摘要

《CSS揭秘》主要是介绍了使用CSS的技巧,经过47个案例来灵活的使用CSS进行实现,同时在实现过程当中注重CSS代码的灵活性与健壮性。经过阅读这本书有利于咱们编写高质量的CSS代码以及打破使用CSS时的固定思惟,可以更加灵活的使用CSS。javascript

《CSS揭秘》中的全部案例代码均上传到:play.csssecrets.io/。css

关于《CSS揭秘》的读书笔记主要是记录经过阅读书中的CSS案例所得到启发和对CSS样式新的认知点。html

第二章 背景与边框

background-clip

background-clip属性设置元素的背景(背景图片或颜色)覆盖到什么位置。
属性值为:border-box(默认值) | padding-box | content-box | text
注:text属性值是设置将背景被裁剪为文字的前景色(chrome浏览器支持须要添加-webkit-前缀;最新版本的火狐浏览器 [ 63.0.3 (64 位) ]直接支持background-clip: text 属性)。java

background-origin

background-origin规定了指定背景图片background-image属性的原点位置的背景相对区域。
属性值为:border-box | padding-box(默认) | content-boxweb

多重边框

传统作法:经过多重元素嵌套来生成多重边框。chrome

新的思路:
方法一:经过box-shadow的第四个参数可让投影面积增大或者缩小,设置box-shadow: 0 0 0 10px #809;获得的“投影”其实就像一道实线边框,而且box-shadow支持逗号分割法,所以咱们能够建立任意数量的投影。
缺点:边框的样式单一,只可以是实线边框。canvas

方法二:经过outline描边属性来设置第二重边框
缺点:只可以适用于两重边框(border一重,outline一重),而且outline的描边不可以贴合border-radius的圆角,只可以是矩形。浏览器

背景图片的灵活定位

传统作法:经过计算元素的大小,设置background-position的位置。bash

新的思路:
方法一:background-position属性模式是经过左上角进行定位的,能够随机指定距离任意角的偏移量,background-position:left 20px top 30px;dom

方法二:经过calc()函数来实时计算background-position的位置,background-position: calc(100% - 20px) calc(100% - 30px);

方法三:能够经过background-origin:content-box,使得background-position之内容区的左上角做为基准,图片距离边角的偏移量等于内边距。

边框内圆角(矩形容器,内侧有圆角)

传统作法:经过两个div嵌套,内部的div设置为圆角,外部的div保持矩形边框形状。

新的思路:outline属性结合box-shadow属性。
一、经过outline能够为border-radius描边,可是描边为矩形,与圆角以前存在空白缝隙,经过box-shadow能够填充缝隙。
二、须要填充的缝隙大小为,圆角半径为r,圆心到描边顶角的距离为√2 r,所以填充的距离为(√2 - 1)r
缺点:由于box-shadow的宽度至少须要设置为(√2 - 1)r,若是描边的宽度小于这个值,那么描边将会被box-shadow遮住。

linear-gradient()

linear-gradient()函数建立一个渐变“图像”
函数内容为:linear-gradient(direction, colorItem1,colorItem2...)
一、角度设置是根据时钟顺时针进行计算的;
二、下一个颜色开始位置与上一个颜色的结束位置一致,则不须要填充颜色之间空余的位置,造成不一样的颜色条而非过渡条;
三、当后面颜色位置小于前面颜色位置时,浏览器之间将后面颜色位置更正为与前面颜色位置一致。

repeating-linear-gradient()

repeating-linear-gradient()建立一个重复线性渐变的“图像”
函数内容为:repeating-linear-gradient(direction, colorItem1,colorItem2...)
每次重复时,色标位置的偏移量都是基准渐变长度(最后一个色标和第一个之间的距离)的倍数,所以要设置开始处(0位置)的颜色。

条纹背景

传统作法:经过两种颜色进行设置

新的思路:
方法一:首先经过background-color设置背景色,而后经过background-image:linear-gradient(rgba(0,0,0,0.2) 50%,transparent 50%);以及background-size:auto 2em;建立一个“黑白条”盖在上面而且高度为2em(1em表明为1行)。

background-color:red;
background-image:linear-gradient(rgba(0,0,0,0.2) 50%,transparent 50%);
background-size:auto 2em;
复制代码

方法二:经过linear-gradient()直接设置两种颜色,而后设置background-size 大小,根据background直接复制平铺。

方法三:经过repeating-linear-gradient()直接设置颜色自动重复。

错落相间的背景图案

一、经过设置两个linear-gradient(),而后各自设置其background-position,来使的背景图案错落开来。
二、矩形的背景图案,能够经过linear-gradient()45deg的建立2个直角三角形拼接而成。

带有图案的边框

传统作法:经过建立两个div,外层的div设置背景图片,内层的div在背景图片上覆盖一层白色背景色,两层之间的差距就造成了图案边框。

新的思路:
一、background能够设置多个背景,可是白色背景色会默认在最底层,没法上浮到图片上方,因此白色背景色经过线性渐变来实现,而且将背景图片的铺盖范围设置为border-box。
二、background-origin默认值是padding-box,所以图片默认是放置在padding-box的原点上,而后经过平铺复制蔓延到border-box,所以border区域的图片显示异常,因此要将border-origin设置border-box。

padding: 1em;
border: 1em solid transparent;
background: linear-gradient(white, white),
	        url(https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSGTVf63Vm3XgOncMVSOy0-jSxdMT8KVJIc8WiWaevuWiPGe0Pm);
background-size:cover;
background-clip:padding-box,border-box;
background-origin:border-box;
复制代码

注:除了图片以外还能够经过渐变来实现有规律的边框图案。

第三章 形状

半椭圆/四分之一椭圆/八分之一椭圆

经过border-radius能够分别设置每一个角的水平和垂直圆形半径,进而达到对每一个角的变形设置。

平行四边形

传统作法:对元素添加skew()属性进行变形。
缺点:元素的形状是发生了改变,可是内部的文本和其余元素也都所有发生了变形。

新的思路:
方法一:经过嵌套元素,外部元素负责形状的变形,内部元素进行反向变形,使元素恢复正常。若是须要图片填充变形的形状,除了对内部图片进行反向变形外,还须要scale放大,填充满整个变形图案。
缺点:须要添加额外的html元素。

方法二:经过添加伪元素,让伪元素来完成形状的变形,元素自己不发生变化。
缺点:没法使图片填充变形的形状。

.button {
	position: relative;
	display: inline-block;
}
.button::before {
	content: ''; /* To generate the box */
	position: absolute;
	top: 0; right: 0; bottom: 0; left: 0; /* 可以自适应元素大小的变化 */
	z-index: -1; /* 背景颜色不会覆盖在字体上方 */
	background: #58a;
	transform: skew(45deg);
}
复制代码

注:以上方法适用于任何咱们想要变形一个元素而不想变形它的内容状况

菱形图片

除了使用“平行四边形”中的方法一来建立一个菱形图片以外,还可使用clip-path属性来直接对图片元素进行裁剪。
缺点:须要提早考虑clip-path属性的兼容性。

img {
	-webkit-clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
	clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
复制代码

切角效果

方法一:
一、切角效果的核心方式就是使用:linear-gradient(45deg, transparent 15px, red 0);经过渐变来实现一个透明的小角,致使视觉效果像切角了。
二、当对元素进行多个切角时,将背景进行划分,每块单独作切角处理,而后定位每块的位置,“拼接”成一个背景。

div{
	background: #58a;
	background: linear-gradient(135deg, transparent 15px, #58a 0) top left,
	            linear-gradient(-135deg, transparent 15px, #58a 0) top right,
	            linear-gradient(-45deg, transparent 15px, #58a 0) bottom right,
	            linear-gradient(45deg, transparent 15px, #58a 0) bottom left;
	background-size: 50% 50%;
	background-repeat: no-repeat;
}
复制代码

三、要实现弧形切角(内凹圆角)时,只须要将径向渐变替换线性渐变便可。

div{
	background: #58a;
	background:	radial-gradient(circle at top left, transparent 15px, #58a 0) top left,
	            radial-gradient(circle at top right, transparent 15px, #58a 0) top right,
	            radial-gradient(circle at bottom right, transparent 15px, #58a 0) bottom right,
	            radial-gradient(circle at bottom left, transparent 15px, #58a 0) bottom left;
	background-size: 50% 50%;
	background-repeat: no-repeat;
}
复制代码

缺点:只能是纯色背景。

方法二:经过SVG画一个切角效果的图片,而后基于border-image的工做原理,将切角效果应用于border上。

div{
	border: 15px solid transparent;
	border-image: 1 url('data:image/svg+xml,\ <svg xmlns="http://www.w3.org/2000/svg" width="3" height="3" fill="%2358a">\ <polygon points="0,1 1,0 2,0 3,1 3,2 2,3 1,3 0,2" />\ </svg>');
	background: #58a;
	background-clip: padding-box;
}
复制代码

缺点:背景颜色只能是纯色或者是边缘接近纯色的背景图片。

方法三:使用clip-path对元素进行裁剪,裁剪出切角效果,不管你的背景是什么这种方法都可以适用,可是要注意clip-path属性的兼容性。

div {
	height:50px;
	background: #58a;
	-webkit-clip-path: 
		polygon(20px 0, calc(100% - 20px) 0, 100% 20px, 100% calc(100% - 20px),
		calc(100% - 20px) 100%,
		20px 100%, 0 calc(100% - 20px), 0 20px);
	clip-path:
	 	polygon(20px 0, calc(100% - 20px) 0, 100% 20px, 100% calc(100% - 20px),
	 	calc(100% - 20px) 100%,
	 	20px 100%, 0 calc(100% - 20px), 0 20px);
}
复制代码

梯形图案

一、经过元素3D旋转投影成2D的梯形形状,而后经过scale将元素按照比例放大,弥补由于旋转形成的高度缩小。
二、经过固定元素的transform-origin,选择元素的哪几条边不须要变化。
三、使用添加伪元素变形方案,由于3D旋转没法进行反向变形,所以不采纳嵌套元素变形方案。
缺点:同种旋转角度不一样的宽度,梯形元素的倾斜角由于宽度缘由会不相同。

div::before {
	content: ''; /* To generate the box */
	position: absolute;
	top: 0; right: 0; bottom: 0; left: 0;
	z-index: -1;
	background: red;
	transform: scaleY(1.5) perspective(.5em) rotateX(5deg);
	transform-origin: bottom; /* 经过设置transform-origin为bottom left或bottom right能够获得左侧倾斜和右侧倾斜的梯形 */
}
复制代码

饼状图

方法一:
步骤一:
一、经过建立一个阴阳图,左边为饼状图默认颜色,右边为饼状图显示颜色。
二、0~50%经过建立伪元素(颜色为默认颜色),挡住右边的显示颜色,经过旋转(0~0.5turn),一点点将显示颜色显示出来。
三、50%~100%经过建立伪元素(颜色为显示颜色),经过旋转(0~0.5turn),一点点覆盖左边的默认颜色。
四、经过animation切换伪元素背景色与重置旋转角度。

.pie {
	width: 100px; height: 100px;
	border-radius: 50%;
	background: yellowgreen;
	background-image: linear-gradient(to right, transparent 50%, currentColor 0);
	color: #655;
}

.pie::before {
	content: '';
	display: block;
	margin-left: 50%;
	height: 100%;
	border-radius: 0 100% 100% 0 / 50%;
	background-color: inherit;
	transform-origin: left;
	animation: spin 3s linear infinite, 
				bg 6s step-end infinite;
}

@keyframes spin {
	to { transform: rotate(.5turn); }
}
@keyframes bg {
	50% { background: currentColor; }
}
复制代码

步骤二:
一、经过animation-delay将直接跳转到动画的指定时间点。

// html
<div class='pie'>50%</div>
// css
.pie {
	display: inline-block;
	position: relative;
	width: 100px;
	line-height: 100px;
	border-radius: 50%;
	background: yellowgreen;
	background-image: linear-gradient(to right, transparent 50%, #655 0);
	color: transparent;
	text-align: center;
}

@keyframes spin {
	to { transform: rotate(.5turn); }
}
@keyframes bg {
	50% { background: #655; }
}

.pie::before {
	content: '';
	position: absolute;
	top: 0; left: 50%;
	width: 50%; height: 100%;
	border-radius: 0 100% 100% 0 / 50%;
	background-color: inherit;
	transform-origin: left;
	animation: spin 50s linear infinite,
				bg 100s step-end infinite;
	animation-play-state: paused;
	animation-delay: inherit;
}
// js
var _dom = document.querySelector('.pie')
_dom.style.animationDelay = '-' + parseFloat(_dom.textContent) + 's';
复制代码

方法二:
一、使用SVG中的虚线描边,将圆形描边的大小设置为半径的2倍,可以彻底覆盖圆形。
二、设置虚线的间隔为圆形的周长,可以保证只显示一块虚线。
三、设置虚线的长度为所占比例,显示出咱们所须要的饼状图。

// html
<svg viewBox='0 0 32 32'>
	<circle r='16' cx='16' cy='16'
</svg>
// css
svg {
	width:100px;
	height:100px;
	background:yellowgreen;
	border-radius:50%;
	transform:rotate(-90deg);
}
circle{
	fill:yellowgreen;
	stroke:#655;
	stroke-width:32; 
	stroke-dasharray:20 100; /* 半径为16,会使的周长刚恰好为100,经过设置虚线长度,直接就可以显示为百分比饼状图 */
}
复制代码

总结

经过以上的案例发现,元素的变形主要经过如下几种方式:
方法一:使用transform变形属性对元素进行2D/3D变形,而后经过scale方法元素来弥补由于变形所形成的宽高损失。

方法二:使用clip-path属性直接对元素进行裁剪。

方法三:使用linear-gradient()对元素进行处理。

第四章 视觉效果

单侧投影/邻边投影/双侧投影

一、box-shadow的第四个参数,称为扩张半径,能够根据指定的值去扩大或者缩小投影的的尺寸。
二、根据扩张尺寸,投影时若是阴影在别的边漫出来了,咱们能够设置扩张尺寸为负,这样就可以在保留阴影效果的同时,将其余边的阴影缩进去已到达去除阴影的效果。

不规则投影

一、box-shadow的投影没法做用于伪元素或者半透明的装饰上(好比虚线中间的缝隙,切角效果)
方法一:使用CSS滤镜filter属性的drop-shadow()函数,它能够为任何非透明的地方添加上阴影,参数等同于box-shadow可是不支持inset关键字和扩张半径。

div {
	filter:url(drop-shadow.svg#drop-shaodow) // 附上一个SVG滤镜能够获得稍好一点的浏览器支持度
	filter: drop-shadow(2px 2px 10px rgba(0,0,0,.5));
}
复制代码

缺点:drop-shaodow能够为任何非透明的地方添加上阴影,所以若是你的背景是透明的,则drop-shadow会为字体添加上阴影。

图片染色效果

方法一:在图片的上层覆盖一层半透明的纯色或者把图片设为半透明并覆盖在一层实色背景之上。
缺点:并非真正的染色效果,而且削弱了图片的对比度。

方法二:把图片放置在<canvas>中,并利用脚本对其进行染色处理。

方法三:经过多个filter滤镜组合对图片进行处理。

img {
	// 根据需求自由组合滤镜
	filter: 
		sepia()  // 将图像转换为深褐色
		saturate(4) // 转换图像饱和度
		hue-rotate(295deg); // 给图像应用色相旋转
}
复制代码

缺点:当添加动画将img切换会原图的效果时,切换效果不是一点点的渐变而是将滤镜一个个剔除的过渡变化。

方法四:混合模式-mix-blend-mode,只须要把图片包裹在一个容器中,并为这个容器的背景色设置为咱们想要的主色调。

<div>
	<img src='demo.jpg'/>
</div>
div {
	background:rgba(255,0,0,0.5);
}
img {
	mix-blend-mode:luminosity;
}
复制代码

缺点:要注意属性的兼容性,混合模式不支持动画,能够将容器的背景色设置为透明来实现正常/染色的切换。

方法五:混合模式-background-blend-mode,只须要使用一个div元素,将第一层背景设置为要染色的图片,将第二层背景设置为咱们想要的主色调。

<div style="background-image:url(demo.jpg)"></div>
div {
	width: 640px; 
	height: 440px;
	background-size: cover;
	background-color: rgba(255,0,0,0.5);
	background-blend-mode: luminosity;
}
复制代码

缺点:要注意属性的兼容性,混合模式不支持动画,能够将容器的背景色设置为透明来实现正常/染色的切换。

毛玻璃效果

一、背景图片之上存在文字,文本层所覆盖的那部分图片区域做模糊处理。
方法一: 为文本层添加一个伪元素,伪元素的设置的背景图片与以前的背景图片一致,致使伪元素的背景图片重叠在原背景图片上方,而后只须要对伪元素背景图片作模糊处理就能够了。

div, .text::before {
	background: url("demo.jpg") 0 / cover fixed;
}

.text {
	position: relative;
	background: hsla(0,0%,100%,.25) border-box; 
	overflow: hidden;
}

.text::before {
	content: '';
	position: absolute;
	top: 0; right: 0; bottom: 0; left: 0;
	margin: -30px; // 模糊到文本层边缘的时候会消失,扩大一圈区域,避免边缘无模糊。
	z-index: -1;
	-webkit-filter: blur(10px);
	filter: blur(10px);
}
复制代码

折角效果

一、使用渐变描绘一个空白的折角区域。
二、经过伪元素建立一个折角,经过三角函数来计算折角的大小,经过折角的角度来计算折角旋转角度和偏移角度,来创造出合乎常理的折角效果。
缺点:只可以对纯色背景进行折角效果。

第五章 字体排印

插入换行

传统作法:经过<br/>标签来进行换行

新的思路:能够经过:before或:after伪类选择器中的content设置为“\A”来进行换行,由于Unicode字符中表明换行符的为“0x000A”,在CSS中能够写为“\000A”或者简化为“\A”

div::after {
	content: "\A";
	white-space: pre; // 可以保留源代码中空白和换行符,不然content中的换行符将被忽略。
}
复制代码

tab-size属性

在须要展现代码的网页上时,经过设置tab-size属性可以指定一个tab缩进几个字符。

为某些字符单独设置字体

传统作法:为须要单独设置字体的字符设置class,经过class为它们设置独特的字体。

新的思路:@font-face中的unicode-range属性能够设置字体的适用于哪些字符。

@font-face {
	font-family: demoFont;
	src: local('Baskerville-Italic'), local('GoudyOldStyleT-Italic'); /* 应用于指定字符的字体 */
	unicode-range: U+26; /* 设置生效字符,'&'的Unicode码位,能够经过'&'.chatCodeAt(0).toString(16)获取'&'的十六进制码位'26',而后前面加上'U+'前缀 */
}

p {
	font-family: demoFont, Helvetica; /* demoFont字体只应用于'&'字符,其余字符会适用后续的字体'Helvetica' */
}
复制代码

自定义文本下划线

传统作法:经过text-decoration:underline;

新的思路:
一、经过background与background-size设置一条自定义格式的下划线;
二、经过text-shadow可让字符周围出现一圈白边,使的显示为下划线遇到字母的降部自动断开避让。
三、文本最好放置在行内元素内,这样下划线才能随这文本的换行也进行换行。

span {
	background: linear-gradient(gray, gray) no-repeat;
	background-size: 100% 1px;
	background-position: 0 1.2em;
	text-shadow: .05em 0 white, -.05em 0 white;
}
复制代码

空心字效果/文字外发光效果/文字凸起效果

经过text-shadow为文本添加效果来实现。

环形文字

一、经过SVG的path画出一个圆形。
二、经过text与textPath添加文本,并经过xlink:href属性将文本连接到路径上。

<div class='demo'>
	<svg viewBox='0 0 100 100'>
		<path d='M0,50 a50,50 0 1,1 0,1z' id='circle'></path>
		<text>
			<textPath xlink:href="#circle">fdsfdsfdsfdsfsdfdsfsdfds</textPath>		
		</text>
	</svg>
</div>

.demo {
	width:300px;
	height:300px;
	margin: 4em auto 0;
}
svg{
	display:block;
	overflow: visible;
}
path {
	fill:none;
}
复制代码

注:这种方法不但适用于环形文字还适用于全部须要特殊路径排序的文字。

第六章 用户体验

扩大用户交互热区

方法一:使用透明的border扩大交互热区。使用background-clip从新定义背景的填充区域。

.demo1 {
	border:20px solid transparent;
	background-clip:padding-box;
	/* 实际border-radius效果值为border-radius减去border的值 */
	border-radius:25px;
	box-shadow: 0 0 0 1px rgba(0,0,0,0.3) inset;
}
复制代码

注:
一、若是要设置border-radius的值时须要注意,实际border-radius效果值为border-radius减去border的值。
二、若是要设置边框能够经过内嵌投影在模拟出一道实色边框。
缺点:没法为元素设置box-shadow阴影效果,由于阴影效果时设置border-box外面的。

方法二:使用一个伪元素,扩大伪元素的范围,伪元素的范围也能够触发热区。经过伪元素能够随意设置热区的尺寸、位置、形状。

.demo2 {
	position:relative;
}
.demo2:before {
	content:'';
	position:absolute;
	top:-10px;
	bottom:-10px;
	left:-10px;
	right:-10px;
}
复制代码

自定义check样式

使用label与checkbox进行相关联,而后将checkbox隐藏起来,最后经过设置label伪元素的样式来顶替checkbox的样式。

建立蒙层

传统作法:建立一个额外HTML元素来设置为蒙层。

新的思路:
方法一:经过body上的伪元素来设置为蒙层。
缺点:伪元素没法绑定独立的JS事件处理函数以及对于元素的z-index设置可能会出现误差。

方法二:经过box-shadow来设置蒙层。box-shoadow: 0 0 0 50vmax rgba(0,0,0,.8)
缺点:只能覆盖当前窗口,页面若是滚动就会露馅以及没法阻止用户与页面其余元素交互。

方法三:使用dialog元素backdrop伪元素能够只能蒙层。
缺点:要考虑backdrop伪元素的兼容性。

弹出窗口背景模糊

实现效果相似毛玻璃效果,只是模糊的不是一张背景图片而是页面上的任意元素。
方法一:页面的元素所有包裹在一个div中,dialog与这个div同级,dialog弹出的时候,将这个div添加上模糊滤镜blur().

滚动提示

方法一:
一、background-attachment:scroll可使的背景图片随着元素滚动而固定在元素上,所以能够在滚动的时候建立一个渐变阴影。这样滚动的时候上方都会存在一个阴影。
二、background-attachment:local可使背景图片相对于元素的内容固定,所以能够建立一个白色遮罩层当用户滚动到顶部的时候遮挡住阴影。

ul {
	overflow: auto;
	background: linear-gradient(white 15px,rgba(255,255,255,0)),
		radial-gradient(at top, rgba(0,0,0,.9), transparent 70%);
	background-repeat:no-repeat;
	background-size:100% 50px,100% 15px;
	background-attachment: local, scroll;
}
复制代码

交互式图片对比

方法一:将两张图片重叠在一块儿,而后经过resize:horizontal来调节覆盖在上层的图片width。

<div class="image-slider">
	<div>
		<img src="https://user-gold-cdn.xitu.io/2019/5/2/16a777e69b3ab1e4?w=400&h=400&f=jpeg&s=57981" alt="Before" />
	</div>
	<img src="https://user-gold-cdn.xitu.io/2019/5/2/16a777e6a9e65856?w=400&h=400&f=jpeg&s=63250" />
</div>

.image-slider {
	position:relative;
	display: inline-block;
}

.image-slider > div { /* 覆盖在上层的图片 */
	position: absolute;
	top: 0; bottom: 0; left: 0;
	width: 50%;
	max-width: 100%;
	overflow: hidden;
	resize: horizontal;
}

.image-slider img {
	display: block;
	user-select: none;
}
复制代码

第七章 结构与布局

自适应内部元素

width与height中存在一些关键词,其中width:min-content将会解析为这个容器内最大的不可断行元素的宽度(即最宽的单词、图片和具备固有宽度的盒元素)

<figure>
	<img src="https://user-gold-cdn.xitu.io/2019/5/2/16a777e6a9e65856?w=400&h=400&f=jpeg&s=63250" />
	<figcaption>
		The great Sir Adam Catlace was named after Countess Ada Lovelace, the first programmer ever.
	</figcaption>
</figure>

figure {
	max-width: 300px; /* 兼容回退处理 */
	max-width: min-content;
	margin: auto;
}

figure > img { max-width: inherit }
复制代码

精确控制表格样式

经过table-layout:fixed可以让咱们更加自由的控制表格中的种种样式。

根据兄弟元素数量/范围设置样式

一、只有1个子元素

li:only-child { /* code */}
或
li:first-child:nth-last-child(1) {/* code */ } /* 元素是第一个元素同时也是最后一个元素,就等同于只有一个元素 */
复制代码

二、判断有多少个元素

li:first-child:nth-last-child(4) {/* code */ } /* 元素是第一个元素同时也是倒数第四个元素,就等同于一共有四个元素 */
li:first-child:nth-last-child(4)~ li {/* code */} /* 当列表只有4个元素时,为列表设置样式 */
复制代码

三、根据兄弟元素范围

li:first-child:nth-last-child(n+4)~ li {/* code */} /* n能够为任何数,表示当列表至少含有4个元素时,为列表设置样式 */
li:first-child:nth-last-child(-n+4)~ li {/* code */} /* n能够为任何数,表示当列表最多含有4个元素时,为列表设置样式 */
li:first-child:nth-last-child(n+2):nth-last-child(-n+6)~ li {/* code */} /* n能够为任何数,表示当列表含有2~6个元素时,为列表设置样式 */
复制代码

满幅的背景,定宽的内容

传统作法:外层的html元素设置为满幅的背景,而后内层html设置为定宽居中的内容。
缺点:须要额外一层html元素。

新的思路:经过calc()函数来设置内容的左右边距,使其定宽居中。

outer {
	padding:0 calc(50% - 450px);/* 经过calc()函数计算内容居中时元素的左右边距;450px为内容定宽900px/2计算获得 */
}
复制代码

垂直居中

CSS 技巧篇(七):设置元素居中

紧贴底部的页脚

方法一:设置mai主体元素的min-height为窗口高度减去footer的高度。

.main {
	min-height:calc(100vh - 100px) /* 100px为footer的高度*/
}
复制代码

缺点:要求footer的高度必须是固定已知的。

方法二:将body元素设置为flexBox,而后设置main主体元素设置为flex:1。

body {
	display:flex;
	flex-flow:colum;
	min-height:100vh;
}
.main {
	flex:1;
}
复制代码

第八章 过渡与动画

缓动效果

在animation或者transition中的调速参数除了ease等关键词以外,还能够经过cubic-bezier()函数自定义调速函数。
cubic-bezier()函数在线调试能够前往贝塞尔曲线在线调试。

逐帧动画(以loading动画为例)

传统作法:设置为一张gif图片。
缺点:gif没法设置为透明而且没法修改动画的属性。

新的思路:将动画划分为逐帧的图片,而后经过animation对图片进行过渡切换,steps()可以将动画切分为多帧,并且是帧与帧之间的硬切。

@keyframes loader {
	to { background-position: -800px 0; }
}

.loader {
	width: 100px; height: 100px;
	text-indent: 999px; overflow: hidden; /* Hide text */
	background: url(http://dabblet.com/img/loader.png) 0 0;
	animation: loader 1s infinite steps(8);
}
复制代码

闪烁效果

方法一:动画的50%设置为transparent,这样动画就造成了从有->无→有的变化。

@keyframes blink { 50% { color: transparent } }
.blink-smooth {
	animation: 1s blink 3;
}
复制代码

方法二:经过animation中的animation-direction:alternate属性可以设置动画的循环周期。

@keyframes blink { to { color: transparent } }
.blink-smooth {
	animation: .5s blink 6;
	animation-direction: alternate;
}
复制代码

打字动画

一、经过animation和steps控制width的值,将字符一个个的显示出来;
二、经过border-right来创造光标;
三、ch能够表示为每个字符的宽度。

@keyframes typing {
	from { width: 0 }
}

@keyframes caret {
	50% { border-right-color: currentColor; }
}

h1 {
	/*width: 8.25em;*/
	width: 15ch; /* ch单位为每一个字符的宽度。 */
	white-space: nowrap; /* 禁止内容换行 */
	overflow: hidden;
	border-right: .05em solid transparent; /* 经过border-right来创造光标 */
	animation: typing 8s steps(15),   /* 打字动画 */
	           caret 1s steps(1) infinite; /* 光标动画 */
}
复制代码

沿环形路径平移的动画

方法一:在图片外在包裹一层div,div为顺时针围绕一个大圆的圆心正常旋转,而img则是相对自身中心逆时针旋转来抵消外部旋转。

<div class="path">
	<div class="avatar">
		<img src="https://user-gold-cdn.xitu.io/2019/5/2/16a777e684aa60d7?w=400&h=400&f=jpeg&s=63250" />
	</div>
</div>

@keyframes spin {
	to { transform: rotate(1turn); }
}

.avatar {
	animation: spin 3s infinite linear;
	transform-origin: 50% 150px;
}

.avatar > img {
	animation: inherit;
	animation-direction: reverse;
}

/* Anything below this is just styling */

.avatar {
	width: 50px;
	margin: 0 auto;
	border-radius: 50%;
	overflow: hidden;
}

.avatar > img {
	display: block;
	width: inherit;
}

.path {
	width: 300px; height: 300px;
	padding: 20px;
	border-radius: 50%;
	background: #fb3;
}
复制代码

方式二:经过translate的移动来顶替transform-origin的效果

<div class="path">
	<img src="https://user-gold-cdn.xitu.io/2019/5/2/16a777e684aa60d7?w=400&h=400&f=jpeg&s=63250" class="avatar" />
</div>

@keyframes spin {
	from {
		transform: 
				   translateY(150px) translateY(-50%)
				   rotate(0turn)
		           translateY(-150px) translateY(50%)
		           rotate(1turn)
	}
	to {
		transform: 
				   translateY(150px) translateY(-50%)
				   rotate(1turn)
		           translateY(-150px) translateY(50%)
		           rotate(0turn);
	}
}

.avatar {
	animation: spin 3s infinite linear;
}

/* Anything below this is just styling */

.avatar {
	margin: 0 auto;
	display: block;
	width: 50px;
	border-radius: 50%;
	overflow: hidden;
}

.path {
	width: 300px; height: 300px;
	padding: 20px;
	border-radius: 50%;
	background: #fb3;
}
复制代码

总结 总结正文

相关文章
相关标签/搜索