CSS从入门到实战

本篇将从基础着手,从易到难讲解CSS的基础及规范。

大纲

  • CSS属性概要
    • 选择器
    • 样式属性及分类
  • 基本用法
    • 布局
    • 过渡/动画
  • 兼容处理
    • 移动端常用
    • PC端常用
    • 奇葩的IE
  • 基本规范
    • 顺序
    • 选择器的使用
    • 利用伪元素
  • 写法规范(基本思想)
    • 第一代:OO-CSS
    • 百花齐放:BEM、SMACSS、Atomic CSS等
    • 预处理时代:Less、Sass、Stylus
    • 组件化时代:css modules、CSS in JS
    • *爱基金:Moo-CSS
  • *移动端的自适应:rem与vw,image-set()等

1 CSS属性概要

早期的Web仅仅是一系列互相链接的研究文档,并使用HTML添加基本的格式和结构,但随着万维网的流行,HTML开始用来表现页面。便出现了如下的页面形式:

1
2
3
4
5
6
<img width="200" height="300" border="0" hspace="3" src="http://blog.michealwayne.cn/images/fundchartspics/line/1.png">
<table width="411">
<tr>
<td valign="top" bgcolor="#eee">table 1</td>
</tr>
</table>

随着网页变得越来越复杂,这种形式的代码变得几乎不能理解了。在此时代背景下,CSS诞生了。CSS的主要作用是控制页面的外观并且将文档的表现部分与内容分隔开。

1.1 选择器

有效且结构良好的文档为应用样式提供了一个框架,要想使用CSS将样式应用于特定的HTML元素,需要有办法找到这个元素。在CSS中,执行这一任务的样式规则部分称为选择器(selector)。

1.1.1 元素选择器和后代选择器

元素选择器有时候也称为类型选择器或简单选择器,用来寻找特定类型的元素。如

1
2
p {color: black;}
h1 {font-size: 30px;}

后代选择器可用来寻找特定元素或元素组的后代。后代选择器由其他两个选择器之间的空格表示。如

1
div p {text-align: center}

1.1.2 ID和类名

元素选择器和后代选择器适合应用那些应用范围广的一般性样式,要想寻找更特定的元素,可以使用ID选择器和类选择器。这两种选择器用于寻找那些具有指定ID或类名的元素。


1
2
#title {font-weight: bold;}
.error {color: red;}

一个ID名只能应用于页面上的一个元素,而同一个类名可以应用于页面上任意数量的元素。类非常适合标识内容的类型或相似的条目,ID应该应用于概念上相似但避免混淆的元素。

在分配ID和类名时,一定要尽可能保持名称有意义并与表现方式无关。例如,可以给导航元素分配ID:rightHandNav,因为你希望它出现在右边。但是,如果以后它的位置改到左边,那么css和html就会不同步。所以,将这个元素命名为subNav或secondaryNav更合适。这种名称解释了这个元素是什么,而没有涉及如何表现它。对于类名,也是这样的。即使你希望所有错误消息以红色显示,也不要使用类名red,而应该选择更有意义的名称,比如error或feedback。

*伪类

有时候,希望根据文档结构之外的其他条件对元素应用样式,例如表单元素或链接的状态。这就需要使用伪类选择器来完成。有关于伪类和伪元素后续将有详细说明。

1.1.3 通用选择器

它匹配所有可用元素。如

1
2
3
4
* {
padding: 0;
margin: 0;
}

以上是CSS1的选择器,CSS2新增了更多有用的选择器

1.1.4 子选择器和相邻同胞选择器

后代选择器选择一个元素的所有后代,而子选择器只选择元素的直接后代,即子元素。如

1
#title > a {color: blue}

相邻同胞选择器可用于定位同一个父元素下某个元素之后的元素。

1
h1 + p {font-weight: bold}

1.1.5 属性选择器

属性选择器可以根据某个属性是否存在或属性的值来寻找元素。

1
2
[href] {color: blue}
[rel="nofollow"] {padding: 10px}

属性选择器的查询条件很丰富,可见mdn-attribute_selectors

CSS3在此基础之上又新增了些选择器

1.1.6 通用兄弟选择器

