CSS学习笔记
最近开始学习前端相关的知识,第一站肯定是 HTML+CSS 了。在这里记录下一些常用的 CSS 技巧和代码片段,当做一个学习的总结,也供今后查阅参考。
强烈推荐Free Code Camp,我就是通过这上面的练习题,边做边学习 CSS 的,非常适合基础较差的、甚至零基础的人学习前端开发技能。
由于刚开始学习 CSS,可能记录的内容会有错误或者局限性很大,我后面会持续更正这些内容。
使用 element ui 或者 andt design,主题就用默认得就好了,记住几个口诀:padding margin 取值 8px 16px 24px,font-size:12px 14px 16px,color:#333 #666 #999 就行了。
因为 css 就不是编程语言,它是查表,从思路上说就和一般概念的编程语言就不一样。
而且 css 这个鬼玩意,它本质不是为 GUI 系统设计的,它最初的出发点是做排版系统,排版系统和 GUI 系统有交集,但并不是一回事,有点像轿车和皮卡的关系。现代 web 开发更多是做 GUI ,做展示页(排版)的时候比较少。这存在不匹配的阻尼。
然后就是 CSS 最初的设计者,按照她自己的说法,她的设计更符合排版系统的需求——她把 CSS 设计成了一个非正交系统。什么叫非正交呢?所谓正交的系统,你动了 A ,不会影响到 B。但是非正交系统不是,你动了 A ,B 会跟着跑,但是它还不会直观的告诉你,你得凭经验。CSS 里到处都充斥这种和“隐藏条件”一样的玩意,导致 CSS 的开发,必须背表,大约有几十种组合,如果这个人对这些表背的滚瓜烂熟,用的随心所欲,那它就不会对 CSS 产生任何怀疑。问题是这种思路它就不是传统编程的思路。即使是前端,也没几个真敢说自己对 css 很熟练的,证据就是这些前端在拿到一个别人开发的,布局有问题的界面时,他们绝大部分时候的选择,就是干脆的自己重新写一遍 css ,而不是像传统编程开发那样,去 debug 一下找到有问题的代码在哪里。CSS 是很难 debug 的,因为非正交的原因,造成当前问题的原因可能是十万八千里之外的一个盒子的输入参数,这种隐藏条件在 CSS 里比比皆是。
一般来说,熟悉 java 的,学习 js 的一点都不难,但是要搞定 CSS 就千难万难。而我见过那种真能熟练 CSS 的的人,他自述它写 CSS 的时候戴着耳机听歌,但是写 JS 的时候就不敢。注意证明这玩意有多大的思维鸿沟,你擅长一边,就很难擅长另外一边。所以这是壁垒。
– https://www.v2ex.com/t/1043871#reply17
“非正交”指的是 CSS 的层叠性质,即多个样式规则可以应用于同一个元素,最终的样式由这些规则的优先级决定。这确实给 CSS 的学习和使用带来了一定的复杂性。
工具网站
CSS 速查手册
http://css.cuishifeng.cn/index.html
浏览器兼容性检查
https://caniuse.com/#search=grid
配色
icon
阿里妈妈的矢量图标:https://www.iconfont.cn/
zwoelf(我还没用过):https://www.zwicon.com/
奇技淫巧
笑脸猫动画、立方体旋转、酷炫 button、3D 照片墙:
https://zhuanlan.zhihu.com/p/24368907
其他
https://enjoycss.com/ css 动画效果
https://webframe.xyz 提供精美的 Web 页面并加以分类
https://ui.glass/generator/ 毛玻璃效果
https://getwaves.io/ 波浪背景样式生成
https://www.shapedivider.app/ 可控制波浪背景
https://cssarrowplease.com/ 气泡框
https://cssgrid-generator.netlify.app/ grid 布局
https://cssfx.netlify.app/ loading 活动效果 小组件
工具原理
预处理和后处理
可以看这篇文章,讲得比较好:
https://www.html.cn/archives/7317
Sass 和 Less 的区别
用 SCSS 就行了,CSS 风格的 Sass
gulp、grunt、webpack 的区别
gulp 和 grunt 是工具,通过插件实现各种功能
webpack 是模块化方案
可以看下这个知乎回答:https://www.zhihu.com/search?type=content&q=webpack%20gulp%20grunt
单位
1.px:绝对单位,页面按精确像素展示
2.em:相对单位,基准点为父节点字体的大小,如果自身定义了 font-size 按自身来计算(浏览器默认字体是 16px),整个页面内 1em 不是一个固定的值。
3.rem:相对单位,可理解为”root em”, 相对根节点 html 的字体大小来计算,CSS3 新加属性,chrome/firefox/IE9+支持。
4.vw:viewpoint width,视窗宽度,1vw 等于视窗宽度的 1%。
5.vh:viewpoint height,视窗高度,1vh 等于视窗高度的 1%。
6.vmin:vw 和 vh 中较小的那个。
7.vmax:vw 和 vh 中较大的那个。
8.%:百分比
布局
Grid
https://ishadeed.com/article/css-grid-area/#header-layout
应用案例:
PVIS 2025 的多国家地图布局 (Github)
flex 布局
来自这个文章,用动图的形式来解说,太直观了。我感觉今后前端交互方面的技术文章,动图是一个必不可少的因素。
1 | |
水平+垂直居中
参考上面的flex布局,利用 flexbox,水平+垂直居中很简单,只需要容器设置display:flex,然后里面的子元素设置margin:auto即可。《CSS 揭秘》里面提到了一些其他方法,不过目前我有 flex 就足够了。
水平居中
如果自身是一个行内元素,就对其父元素设置text-aling: center;如果自身是块级元素,就对其自身设置margin: auto。
同一行的元素,横向均匀排列
可以用 grid 布局。
也可以直接不用布局,然后将一行中的 2 个 div 的 display 改为 inline,然后分别给个样式,设置左右对齐。
大屏
大屏一般是基于一张背景图进行元素定位的,因此元素的位置可以用绝对定位:
1 | |
技巧
flex 固定每行的元素数量
如果我们要通过 flex 布局进行定位。但是又想固定每行的元素数量,并且每一个元素的宽度是固定的,这个时候可以通过设置复元素的 padding-right 来完成。这个值可以通过 calc 函数来完成,它等于 100%的页面宽度减去单个元素的宽度乘以该行显示的元素个数,详见如下代码:
1 | |
定位
绝对定位
我是看这个文章来学习的,关键知识点:Normal Flow、父容器的 position、逐级上溯。
1 | |
漂浮
设置position:fixed即可,如果要指定漂浮在哪个位置,就再加上上下左右的距离,比如:right: 0px;
边距
margin 和 padding 的选择
这两个我一开始没有搞清楚,不明确在不同的场景下具体该选择哪个。
相邻 margin 的合并
If two adjacent elements both have the margin set on them and the two margins touch, the larger of the two remains, and the smaller one disappears — this is called margin collapsing, and we have met this before too.
比如下面这 2 个相邻的 div,一个 margin-bottom: 100px; 一个 margin-top: 120px ,那么最终只有 margin-top: 120px 生效了。
1 | |
边框
给多个列表元素设置上下边框
如果只设置上边框或者下边框,那么最后一个元素或者最前面的元素会少一道边框;如果上下边框都设置,那么中间的元素会出现宽度 X2 的边框。
为了解决这个问题,我是给每个元素设置了一个下边框,然后给这些元素的父容器设置了一个上边框。
1 | |
色彩
背景
固定不动的背景
body {
background:url(http://i.thsi.cn/images/zcx/blog/life/me_20190915.jpg);
background-repeat: no-repeat;
background-attachment:fixed;
background-position:50% 50%;
background-size:cover;
}
关键配置是background-attachment,默认是 scroll,背景图会随着页面滚动;如果设置为 fixed 则固定不动。
小技巧:可以将背景地址设置为一个可以随机获取图片的地址,比如这个:
https://source.unsplash.com/random/1920x1080
这样每次刷新页面,背景都不一样
阴影
渐变
注意:渐变还未加入规范,因此必须加上浏览器前缀,否则不生效。
https://codepen.io/P1N2O/pen/pyBNzX
background: linear-gradient(direction, color-stop1, color-stop2, …);
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
定义方向+颜色即可。
文档:https://www.runoob.com/cssref/func-linear-gradient.html
另外,SVG 现在还有专门的linearGradient元素,用来定义线性渐变,用于图形元素的填充或描边。
这个似乎用得比较少,有需要的时候再看文档吧:
https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/linearGradient
透明度
通过 rgba()函数来实现:
1 | |
比如设置一个透明渐变的效果,可以这样写:
1 | |
文字
换行
用white-space: pre;即可,可以根据换行符,显示换行效果。
下划线
除了text-decoration,还可以通过border来设置,边距更可控,更美观。
动画
动画一般是用 CSS3 的 animation 来实现的。需要掌握的关键知识点包括:动画实现原理、兼容性、JS 控制 CSS 动效等。
注意:我们的虚拟桌面把动画给关了,需要我们手动开启:https://jingyan.baidu.com/article/db55b6099ed20a4ba30a2f94.html
实现原理
核心在于关键帧,即keyframes。
我是这样理解动画的:从一个状态,过渡(transition)到另一个状态。
可以参考这个文章:https://zhuanlan.zhihu.com/p/50910069
transition
为什么不用 transition?
因为 transition 是一次性的。
animation
animation 的属性如下:
1 | |
transform
transform 可以实现多种效果:
matrix矩阵变换translate位移scale缩放rotate绕轴旋转skew[skju:] 倾斜perspective透视距离
(TODO)3D 透视
https://www.zhihu.com/zvideo/1443883348855259136
兼容性
给不同系统设置不同的样式
比如我最近遇到的一个问题:我的页面在小米 8 上显示 OK,但是再 iPhone 上字体显示非常小。
这种需求可以通过@media来实现,比如下面这个就是兼容 iPhone7 的样式:
1 | |
这里有个文章,罗列了常见的几种 iPhone 的兼容条件: