本文是字节跳动第四届青训营前端专场的第一篇自学笔记,以课上内容为主干,补充自学知识整理成文。主要内容为前端“三件套”——HTML, CSS, Javascript的基本框架和要点梳理。关于青训营的更多信息,请见 这里

HTML

字节跳动第四届青训营-前端Lecture 1
课件:https://slides.com/fe-fairy/fe-n-html

基本语法

  • 在文档头部使用 <!DOCTYPE html>,向浏览器指定使用HTML引擎渲染

  • 每个HTML文档对应一个页面,页面的标签结构形成一棵DOM树

    DOM树结构示意

  • 不区分大小写,无内容的空白标签可以不闭合(但需要在末端加 /),其它标签两端需闭合

  • 推荐语义化写法,标签类型要与内容的作用相符,方便自己,方便他人

常见标签

  • 六级大纲/标题,段落 <p>

  • 各类列表

    • 有序列表 <ol><li>
    • 无序列表 <ul><li>
    • 键值列表 <dl><dt><dd>
  • 超链接 <a>

  • 多媒体:<img><audio><video>

  • 输入 <input>

    • 滑动条:type=range
    • 数字:type=number
    • 日期:type=date
    • 多行输入:<textarea>
    • 选择框,一组选择框需要在一个段落中
      • 多选框:type=checkbox
      • 单选框:type=radio
      • 下拉选择:<select><option>
    • 下拉选择与输入
      1
      2
      3
      4
      5
      6
      <input list="countries" />
      <datalist id="countries">
      <option>Greece</option>
      <option>United Kingdom</option>
      <option>United States</option>
      </datalist>
  • 段落引用 <blockquote>

  • 行内引用 <cite><q>

  • 代码字体 <code>

  • 等宽字体段落 <pre>

    • pre标签内包含的文本将保留所有的空格和换行符,并以等宽字体呈现。
  • 粗体 <strong>,斜体 <em>

CSS

字节跳动第四届青训营-前端Lecture 2
Cascadiing Style Sheets,层叠样式表
课件:https://slides.com/fe-fairy/css1 and https://slides.com/fe-fairy/css2

  • CSS可以定义html元素的样式
  • CSS主要通过选择器选择页面元素,使用包含属性和值的声明定义样式
  • CSS有三种写法
    • 外链,把所有样式声明集中在一个css文件中,在HTML文档内使用<link rel="stylesheet" href="LINK_TO_CSS">引入样式表
    • 嵌入,在html文档中使用<style>标签包裹css内容
    • 内联,直接在html标签的style属性中以声明字符串的形式指定元素样式,多条声明之间用分号;分隔
    • 推荐外链和嵌入形式的写法,不推荐使用内联

CSS的整体工作模式

  • 浏览器加载并解析HTML
  • 浏览器在解析过程中创建DOM树,并发现文档中引入的CSS内容
  • 浏览器加载并解析CSS
  • 浏览器根据CSS内容为DOM树中的对应节点添加属性
  • 渲染页面

关于选择器

选择器在CSS中定位元素,因此其地位很重要,有多种选择方式。

常见选择器

  • 通配选择器 *

  • 标签选择器,例如:h1选择文档中所有的一级标题元素

  • id选择器,格式为#ID

  • 类选择器,格式为.CLASS_NAME

  • 属性选择器,可以选择属性值满足特定条件的元素

    • 仅有属性值的写法,如[disabled]
    • 同时指定标签类型和属性值的写法,如input[type="password"]
    • 特定字符匹配的写法,如a[href^=...]表示链接元素的url以某个值开头,而a[href$=...]则表示以某个值结尾,a[href*=...]则表示属性值包含某个子串
  • 伪类选择器:根据HTML的状态或结构选择相应元素

    • 伪类一般与其它选择器(如标签、id等)结合使用,中间以冒号:分隔
    • 状态伪类,例如对于链接元素,可以有正常状态下的a:link,鼠标掠过/悬停时的a:hover、点击时的a:active、点击后的a:visited;其它伪类还有输入框聚焦、多选框选中等
    • 结构伪类,一般与元素在DOM树中的位置有关,例如列表中的第一个元素可以用li:first-child,最后一个用li:last-child
    • 关于较全面的伪类,可以参见这里

