CSS (Cascading Style Sheet) 是通过一组一组的样式规则,来指定 HTML 元素的样式。入门 CSS 的时候,经常会遇到这样的问题。
为什么这个元素不在这里出现?为什么这个元素会在这里出现?
一、钦点(CSS 选择器)
CSS 要决定修改哪个元素的样式,就需要对 HTML 节点进行钦点(选择)。
CSS 中主要用到的有以下选择器:
- 元素选择器
- ID 选择器
- 类选择器
- 属性选择器
- 伪类选择器
其中,属性选择器可以选择具备某些属性值的 HTML 标签。
img[src] {
width: 100px;
height: 100px;
}
以上示例中,我们选择了所有具有 src 属性的 img 标签。即所有的 <img src="">。
二、子承父业(层叠与继承)
先来看一个简单的例子。在 HTML 中有一个简单的 div。
<div class="demo"></div>
.demo {
width: 100px;
height: 100px;
/* 先设置红色背景 */
background-color: red;
}
.demo {
/* 再设置蓝色背景 */
background-color: blue;
}
See the Pen Cascading & Inheriting by Yiyang Sun (@syycn)
on CodePen.
可以通过 codepen 看到,最终这个 div 显示的颜色为 蓝色。
给这个蓝色的 div 加一个红色的边框,设置字体颜色为白色,再给其中放入一个 span 会是什么效果?
<div class="demo2">
<span>我是 span</span>
</div>
.demo2 {
width: 100px;
height: 100px;
background-color: blue;
border: 10px solid red;
color: white;
}
span {
}
可以看到,字体颜色 和 背景颜色 继承了父元素的样式,而 边框 并未默认继承样式。
除此之外,还有一些其他的特性,可以在 codepen 上进行探索。
简单总结一下:
- 选择器越具体,优先级越高
- 后出现的样式会覆盖前面出现的样式
color、background-color等属性会默认继承父元素样式,border属性不会默认继承父元素的样式。
三、盒模型
说起 CSS,不得不提起一个重要的概念,那就是 盒模型。
我们可以把网页上的元素想象成一个个盒子,这个盒子由以下四个部分组成:
- 外边距 - margin
- 边框 - border
- 内边距 - padding
- 内容 - content
在开发过程中,常接触到两种盒子:
content-boxborder-box
两者的区别主要体现在盒子长宽的计算上。
这里盒子的长宽指的是
border之间的距离(含border)。
3.1 content-box
.box {
box-sizing: content-box;
margin: 10px;
border: 5px solid black;
padding: 20px;
width: 40px;
height: 30px;
}
对于上面这个盒子而言,它的宽度为 (5px + 20px) * 2 + 40px = 90px,它的高度为 (5px + 20px) * 2 + 30px = 80px。也就是说,我们在 CSS 中设置的 width 和 height 属性,并不是盒子真实的宽高,而是 content 区域的宽高。
3.2 border-box
.box {
box-sizing: border-box;
margin: 10px;
border: 5px solid black;
padding: 20px;
width: 40px;
height: 30px;
}
在日常开发中,我们希望所设置的 width 和 height 的值就是盒子真实的宽高,就可以使用 border-box。
如果我们让 border-box 的 padding 或 border 的总宽度和总高度恰好与 width 和 height 相等,会发生什么呢?
感觉很是神奇,当边框或内边距单独变得很大时,会侵占 content 区域的空间;当它们的总宽高大于 width 和 height 时,这个宽高值的设置就不起作用了,多出来的部分会向外扩展。
The content box can't be negative and is floored to 0, making it impossible to use border-box to make the element disappear. [1]
这是 MDN 上的一段话,意思是 border-box 中,content 区域不能为负值,最小值是 0,这使得不能使用 border-box 来让元素消失。
这也就解释了为什么 padding 或者 border 过宽时,会向外扩展。
四、布局
常用的布局方式有两种:
- 弹性布局 (Flex)
- 定位 (Position)
关于 Flex 布局和 Position 布局,其最大的区别是 Position 布局有可能使元素脱离文档流。脱离文档流的元素,其任何样式上的变化不会引起 重绘和回流。
关于这两种布局方式,回头可以单独整理一下其中常用的属性值,先在这里挖一个大坑 🕳。
五、装饰
对 HTML 的装饰主要包括以下几种:
- 字体相关
- 背景
- 阴影
- 交互相关 (hover 等)
- 动画
其中,阴影和 CSS 3 的动画是两门很深的学问。当下比较火的 新拟态 就是巧妙利用的光影,模拟真实世界;而有一些比较炫酷的动画效果是可以通过 CSS 来实现的。
这里推荐一位 B 站的 Up 主,CodingStartup 起码课。他经常会更新一些有趣的前端小 demo。
六、CSS 发展
6.1 调试 CSS
平时在编写 CSS 样式的时候,如果改一次参数,跳转到浏览器看一下效果,不合适再改,这样效率会比较低下。
推荐的方法是使用浏览器的开发者工具,选中某个节点直接进行对其样式进行修改,可以实现实时修改,实时预览。
6.2 CSS 扩展
现在有比较流行的 CSS 预处理器,例如 SCSS 或 LESS。这些 CSS 预处理器很好地实现了样式的嵌套,便于代码的维护。
不过 CSS 原生似乎也在向这个方向前进,最近 CSS 原生嵌套语法在前端社区中比较火,未来如果 CSS 支持了嵌套语法,这些预处理将何去何从,我们拭目以待。
6.3 CSS 革新
革新主要分为两类:
css-in-jsutility-class
第一种是把 CSS 集成到 JS 中进行编写和管理。
第二种是 语义化类名,以 tailwind 为代表。一个 CSS 类名对应一种特定样式,这样只需要在 HTML 中写类名,而不需要重复编写样式代码。
语义化类名通过限制 CSS 样式的可选择性,来提升对 CSS 代码的管理。
七、小结
参加 字节青训营,听行业内的大牛们讲课,深感知识积累以及基础的重要性。
通过简单整理 CSS 相关的知识,我学习到了第一次粗略学习时没有关注到的点。
温故而知新~