前言
本文主要是对CSS常用的知识点进行梳理和复习。本文主要内容为:
- CSS3核心思想
- 响应式
- 堆叠上下文
- 常见布局:float布局、flex布局、grid布局
- 常见动画:Fullpage、轮播、3D变化
- 常见组件:表单美化常用工具
- CSS必背知识
CSS3核心思想
从历史角度
问:你知道CSS的发明者是谁吗? 答:???👉🏻 维基百科
以上是用谷歌搜索出来的答案。
在没有 CSS 之前, HTML 自己是自带属性的👇
那个时候的需求不复杂,大家只是写写文章,后来大家对样式的的要求越来越复杂,现有的 HTML 无法满足,于是大家就想有没有一个东西可以选到这个标签,于是就有了选择器的概念,故而发明了选择器、属性、值,可是这些远远不能满足当时的需求,于是乎浏览器就自己加属性,但是大部分人不会CSS,为了让学术工作者可以专心的写文,于是CSS直接引入就可以自动改变了样式
css 主要用来 写文章 和 打印文章 media="print" 你要啥功能我就加啥属性,于是便有了颜色属性、图文混排(float: left)、绝对定位... CSS的很多属性(效果)都是可以抄出来的(不需要复杂的逻辑)
不正交的表现
- 各属性之间相互影响
- margin V.S. border
margin合并问题,为啥加了border就不会合并了???一开始不和并不行吗?我改border,为何会变margin,一开始不合并不行吗?
为何display:table /display:flex 会隔开呢?
父元素没加 border 前
加了后
这里有篇关于 BFC 的文章 👉🏻 你或许会找到答案 「BFC」块级格式化上下文 到底是个啥???
-
小圆点 V.S. display display 默认
display: list-item;我把它改成别的 display 其他的属性,小圆点就不见了 -
position: absolute V.S. display: inline 被position后,它只改变 inline inline-block
为啥那么反人类呢?
- 各元素之间相互影响
- position: fixed V.S. transform
正常来说它应该在左下角的,可是为啥加了 transform 后,明明是 fixed 定位, 为啥你还给我加了绝对定位的东西?为啥就不能出现在我想要的地方呢?
- float 影响 inline 元素
为啥文字会被浮动元素影响?
最初浮动元素是用来做文图混排的,需求就是文字环绕图片,故 hone 就会自动去寻找浮动元素的边缘去环绕着它。
那它为啥不影响它旁边的div啊?因为它浮动了啊,那为啥浮起来了还能影响这个div的内容?因为浮动元素的初心在一开始并没有想做成真正的浮动,只是为了做图文混排(通过float属性来实现),这个名字会让我们以为它浮起来了,实际它没有浮起来。
CSS学习的简单点
背一些基本套路
- 水平居中 在块级元素中
- child 宽度不确定,
margin-left:20px; margin-right:20px; - child 宽度确定,
margin-left:auto; margin-right:auto;
在行内块元素中:text-align: center;
- 垂直居中
时刻避免parent高度确定的情况
👉🏻 垂直居中的10种法子 点这里
兼容 IE 用table ,其他的都可以用 Flex
使用工具
- CSS 3 Generator
- 盒子阴影
- clip 还有很多我就不一一介绍了...
宽度与高度
如果CSS里面有大量的宽度、高度,那么CSS就是有问题,因为对CSS的高度和宽度理解的不深刻。
文档流(Normal Flow)
块级元素/内联元素的宽高
- 请问以下元素的高度是多少?
- 你会想到是这个吗?那是啥导致的?行高吗?
- 来看看
是nomal!!!,假设是它导致的,那么 28.8/20 = 1.44, 行高默认 1.44, 这对吗? 我认为这种推理不严谨, 如果换一个字体呢?
以下是默认字体改成 Tahoma 后
是的,你没有看错,它变了🙃,那么是因为不同字体对应的行高不一样吗?
那每一种字体对应的行高是多少???😳😳😳 🚑🚑🚑🚑
首先我们要知道字体相关知识: - 字和字之间是通过基线对齐的,而不是中线对齐的
- 两排字的时候就会挨在一起
- 故而设计师在设计字体的时候会给一个建议行高
于是得到了默认的行高就是字体设计师写进去的建议行高。 这就是为啥写
font-size: 20px的时候,它div的高度却是一个不确定的值。为啥呢?因为上面的28.8是由字体的设计师建议的,要想写死的话给一个line-height: 30px那么它就不会变。
结论
当我们在 div 里面写一个 1 的时候,那么这个 div 的高度是由 (是由这个字的字体) + (它建议的行高) 确定的,跟这个字有多大没关系。
这个 div 的高度是由行高确定的。
如果 div 里面只有一个内联元素,那么 div 的高度,就是这个内联元素这一行的行高,这一行(行盒)。
为啥我打了很多空格,它只显示一个空格,因为 html 会把它多的空格给缩起来, 给它加上
(no break space)它就可以空两行,或者用全角空格。不同字体的空格宽度是不一样的,不同字体空格的宽度是由设计师确定的。
text-align: justify;
多行文字,没给这个属性是没有靠边的
加了后
那么又「该如何让 姓名 两端对齐呢?」
使用 :after
姓名两端对齐详细代码:
👉🏻 链接
在看 👇,一个回车两个空格,最终变成了一个空格
这就是 HTML 的特点,它会把所有内联元素之外的删掉,不显示在页面里,同时内联元素(inline、inline-block)之间的所有看不见的字符全部都显示成一个空格。
举例:ul列表的问题 👇
那如何解决? 那就不要用 inline-block 👇
如果内联元素足够多,那么一行容不下就会自动换行,这就叫做文档流。
在看一个例子
为啥会出现这种情况?
中文里的你好写成字母nihao,在中文的意思是两个字,而在英文的意思是1个字,上面的 ahhhh... 被识别为一个字,不过现实中没有这么长的英文,实在不行可以加连字符(-),加了连字符浏览器就会知道这是两个字。
那我可以从不加连字符也可以使其断开吗?
使用 word-braek: break-all; 意思是该什么时候断就什么时候断,不用管它是不是一个整体。
总结
当一个div里面只有内联元素的时候,div的高度是由什么确定的呢?如果是一行内容主要是由这一行的行高确定的,如果有多行内容,就是吧每一行的行高加起来一起算,如果中间有一串很长的字,那就用work-break: break-all。
解决中文文字不对齐
p{
text-align: justify;
}
文字溢出省略(多行)
div的宽度不是有文字绝定的
单行文本溢出省略
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
多行文本溢出省略
直接在谷歌搜 css multiple line ellipsis
3行
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
2行
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
适配IE的(不管了)
文字垂直居中
以上这种法子是可以让文字垂直居中,但是它有一个问题,一旦字多了(把单行省略去掉)就会出现以下情况 👇。
丑的很嘞,代码写的太死了,采用以下写法,文字就居中了
这样写的好处就死不会出现前面的那种bug
那么也就是说:高度 = 行高 + 上下内边距, 不要把高度写死!!!
margin合并
加margin 之前
加margin 之后
它没有变高!!!margin 合并了
如果父元素没有什么东西挡住 margin ,那么子元素的外边距就会和父元素的上下外边距合并
如果一个 div 里面,还有 div ,那么这个 div 的高度,就是由它里面 div 的高度 + padding + margin。
那么该如何取消合并? 加个 padding 就可以了,其他的比如overflow: hidden 不建议使用,会用副作用
max/min-content及fit-content等width值
width:fit-content可以实现元素收缩效果的同时,保持原本的block水平状态
堆叠上下文
堆叠顺序
- background
- border
- 块级
- 浮动
- 内联
- z-index: 0
- z-index: +
如果是兄弟元素重叠,那么后面的盖在前面的身上 👉🏻 代码链接
堆叠上下文
MDN堆叠上下文 可以理解为堆叠作用域,就和 BFC 一样,无法定义,但是知道一些属性会触发堆叠上下文。
-
文档根元素(
<html>); -
position值为absolute(绝对定位)或relative(相对定位)且z-index值不为auto的元素; -
position值为fixed(固定定位)或sticky(粘滞定位)的元素(沾滞定位适配所有移动设备上的浏览器,但老的桌面浏览器不支持); -
flex (
flexbox(en-US)) 容器的子元素,且z-index值不为auto; -
opacity属性值小于1的元素(参见 the specification for opacity); -
mix-blend-mode属性值不为normal的元素; -
以下任意属性值不为
none的元素: -
isolation属性值为isolate的元素; -
-webkit-overflow-scrolling属性值为touch的元素; -
will-change值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素(参考这篇文章); -
contain属性值为layout、paint或包含它们其中之一的合成值(比如contain: strict、contain: content)的元素。
堆叠上下文主要影响z-index
移动端页面
配置环境:
npm i -g http-server
http-server -c-1
媒体查询
@media (max-width: 800px){}如果媒体宽度满足 0~800px 之间就对其查询@media (min-width: 801px){}如果媒体宽度满足大于 800px 就对其查询@media (min-width: 320px) and (max-width: 375px){}如果媒体宽度满足 320~375px 就对其查询<link rel="stylesheet" href="style.css" media="(max-width: 320px)">只有在设备满足最大宽度为320px的时候才会生效(提前下载好在满足这个条件时 link 才会生效)
meta viewport
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
视口
宽度=设备的宽度
用户是否可以缩放:不要
初始缩放倍数/最大缩放倍数/最小缩放倍数 1.0 \
viewport-fit=cover (为了适配iPhoneX)
iOS11 新增特性,苹果公司为了适配 iPhoneX 对现有 viewport meta 标签的一个扩展,用于设置网页在可视窗口的布局方式,可设置三个值:
- contain: 可视窗口完全包含网页内容(左图)
- cover:网页内容完全覆盖可视窗口(右图)
- auto:默认值,跟 contain 表现一致
Flex布局
对于flex布局google一哈,大家都有系统的总结
我这里经常看的是天天写的 👉🏻链接🔗
然后在给大家推荐一些练习网站:
说到CSS那肯定的要看一下 张鑫旭 的博客了
- flex 布局
- flex属性深入理解 以下是对里面的文章做的大概梳理,详情请看张鑫旭大大的博客 👉🏻 点这里
使用flex布局的小效果:
Flex之前
主要使用的布局
- normal flow
- float + clear
- position relative + absolute
- display inline-block
- 负 margin
Flex到来
- 块级布局侧重垂直方向、行内布局侧重水平方向,flex布局与方向无关的
- flex布局可以实现空间自动分配、自动对对齐(flexble: 弹性、灵活)
- flex布局适用于简单的线性布局,更复杂的布局要交给 grid 布局
基本概念
flex container 的六个属性
- flex-direction 方向 (默认 row, 从左到右排)
parent 加了 flex-direction: row-reverse;属性,从右到左排
parent 加了 flex-direction: column;属性,从上往下排
parent 加了 flex-direction: column-reverse;属性,从下往上排
- flex-wrap 换行(flex默认不换行)
parent 加了
flex-wrap: wrap;属性, 换行显示
- flex-flow 上面两个的简写
- justify-content 主轴方向对齐方式
justify-content: center
justify-content: space-between
justify-content: space-around
justify-content: flex-start
justify-content: flex-end
- align-items 侧轴对齐方式
align-items: stretch;默认值,在高度没有写死的情况下,把所有的元素伸开(和最高的元素一样高)align-items: flex-start;所有的元素往侧轴的起点靠,不要延伸
align-items: center; 垂直居中,往中间靠,不要延伸
- align-content 多行/列 内容对齐方式
align-content: space-between;
align-content: flex-start
align-content: flex-end;
flex item 的六个属性
- flex-grow 增长比例(空间过多时)
flex-grow: 1;它吃独食,剩余空间它都占了
按比例分配剩余空间
-
flex-shrink 收缩比例(空间不够时)
flex-shrink: 0;经常用于图文混排的时候,让图片不flex。 -
flex-basis 默认大小(一般不用) 不写的话就是原始大小,写了这个属性就是按照它给的大小分配
-
flex 上面3个的缩写 flex: flex-grow flex-shrink flex-basis
flex: 1 2 100px
这个元素,在涨的时候它吃1份,缩的时候是它吐2份,原始100px -
order (顺序,代替双飞翼)
以上是各大浏览器的兼容性
- align-self 自身的对齐方式
可以让每个孩子,自己选择自己的对齐方式
例子
1.手机页面布局(topbar + main + tabs)
链接
2. 产品列表(ul>li*9)
使用flex布局的justify-content: space-between
3. pc页面布局
链接
4. 完美居中
display: flex;
justify-content: center;
align-items: center;
Grid布局
概述
CSS网格布局(Grid Layout),一个二维系统,先定好网格在摆放元素,可以同时处理行列
参考文献
雷切尔·安德鲁(Rachel Andrew)
Chris Coyier
Grid容器的孩子(grid item)类似于 ul>li{} 而不是 ul li{}
网格线(grid line)虚拟的网格线
相邻网格线(grid track)
网格单元(grid cell)
网格区域(grid area)
针对父级设置网格线,把这一片区域进行逻辑划分,然后对于子元素让它放到哪个盒子上/哪些格子上,去做一个适当的对齐
Grid属性列表
Grid Container 的全部属性(设置网格相关信息)
- display
- grid-template-columns
- grid-template-rows
- grid-template-areas
- grid-template
- grid-column-gap
- grid-row-gap
- grid-gap
- justify-items
- align-items
- justify-content
- align-content
- grid-auto-columns
- grid-auto-rows
- grid-auto-flow
- grid
Grid Items 的全部属性(设置自己的位置/排列方式)
- grid-column-start
- grid-column-end
- grid-row-start
- grid-row-end
- grid-column
- grid-row
- grid-area
- justify-self
- align-self
如何使用Grid布局
1.display(定义Grid属性)
- grid - 生成一个块级(block-level)网格
- inline-grid - 生成一个行级(inline-level)网格
- subgrid - 如果你的 grid container 本身就是一个 grid item(即,嵌套网格),你可以使用这个属性来表示你想从它的父节点获取它的行/列的大小,而不是指定它自己的大小。
.container {
display: grid | inline-grid | subgrid;
}
注意:column, float, clear, 以及 vertical-align 对一个 grid container 没有影响
2.grid-template-columns / grid-template-rows(设置网格列/行)
.container {
grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
grid-template-rows: <track-size> .. . | <line-name> <track-size> ...;
}
例子:
(如果未显示的给网格线命名),轨道值之间仅仅有空格时,网格线会被自动分配数字名称:
.container {
grid-template-columns: 40px 50px auto 50px 40px;
grid-template-rows: 25% 100px auto;
}
fr
fr可以将轨道大小设置为网格容器自由空间的一部分。 例如,下面的代码会将每个 grid item 为 grid container 宽度的三分之一:
.container {
grid-template-columns: 1fr 1fr 1fr;
}
自由空间是在排除所有不可伸缩的 grid item 之后计算得到的。 在下面的示例中,fr单位可用的自由空间总量不包括50px:
.container {
grid-template-columns: 1fr 50px 1fr 1fr;
}
3.grid-template-areas (网格如何摆放)
通过引用 grid-area属性指定的网格区域的名称来定义网格模板。 重复网格区域的名称导致内容扩展到这些单元格。 点号表示一个空单元格。 语法本身提供了网格结构的可视化。
值:
<grid-area-name>- 使用 grid-area 属性设置的网格区域的名称.- 点号代表一个空网格单元- none - 没有定义网格区域
<div class="container">
<div class="header">header</div>
<div class="main">main</div>
<div class="aside">aside</div>
<div class="footer">footer</div>
</div>
.container {
height: 100vh;
border: 1px solid red;
display: grid;
grid-template-columns: 10% auto 10%;
grid-template-rows: 50px auto 50px;
grid-template-areas:
"header header header"
". main aside"
"footer footer footer"
}
.header {
grid-area: header;
background: red;
}
.main {
grid-area: main;
background: blue;
}
.aside {
grid-area: aside;
background: yellow;
}
.footer {
grid-area: footer;
background: grey;
}
声明每一行有相同数量的单元格。
.来声明单个空单元格。 点号之间没有空格,代表了一个单一的单元格。
这个是在命名区域。 区域两端的网格线实际上是自动命名的。
grid-template
grid-template-rows、grid-template-columns、grid-template-areas的简写
grid-template-columns: 10% auto 10%;
grid-template-rows: 50px auto 50px;
grid-template-areas:
"header header header"
". main aside"
"footer footer footer"
以上简写为👇
grid-template:
"header header header" 50px
". main aside" auto
"footer footer footer" 50px
/ 10% auto 10%
"header header header" 50px指的是每一列都是header, 每行高度 50px
". main aside" auto 第一列是空单元格 第二列是 main 第三列是 aside,这一行的高度 auto
"footer footer footer" 50px 指的是每一列都是 footer,每行高度 50px
/ 10% auto 10% 这个的意思就是 行比例为 10% auto 10%
grid-column-gap / grid-row-gap 行列之间的缝隙
grid-column-gap: 10px;
grid-row-gap: 15px;
grid-column-gap 每一列
grid-row-gap 每一行
grid-gap grid-row-gap 和 grid-column-gap 的缩写
justify-items 水平方向
align-items 垂直方向
值:
- start: 内容与网格区域的左端对齐
- end: 内容与网格区域的右端对齐
- center: 内容位于网格区域的中间位置
- stretch: 内容宽度占据整个网格区域空间(这是默认值)
justify-content (网格容器内的网格的对齐方式)
类似 flex 布局的 justify-content
值:
- start - 网格与网格容器的左边对齐
- end - 网格与网格容器的右边对齐
- center - 网格与网格容器的中间对齐
- stretch - 调整g rid item 的大小,让宽度填充整个网格容器
- space-around - 在 grid item 之间设置均等宽度的空白间隙,其外边缘间隙大小为中间空白间隙宽度的一半
- space-between - 在 grid item 之间设置均等宽度空白间隙,其外边缘无间隙
- space-evenly - 在每个 grid item 之间设置均等宽度的空白间隙,包括外边缘
align-content类似 flex 布局的align-content
grid-auto-columns / grid-auto-rows
指定自动生成的网格轨道(又名隐式网格轨道)的大小
.item-a {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.item-b {
grid-column: 5 / 6;
grid-row: 2 / 3;
}
.container {
grid-auto-columns: 60px;
}
指定隐式轨道的宽度
grid-auto-flow
值:
- row - 告诉自动布局算法依次填充每行,根据需要添加新行
- column - 告诉自动布局算法依次填充每列,根据需要添加新列
- dense - 告诉自动布局算法,如果后面出现较小的 grid item,则尝试在网格中填充空洞
.item-a {
grid-column: 1;
grid-row: 1 / 3;
}
.item-e {
grid-column: 5;
grid-row: 1 / 3;
}
.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: column;
}
Grid Items
.item-a {
grid-column-start: 2;
grid-column-end: five;
grid-row-start: row1-start;
grid-row-end: 3;
}
.item-b {
grid-column-start: 1;
grid-column-end: span col4-start;
grid-row-start: 2
grid-row-end: span 2
}
grid-column / grid-row
.item-c {
grid-column: 3 / span 2;
grid-row: third-line / 4;
}
grid-area
给一个网格项命名
.item-d {
grid-area: header
}
作为 grid-row-start + grid-column-start + grid-row-end + grid-column-end 的简写:
.item-d {
grid-area: 1 / col4-start / last-line / 6
}
justify-self
.item-a {
justify-self: start;
}
.item-a {
justify-self: end;
}
.item-a {
justify-self: center;
}
.item-a {
justify-self: stretch;
}
align-self
.item-a {
align-self: start;
}
.item-a {
align-self: end;
}
.item-a {
align-self: center;
}
.item-a {
align-self: stretch;
}