选择器的组合

  • 直接组合,两个选择器之间无分隔,例如input.class会选择输入框中类名为class的元素

  • 后代组合,以空格分隔,例如nav a会选择导航栏各级子元素里面所有的链接

  • 亲子组合,以>分隔,例如section > p会选择域所属的所有段落元素,需要注意这里只有直接上下级元素才会选中

  • 兄弟选择,以~分隔,例如h2 ~ p会选择二级标题之后所有与该二级标题具有相同父元素的段落元素

  • 相邻选择,以+分隔,例如h2 + p会选择紧跟在二级标题后面同一级别的一个段落元素,与~的区别就在选择元素的个数上

  • 选择器组,即多个选择器指定相同样式,不同选择器之间用逗号分隔

选择器的优先级

如果HTML中的一个元素在样式表中可以匹配到多个选择器,那么我们就需要决定哪一个选择器的规则对其适用。整体上,各类选择器以及样式定义方式的优先级顺序如下:

!important > 行内样式 > ID选择器 > 类选择器 > 标签选择器 > 通配选择器 > 继承 > 浏览器默认属性

其中部分概念的解释:

  • !important,是指在某条声明属性值的后面加上!important,此时该条声明将会获得最高优先级;
  • 行内样式是指在HTML标签使用style属性定义的样式;
  • 继承是CSS中的一个重要特征,有以下几个要点:
    • 可继承属性会继承DOM树里面父元素的计算值,除非显式指定
    • 文字相关的属性一般可继承
    • 盒模型相关的一般不可继承(在后文会介绍盒模型)
    • 显式继承可以使得不可继承属性变为可继承,方式为在通配选择器设置属性值为inherit
    • 没继承到时使用硬编码的初始值,可以用initial显式指定

如果同一元素的多条匹配规则中存在多个选择器的组合,则需要以特异度来决定选择器的优先级,根据以下规则

id选择器数 > (伪)类选择器数 > 标签选择器数

先比较规则中id选择器的数目,再比较类选择器和伪类选择器的数目,最后比较标签选择器的数目,直到可以判断出高低为止。

关于颜色

颜色是CSS中十分常见的一个要素,文字、背景、边框、阴影等要素都会涉及到颜色的设置。

颜色模型

  • 最常用:RGB模型,对应红绿蓝三原色

    • 标准写法为rgb(red_value, green_value, blue_value),三个颜色值的取值范围都是0-255之间的整数
    • 也可以采用较为简洁的十六进制写法如#ffffff,其中前两位、中间两位、后两位分别表示红绿蓝的十六进制值
    • RGB模型符合计算机生成颜色的原理,但缺点在于不太符合人的阅读习惯,即给定一个颜色值,很难直观判断颜色的属性
  • HSL模型

    • Hue色相:取值0-360,代表色彩的基本属性(是什么颜色)
    • Saturation饱和度:取值0-100%,代表色彩鲜艳程度
    • Lightness亮度:取值0-100%,代表色彩的明亮程度
    • HSL的标准写法为hsl(h_value, s_value%, l_value%)
    • HSL模型相对于RGB颜色的优势是使视觉感知与属性值联系起来,可以通过S和L判断颜色的性质,例如在生成渐变颜色的时候很有用

关键字

可以用关键字来表示一些常见颜色,如"black",实践中不用记太多。一个较为全面的常见关键字列表在这里

透明度

  • 另一个较为重要的颜色指标是透明度alpha,取值范围0-1,0为完全透明,1不透明

  • 加入透明度之后,原先两种模型的的标准写法扩展为rgba(·, ·, ·, alpha)或者hsla(·, ·, ·, alpha)

  • 对于RGB模型的十六进制写法,可以在后面加两位十六进制字符 (此时该两位的取值同为0-255即00h-ffh),例如透明度为0.5的白色表示为#fffff7f

关于字体