兄弟选择符,位置无须紧邻,只须同层级,A~B 选择A元素的所有同层级B元素。

1
2
3
p ~ span {
color: red;
}

css属性列表可参考w3school css选择器列表mdn-css_selectors

*多类症(classitis)

在几乎所有东西上添加类,从而试图更精细地控制它们的样式。

解决:如果你发现自己在文档中添加了许多不必要的类,那么这可能是文档结构不合理的一个警告信号。这时候应该分析这些元素之间的差异。你常常会发现唯一的差异是他们在页面上出现的位置。一种解决方案是不要给这些元素指定不同的类,而是将一个类或ID应用于它们的祖先,然后使用后代选择器。另一种解决方案就是Moo-CSS的模块思想

*多div症
*在主体标签上添加类或ID

一种有意思的写法是在主体(如body)标签上应用类或ID,这样做之后,就可以根据页面或在站点范围内覆盖样式。

no camelcase

1.2 样式属性及分类

1.2.1 边框盒背景属性

属性 说明 CSS版本
background 设置所有背景值的简写属性 1
background-attachment 设置元素的背景附着属性,决定背景图片是否随页面一起滚动 1
background-clip 设置元素背景颜色和图像的裁剪区域 3
background-color 设置背景颜色 1
background-image 设置背景图像 1
background-origin 设置背景图像绘制的起始位置 3
background-position 设置背景图像在元素盒子中的位置 1
background-repeat 设置背景图像的重复方式 1
background-size 设置背景图像的绘制尺寸 3
border 为所有边界设置所有边框宽度的简写属性 1
border-bottom 为所有下边框设置宽度的简写属性 1
border-bottom-color 为所有下边框设置颜色 1
border-bottom-left-radius 将边框左下角设置为圆角 3
border-bottom-right-radius 将边框右下角设置为圆角 3
border-bottom-style 设置元素下边框的样式 1
border-bottom-width 设置元素下边框的宽度 1
border-color 设置四条边框的颜色 1
border-image 使用图像作为边框的简写属性 3
border-image-outset 指定图像向边框盒外部扩展的区域 3
border-image-repeat 指定边框图像的缩放和重复方式 3
border-image-slice 指定边框图像的切割方式 3
border-image-source 设置边框图像的来源路径 3
border-image-width 设置边框图像的宽度 3
border-left 设置元素左边框的简写属性 1
border-left-color 设置左边框的颜色 1
border-left-style 设置左边框的样式 1
border-left-width 设置左边框的宽度 1
border-radius 指定圆角边框的简写属性 3
border-right 设置元素右边框的简写属性 1
border-right-color 设置右边框的颜色 1
border-right-style 设置右边框的样式 1
border-right-width 设置右边框的宽度 1
border-style 设置所有边框样式的简写属性 1
border-top 为所有上边框设置宽度的简写属性 1
border-top-color 为所有上边框设置颜色 1
border-top-left-radius 将边框左上角设置为圆角 3
border-top-right-radius 将边框右上角设置为圆角 3
border-top-style 设置元素上边框的样式 1
border-top-width 设置元素上边框的宽度 1
border-width 设置四个边框的宽度 1
box-shadow 设置元素的一个或者多个阴影效果 3
outline-color 设置元素边框外围轮廓线的颜色 2
outline-offset 设置轮廓距离元素边框边缘的偏移量 2
outline-style 设置轮廓的样式 2
outline-width 设置轮廓的宽度 2
outline 在一条声明中设置轮廓的简写属性 2

1.2.2 盒模型属性

属性 说明 CSS版本
box-sizing 设置要应用盒子尺寸相关属性的元素 3
clear 设置盒子的左边界、右边界或左右两个边界不允许出现浮动元素 1
display 设置元素盒子的类型 1
float 将元素移动到其包含块的左边界或者右边界,或者另一个浮动元素的边界 1
height 设置元素盒子的高度 1
margin 设置元素盒子四个外边距宽度的简写属性 1
margin-bottom 设置盒子下外边距的宽度 1
margin-left 设置盒子左外边距的宽度 1
margin-right 设置盒子右外边距的宽度 1
margin-top 设置盒子上外边距的宽度 1
max-height 设置元素的最大高度 2
max-width 设置元素的最大宽度 2
min-height 设置元素的最小高度 2
min-width 设置元素的最小宽度 2
overflow 设置内容横向和竖向溢出盒子时处理方式的简写属性 2
overflow-x 设置内容横向溢出盒子时的处理方式 3
overflow-y 设置内容纵向溢出盒子时的处理方式 3
padding 设置元素盒子四个内边距宽度的简写属性 1
padding-bottom 设置盒子下内边距的宽度 1
padding-left 设置盒子左内边距的宽度 1
padding-right 设置盒子右内边距的宽度 1
padding-top 设置盒子上内边距的宽度 1
visibility 设置元素的可见性 2
width 设置元素的宽度 1

