起源

CSS 究竟是什么?简单的回答是,层级装饰表,能够描述网页上元素的样式形态,例如颜色、大小、布局等等。复杂的回答是,它既是浏览器所支持的样式配置,也是一种配置语言。回到很久很久以前,互联网的初期,人们刚刚创造了XML的小表弟 —— HTML,将其用于构造一个“好看”的网页。人们用不同的元素名,来表示页面上的不同内容,并根据浏览器内置的风格来渲染它们。例如 h1是大字号的黑体,code是等宽的小字,p是分段的正文等等。后来,人们渐渐觉得内置的这些样式无法满足对于好看的追求,浏览器厂商就想,干脆让你们这些些写网页的人自己去配置好了。于是,HTML 元素有了 style 属性,人们可以通过它来修改元素的样式:

<div style="color: green">hello</div>

语法

一个元素没问题,元素一多,这样的配置方法就麻烦了,比如页面上所有的按钮都要统一格式,每个都单独配置肯定不现实。于是 style sheet 应运而生,简而言之就是用单独的文件来保存页面上所有元素的样式配置。CSS 的主要语法很简单,大括号外面的是选择器,表示选中的元素,大括号里面是具体的样式配置:

h1 {
    color: red;
    font-size: 20px;
}

每个样式属性之间,使用分号分割,最后一项可以省略分号。对于分号的位置并没有要求,如果你喜欢,把分号放在行首也是可以的。css 继承了 XML 和 HTML 对于大小写不敏感的特点,当然,为了代码的整洁性,最好还是统一一个大小写的格式:

elEmEnt {
  CoLoR: red
  ;fonT-size: 20px
  ;background-color: green
}

CSS 中唯一的数据类型就是字符串,它不像 JSON,有布尔值、数字这些,CSS里全都是字符串,但记住它们不需要加引号。CSS 里每个属性可以接收一个或多个参数,参数之间用空格分割,例如:

padding: 10px 10px 10px;

选择器

元素名,类,id

刚才我们说了大括号外边那个就是选择器,这让我想起了jQuery 里面的$选择器,其实和那个很类似。基本的规则是:.开头的表示元素的 class, # 开头的表示元素的id,字母开头的表示元素的类型名。注意,class 和 id 都是大小写敏感的,这和元素类型名不一样。

h1 {}
.my-class {}
#my-id {}

如果想同时给多个选择器配置相同的风格参数,那么用,隔开就可以了,表示 “或” 的意思:

.my-class
, #my-id {
  background-color: yellow
}
伪类

选择器还可以添加一些修饰符,例如,表示鼠标悬浮时的风格,在后面加上 :hover 即可,这种单个冒号的修饰叫做伪类(pseudo class):

.my-class:hover {
  color: red
}
伪元素

还有一种,就在后面加两个冒号,叫做伪元素(pseudo element),比如,::first-letter 表示元素内容的首字母:

.my-class::first-letter {
  color: red
}

根据我的实际测试,同时使用时,两个冒号的必须放在一个冒号的后面,也就是 .my-class:hover::first-letter 这样能起效果,反之无效。

转义

如果你的class名称里面带有引号,需要使用\进行转义,例如:

<div class='super:man::class'>c3</div>
.super\:man\:\:class {
  font-size: 50px;
}
属性选择器

接下来是一种最为逆天的选择器,它叫做属性选择器,根据匹配属性的值来进行选择,例如:

    <div group='g1'>c1</div>
    <div group='g2'>c2</div>
    <div group='g3'>c3</div>
[group^=g] {
  color: blue
}

表示选中所有满足其 group 属性以 "g" 开头的元素。

关于选择器就说这么多吧,实际工作中会用到的其实也就很少的几种,主要还是最前面的三种。还有更复杂的结合选择器这里就不讲了,我也不想这篇文章完全变成一个文档的样子,还是希望能多讲一些有意思的想法。那些特别复杂的选择器的存在有其历史原因,我猜测是因为过去网络速度比较慢,需要尽量减少传输的文本数量,所以就增加了选择器的复杂度。

Flexbox 和 Grid

不得不提一下的是页面的布局(layout),css目前比较常用的是 Flexbox(弹性盒)和 Grid(网格)模型。顾名思义,Flexbox模型里的元素是可以拉伸和压缩的,Grid是把页面分割成几行几列的网格,将元素置于某个网格的位置。

基于class的css框架

首先我们需要知道一个html的特性:每个元素可以同时设置多个类(class),类之间用空格隔开。

这种特性催生了一系列基于预制类的css框架,例如tailwindcss。它们预先定义了许多类,提供特定的功能,程序员在使用时不再需要自己去定义类,而是直接给html元素设置多个预制类。这就解决了传说中编程领域最难的问题之一 —— 命名。

<div class="pt-6 space-y-4">

比如,这里的pt-6 表示 "padding-top: 1.5rem", space-y-4表示 "margin-top: 1rem"。程序员通过组合这些预制类,就可以达到想要的效果。如果说原来手写css是用泥巴捏出一个造型,使用基于class的框架就好比是用现成的乐高积木进行拼装。

总结

以上是我从一个非前端程序员的角度来聊聊css,如有错误欢迎指出。个人觉得css是一个偏向设计的东西,需要有专业的设计能力,或者参照UI设计师的设计图来进行编写。如果非专业人员想要快速地做出一个好看好用的页面,可以直接使用css框架。

https://www.bilibili.com/vide...

本文参与了SegmentFault 思否写作挑战赛,欢迎正在阅读的你也加入。

Ljzn
399 声望102 粉丝

网络安全;函数式编程;数字货币;人工智能