字形

  • 字形在css中使用font-family属性设置。一般会同时设置多个并以逗号分隔,因为不同设备安装的字体不同,当浏览器找不到某个字体时,可以有其它字体作为替代
  • 最后一个字体建议使用通用字体族作为兜底。通用字体族并不是具体的字体,而是某一类字体的总称,如果其它字体都未在设备上安装,浏览器会自动选择指定字体族的一种字体。常见的通用字体族有五种:
    • serif——衬线体,如宋体、Georgia等
    • sans-serif——无衬线体,如微软雅黑、Arial等
    • cursive——手写体,如楷体、Brush Script MT等
    • fantasy——幻想体,主要是一些具有装饰性的字体
    • monospace——等宽体,如Consolas、Courier New等
  • 建议设置字体时,英文在中文前面,可以起到中西文字体分类的作用
  • 如果设备上没有字体,也可以在指定字体时使用外部字体,让浏览器先下载字体再渲染,具体写法为在CSS样式表头部添加@font-face模块:
    1
    2
    3
    4
    @font-face {
    font-family: NAME_OF_FONT;
    src: url("LINK_TO_FONT_FILE");
    }

字号和样式

  • 字体大小/字号使用font-size属性设置,有以下几种写法:

    • 像素数px
    • em和百分比,是相对单位,相对于无此规则时字体默认大小的倍数
    • 关键字:例如small medium large等

CSS中的长度单位
CSS中很多属性都要涉及到设置长度,而长度的单位有很多种,为了下文方便叙述,这里对一些常见单位进行总结:

  • mm/cm,即毫米/厘米
  • in,英寸
  • px,像素
  • em,相对于元素font-size的倍数(未设置则查找父元素font-size)
  • rem,相对于根元素font-size的倍数
  • %,相对于父元素尺寸的百分比
  • vw/vh,相对于浏览器窗口宽度/高度的百分比数值
  • vmin/vmax,相对于浏览器窗口较短边/较长边的百分比数值
  • 文字的倾斜使用font-style属性设置,normal代表正常,italic代表书写体,oblique代表倾斜体;字体未实现oblique设计时,会直接用italic代替
  • 文字的粗细使用font-weight属性设置,取值范围为100-900,可以直接写数值,也可以用两个常见的关键字:
    • normal——400,正常值
    • bold——700,粗体值
    • font-weight属性同样需要字体设计的支持,如果在调整该属性值后发现字体粗细未发生变化,那大概率意味着字体没有实现对应值的版本:很多字体只实现了normal和bold两种粗细度。
  • 文字的装饰线使用text-decoration属性设置,默认为none,此外常见的几个取值:
    • underline——下划线
    • line-through——删除线
    • overline——上划线,即线在文字顶部

文字与段落相关设置

  • 行高使用line-height属性设置,表示两行文字基准线(basline)的距离
  • 对齐方式使用text-align属性设置,主要取值:
    • left——左对齐
    • center——居中对齐
    • right——右对齐
    • justify——两端对齐,但最后一行不适用
  • 字间距的设置,主要涉及到两个属性:
    • letter-spacing是字母间的距离
    • word-spacing是词汇间的距离
    • 对于不是以word为基本单位的语言如汉语、日语等,由于css中word定义为由空白字符包裹的非空白字符串,所以word-spacing属性并没有实际用处
  • 段落缩进使用text-indent属性设置
  • 空格相关规则使用white-space属性设置
    • 在HTML文档中,如果标签内容存在多个空格,默认将会合并成一个;同时,在标签内容中的换行默认也是无效的。通过设置white-space属性可以改变处理规则
    • normal:默认值
    • nowrap:强制不换行
    • pre:保留所有空格(但不保留换行)
    • pre-wrap:保留空格且换行
    • pre-line:合并空格但保留换行

Font属性

font属性可以一次性设置与字体段落相关的多个属性值,其写法为:

1
font: style weight size/line-height family

CSS的求值过程

对于字体和布局中涉及到的各种长度,由于单位的多样性,需要一个复杂的过程从CSS中的定义计算出实际在页面中显示时所用的值。