1.2.3 布局属性

属性 说明 CSS版本
bottom 设置元素下外边距边界与包含块下边界之间的偏移 2
column-count 指定多列布局的列数 3
column-fill 多列布局中列与列之间的内容如何发布 3
column-gap 指定多列布局中列与列之间的间隔 3
column-rule 多列布局中定义列与列之间的规则的简写属性 3
column-rule-color 设置多列布局中的颜色规划 3
column-rule-style 设置多列布局中的样式规则 3
column-rule-width 设置多列布局中的宽度规则 3
columns 在多列布局中设置列数和列宽度的简写属性 3
column-span 指定多列布局中元素能跨多少列 3
column-width 设置多列布局中列的宽度 3
display 指定元素在页面上的显示方式 1
flex-align、flex-direction、flex-order、flex-pack 它们都是由弹性盒子布局定义的 3
left 设置元素左外边距边界与包含块左边界之间的偏移 2
position 设置元素的定位方法 2
right 设置元素右外边距边界与包含块右边界之间的偏移 2
top 设置元素上外边距边界与包含块上边界之间的偏移 2
z-index 设置定位元素的堆叠顺序 2

1.2.4 文本属性

属性 说明 CSS版本
@font-face 指定网页使用的字体 3
direction 指定文本方向 2
font 在一条声明中设置文本字体、大小和颜色的简写属性 1
font-family 指定文本所用的字体系列,排在前面的优先使用 1
font-size 指定字体大小 1
font-style 指定采用正常字体、斜体还是倾斜字体 1
font-variant 指定字体是否以小型大写字母显示 1
font-weight 指定文本粗细 1
letter-spacing 设置字母间距 1
line-height 设置行高 1
text-align 设置文本对齐方式 1
text-decoration 规定添加到文本的修饰(如下划线) 1
text-indent 规定文本块中首行文本的缩进 1
text-justify 设置文本对齐方式 3
text-shadow 指定文本块的阴影效果 3
text-transform 控制文本块的阴影效果 1
word-spacing 指定单词间距 1

1.2.5 过渡、动画和变换属性

属性 说明 CSS版本
@keyframes 为动画指定一个以上的关键帧 3
animation 设置动画的简写属性 3
animation-deplay 指定动画开始前的延迟时间 3
animation-direction 指定动画重复播放时的播放方向 3
animation-duration 指定动画的持续时间 3
animation-iteration-count 指定动画的循环次数 3
animation-name 指定用于动画的关键帧集合的名称 3
animation-play-state 指定动画状态(播放或暂停) 3
animation-timing-function 指定关键帧之间计算属性值的函数 3
transform 指定应用于元素的变换 3
transform-origin 指定元素变换的起点 3
transition 指定CSS属性过渡效果的简写属性 3
transition-delay 指定触发过渡的延迟时间 3
transition-duration 指定过渡的持续时间 3
transition-property 指定带有过渡效果的属性 3
transition-timing-function 指定过渡期间计算中间属性值的函数 3

1.2.6 其他属性

属性 说明 CSS版本
border-collapse 指定表格相邻单元格边框的显示样式 2
border-spacing 指定相邻单元格的边框的距离 2
caption-side 指定表格标题的位置 2
color 设置元素的前景色 1
cursor 指定光标的形状 2
empty-cells 指定是否显示表格中的空单元格 2
list-style 设置列表样式的简写属性 1
list-style-image 指定列表项标记使用的图像 1
list-style-position 指定列表项标记相对于列表项内容的位置 1
list-style-type 指定列表项标记的类型 1
opacity 设置元素的透明度 3
table-layout 指定表格单元格、行和列的算法规则 2