CSS求值过程,点击图片查看清晰大图

  • 关键环节:filtering - cascading - defaulting - resolving - formatting - constraining - 渲染
  • 计算值和使用值:前者是仅通过分析css计算出的值,后者还需要结合浏览器本身渲染环境的属性进行计算
  • 继承是继承父元素计算值

关于布局

布局在CSS中是指在页面上确定内容大小、位置的算法,涉及到三种相关技术:常规流、浮动、绝对定位。在介绍布局方式之前,我们先从最基本的布局单元——盒模型讲起。

盒模型

盒模型是对HTML元素的一种抽象,我们可以将每个DOM树中的节点看作一个盒子,盒子里面会有各类内容,子节点同样也可以看成一个盒子,这样,页面布局就可以简化为处理一个个盒子之间的关系。盒子中有内容,自然也有边界,构成盒子的基本要素从内向外分别是:

  • content——内容
  • padding——内边距
  • border——边框
  • margin——外边距

盒子的尺寸

在明确盒模型四个基本要素的基础上,首先来考虑各个要素的尺寸。CSS中存在两种盒模型,可以使用box-sizing属性进行切换。该属性默认取值为content-box,还可以取border-box。下图展示了二者的区别:

box-sizing: content-box box-sizing: border-box
  • width&height属性可以设置宽度和高度(具体范围见上图)
    • 属性值可以用px/百分数/auto
    • 百分数是相对于容器的指定宽高度的比例
    • auto是根据容器内容自动计算
  • padding&margin属性分别设置盒子的内外边距
    • 写法可以有1/2/4个值,或者使用类似padding-top格式的属性单独设置某个方向的边距
    • 1个值同时指定四个边距,2个值分别是上下和左右,4个值是顺时针旋转即分别为上、右、下、左
    • 除直接设置尺寸外,也可以用百分数(相对容器宽度的百分比)和auto
    • margin collapse:两个元素的外边距方位重叠时,会直接取较大的值,而不是叠加
  • border属性设置边框
    • border属性包含三个子属性:border-width边框宽度, border-style边框样式(如实线、虚线等), border-color边框颜色,每一个子属性都可以单独设置,也可以直接通过border: width style color的格式一次性指定
    • 如果想要单独设置某一方向边框的属性,也可以使用类似border-top或者border-width-top的格式
    • 可以用三角形例子组合形状
  • overflow可以设置盒子内容超出宽高时的处理方式
    • visible——默认值,直接显示所有内容,超出容器范围的显示在容器外
    • hidden——隐藏超出容器范围的内容
    • scroll——隐藏超出容器范围的内容,但会有滚动条以便查看这些内容
    • auto——如果内容未超出容器则正常显示,超出则显示滚动条

盒子的显示方式

在CSS中,盒子有两种的不同类型,它们具备不同的显示特征:

  • 块级box:不与其它box同行摆放
  • 行级box:可以和其它行级box放在一行或者拆成多行显示,此时widthheight属性不再适用

那么如何判断某一个盒子是块级or行级呢?一般有以下规则:

  • 块级HTML元素生成块级box
    • 常见块级元素有body, div, section, h1-6, p, ul, li等
  • 行级HTML元素生成行级box,但由于一行能显示的有限,元素内容可能分散在多个行box中
    • 常见行级元素有span, em, a, strong, cite, code等
  • 可以用display属性显式指定盒子类型
    • block——块级box
    • inline——行级box
    • inline-block——不能拆分内容的行级box,类比图片可以跟文字放在一行,但无法拆成两行放
    • none——布局时完全去掉盒子

常规流布局方式

常规流指正常情况下内容排版的队列,包括行、块、table、flex、grid五种布局方式。除根元素、浮动以及绝对定位元素之外的其它元素都在常规流内,常规流中的盒子通过上面五种的其中一种方式参与布局。

行级和块级排版

  • 行级排版上下文(IFC)
    • 只包含行级或inline-block盒子的容器会创建一个IFC
    • IFC中的盒子在一行内水平摆放,摆不下时换行
    • text-align/vertical-align属性分别控制一行内盒子的水平对齐和垂直对齐方式。
  • 块级排版上下文(BFC)
    • 根元素、浮动元素、绝对定位元素、inline-block元素、弹性容器和网格容器的直接子元素等都会创建一个BFC。比较全面的BFC生成条件可见这里
    • BFC中的盒子从上到下摆放
    • 合并垂直margin(即上文提到的margin collapse),但BFC内盒子的margin不会与外部盒子合并
    • BFC不与浮动元素重叠

需要注意的时一个盒子内的子容器默认只能都是块级或者都是行级,如果在IFC中插入一个块级box,IFC会变为BFC,同时创建匿名的块级box包裹其它的行级元素。

Flex排版

Flex排版上下文是比较新的一种排版方式,在该上下文中,可以通过多种属性灵活控制子级盒子,因此得到了十分广泛的应用,已经成为前端布局的主流。Flex排版通过设置display: flex启用。

  • Flex容器中的盒子流向由flex-direction属性指定

    • row——默认值,从左到右
    • row-reverse——从右到左
    • column——从上到下
    • column-reverse——从下到上
  • 盒子对齐方式用主轴和侧轴方向指定

    • justify-content设置主轴即盒子流向方向的对齐
    • align-items设置侧轴对齐方式,即与流向正交方向的对齐
    • align-self可以给flex容器中某个子级盒子单独设置对齐
    justify-content align-items
  • Flex容器中,设置子元素的order属性可以使子元素按指定排列顺序,即按照order值从小到大的顺序,默认为0

  • flex属性可以设置flex容器中子级盒子的“弹性”,它包括三个子属性

    • flex-basis是盒子在无伸缩状态下在主轴方向的基础长度
    • flex-grow相当于基础宽度上的弹力,容器减去基础空间之后的宽度按flex-grow相对比例分配
    • flex-shrinkflex-grow含义类似,但相当于容器空间不足时的压缩空间比例,值0代表刚性即不可压缩
    • flex属性可以同时设置三个子属性:flex: grow shrink basis
  • 其它一些属性较多,可以用到时再查询文档

Grid布局上下文

grid即网格布局,相当于flex在二维上的布局方式,通过设置display: grid启用,生成一个块级Grid容器。

  • 通过grid-template-columnsgrid-template-rows属性划分网格

    • 取值可以用像素值/auto/fr,fr即fraction,指将剩余空间按比例分配
    • 有几个值就是几行或者几列
  • grid-area相关属性设置每个子项占哪些行列

    • 给网格线从1开始从左向右/从上向下编号,例如:
      grid布局网格线示意
    • 对grid容器中的子元素,通过设置grid-area:row_start/col_start/row_end/col_end一次指定边界网格线的线号,例如1/1/3/3代表子容器将占据上面容器的左侧4个网格
    • 也可以通过一些子属性单独指定
      • grid-row-start
      • grid-column-start
      • grid-row-end
      • grid-column-end

浮动布局

浮动布局现在主要的作用使实现类似于“文字环绕图片”的效果,可以通过float属性设置:

  • none——默认值,无浮动
  • left——向左浮动
  • right——向右浮动

如果启用了浮动,元素将会脱离常规流,并向左侧或右侧贴靠,直到遇到父容器边界或者碰到其它浮动的容器。

绝对定位

绝对定位是指元素的布局不再依赖常规流而相对固定,主要通过position属性设置。该属性主要的取值有:

  • static——默认值,参与常规流布局
  • relative
    • 在常规流中布局,相对本来的位置偏移
    • top/left/right/bottom设置各个方向的偏移量
  • fixed
    • 脱离常规流,相对可视窗口范围定位
    • 适用于导航栏/返回顶部等功能
    • top/left/right/bottom设置相对可视窗口边界的距离
  • absolute
    • 脱离常规流,相对于最近的非static祖先定位
    • 常规流布局不再考虑该元素
    • top/left/right/bottom设置相对父元素边界的距离
  • sticky
    • 具体解释比较复杂,看文档

需要注意的是,不同排版方式可以层层嵌套。例如一个元素是脱离了常规流进行绝对定位,但其内部的子元素如非特意设置,则依然是一个常规流。

学习建议

  • 文档参考:MDN / W3C CSS标准
  • 善用浏览器开发者工具
  • 持续学习