2 基本用法

2.1 布局

2.1.1 浮动布局

浮动被用来将元素盒子向左或向右移动,同时让内容环绕其展示。

2.1.2 定位

想要把一个元素脱离正常文档流或者改变其在正常文档流中的位置,可以使用CSS的position属性。在正常文档流中,元素的position的值为static(也是position的默认值)。在块级维度上元素会一个接一个排列下去,当你滚动页面时,元素也会随着滚动。

相对定位
1
position: relative
绝对定位
1
position: absolute
固定定位
1
position: fixed
粘性定位
1
position: sticky

2.1.3 Flex布局

Flexbox布局是一种用于一维布局而设计的布局方法。一维的意思是你希望内容是按照行或者列来布局。你可以在元素上将display设置为flex值,把该元素为变弹性布局。

*2.1.4 Grid布局

CSS Grid布局是一种用来进行二维布局的技术。二维意味着你希望按照行和列来排布你的内容。和Flexbox类似,Grid布局也需要设置一个display值。你可以为容器元素设置display: grid,并且使用grid-template-columns和grid-template-rows属性来控制网格中的行与列。

2.2 过渡/动画

过渡transition

css3过渡是元素从一种样式逐渐改变为另一种样式时的效果。

动画animation

3 兼容处理

3.1 移动端常用

retina:一种具备超高像素密度的液晶屏,同样大小的屏幕上显示的像素点由1个变为多个,如在同样带下的屏幕上,苹果设备的retina显示屏中,像素点1个变为4个

在高清显示屏中的位图被放大,图片会变得模糊,因此移动端的视觉稿通常会设计为传统PC的2倍。

3.1.1 清除默认样式

webkit上的input,button,及select的默认样式可以通过以下代码禁用,然后自定义。

1
2
3
4
5
input, 
button,
select {
-webkit-appearance: none;
}

3.1.2 去除触摸反馈遮罩

ios用户点击一个链接,会出现一个半透明灰色遮罩, 如果想要禁用,可设置-webkit-tap-highlight-color的alpha值为0,也就是属性值的最后一位设置为0就可以去除半透明灰色遮罩

1
2
3
body {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

3.1.3 改变webkit表单输入框placeholder的颜色值

1
2
input::-webkit-input-placeholder{color:#aaa;}
input:focus::-webkit-input-placeholder{color:#eee;}

3.1.4 禁止浏览器图片长按保存

1
img {-webkit-touch-callout: none}

3.1.5 禁止用户选择文字

1
2
3
body {
-webkit-user-select: none;
}

3.2 PC端常用

3.3 奇葩的IE

4 基本规范

无论编写什么文档,我们都应当维持统一的风格,包括统一的注释、统一的语法与统一的命名规范。

总则
将行宽控制在 80 字节以下。渐变(gradient)相关的语法以及注释中的 URL 等可以算作例外,毕竟这部分我们也无能为力。

我倾向于用 4 个空格而非 Tab 缩进,并且将声明拆分成多行。

单一文件与多文件
有人喜欢在一份文件文件中编写所有的内容,而我在迁移至 Sass 之后开始将样式拆分成多个小文件。这都是很好的做法。无论你选择哪种,下文的规则都将适用,而且如果你遵守这些规则的话你也不会遇到什么问题。这两种写法的区别仅仅在于目录以及区块标题:

4.1 顺序

尽量按照特定顺序编写规则,这将确保你充分发挥 CSS 中第一个 C 的意义:cascade,层叠。

一份规划良好的 CSS 应当按照如下排列:

Reset 万物之根源
元素类型 没有 class 的 h1、ul 等
对象以及抽象内容 最一般、最基础的设计模式
子元素 由对象延伸出来的所有拓展及其子元素
修补 针对异常状态
如此一来,当你依次编写 CSS 时,每个区块都可以自动继承在它之前区块的属性。这样就可以减少代码相互抵消的部分,减少某些特殊的问题,组成更理想的 CSS 结构。

4.2 选择器的使用

4.3 利用伪元素

css 图形

1
2
2019.05.14
to be continue