HTML 部分

1. 迭代

网页的版本

  • HTML4

  • XHTML2.0

  • HTML5

2. 文档声明(doctype)

文档声明用来告诉浏览器当前网页的版本

1
2
3
4
<!-- html5的文档声明 -->
<!doctype html>
<!-- 或者 -->
<!Doctype HTML>

3. 字符编码

所有的数据在计算机中存储时都是以二进制形式存储的,文字也不例外。

所以一段文字在存储到内存中时,都需要转换为二进制编码当我们读取这段文字时,计算机会将编码转换为字符,供我们阅读

编码

将字符转换为二进制码的过程称为编码

解码

将二进制码转换为字符的过程称为解码

字符集(charset)

编码和解码所采用的规则称为字符集(相当于密码本)

乱码

如果编码和解码所采用的字符集不同就会出现乱码问题。

可以通过meta标签来设置网页的字符集,避免乱码问题

1
<meta charset="utf-8">

4. 常见的字符集

ASCII

ASCII(American Standard Code for Information Interchange):美国信息交换标准代码

在所有字符集中,最知名的可能要数被称为ASCII的8位字符了。美国信息交换标准代码是由美国国家标准学会(American National Standard Institute , ANSI )制定的,是一种标准的单字节字符编码方案,用于基于文本的数据。它最初是美国国家标准,供不同计算机在相互通信时用作共同遵守的西文字符编码标准,后来它被国际标准化组织(International Organization for Standardization, ISO)定为国际标准,称为ISO 646标准。适用于所有拉丁文字字母

ASCI 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符。标准ASCII 码也叫基础ASCII码,使用7 位二进制数(剩下的1位二进制为0)来表示所有的大写和小写字母,数字0 到9、标点符号,以及在美式英语中使用的特殊控制字符

ASCII码表:Ascii Table - ASCII character codes and html, octal, hex and decimal chart conversion

ISO-8859-1

ISO-8859-1编码是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCII一致,0x80-0x9F之间是控制字符,0xA0-0xFF之间是文字符号。

ISO码表:HTML ISO-8859-1 参考手册

GB2312

GB2312(信息交换用汉字编码字符集)是由中国国家标准总局1980年发布。基本集共收入汉字6763个和非汉字图形字符682个。GB 2312的出现,基本满足了汉字的计算机处理需要,它所收录的汉字已经覆盖中国大陆99.75%的使用频率。

GBK

GBK(即“国标”、“扩展”汉语拼音的第一个字母),汉字编码字符集。2000年已被GB18030-2000国家强制标准替代。 2005年GB18030-2005发布,替代了GB18030-2000。

GBK使用了双字节编码方案,其编码范围从8140至FEFE(剔除xx7F),共23940个码位,共收录了21003个汉字,完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。

Big5

Big5,又称为大五码或五大码,是使用繁体中文(正体中文)社区中最常用的电脑汉字字符集标准,共收录13,060个汉字。

Big5虽普及于台湾、香港与澳门等繁体中文通行区,但长期以来并非当地的国家/地区标准或官方标准,而只是业界标准。倚天中文系统、Windows繁体中文版等主要系统的字符集都是以Big5为基准,但厂商又各自增加不同的造字与造字区,派生成多种不同版本。

UTF-8

UTF-8(8位元,Universal Character Set/Unicode Transformation Format)是针对Unicode的一种可变长度字符编码,也叫万国码、统一码。它可以用来表示Unicode标准中的任何字符,而且其编码中的第一个字节仍与ASCII相容,使得原来处理ASCII字符的软件无须或只进行少部分修改后,便可继续使用。

UTF-16

UTF-16是Unicode的其中一个使用方式。UTF-16比起UTF-8,好处在于大部分字符都以固定长度的字节(2字节)储存,但UTF-16却无法兼容于ASCII编码。

Unicode

Unicode只是一组字符设定或者说是从数字和字符之间的逻辑映射的概念编码,但是它并没有指定代码点如何在计算机上存储。UCS4、UTF-8、UTF-16(UTF后的数字代表编码的最小单位,如UTF-8表示最小单位1字节,所以它可以使用1、2、3字节等进行编码,UTF-16表示最小单位2字节,所以它可以使用2、4字节进行编码)都是Unicode的编码方案。UTF-8因可以兼容ASCII而被广泛使用。

如果把各种文字编码形容为各地的方言,那么Unicode就是世界各国合作开发的一种语言。

HTML5的基本结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!doctype html>
<!-- html的根标签(元素),网页中的所有内容都要写根元素的里边 -->
<html>
<!-- head是网页的头部,head中的内容不会在网页中直接出现,主要用来帮助浏览器或搜索引擎来解析网页 -->
<head>
<!-- meta标签用来设置网页的元数据,这里meta用来设置网页的字符集,避免乱码问题 -->
<meta charset="utf-8">
<!-- title中的内容会显示在浏览器的标题栏,搜索引擎会主要根据title中的内容来判断网页的主要内容 -->
<title>网页的标题</title>
</head>
<!-- body是htm1的子元素,表示网页的主体,网页中所有的可见内容都应该写在body里 -->
<body>
<!-- h1网页的一级标题 -->
<h1>网页的大标题</h1>
</body>
</html>

5. 字符实体

有些时候,在HTML中不能直接书写一些特殊符号,如:

  • 多个连续的空格(在网页中编写的多个空格默认情况会自动被浏览器解析为一个空格)

  • 比如字母两侧的大于小于号(可能会被认为是标签并解析)

如果我们需要在网页中书写这些特殊的符号,则需要使用html中的实体(转义字符)实体的语法:&实体的名字;,如:

实体名称 显示结果 描述
`` 空格
> > 大于号
< < 小于号
& &
© © 版权
® ® 注册商标
商标
× × 乘号
÷ ÷ 除号
¿ ¿ 倒问号

更多的字符实体,可参考:HTML 字符实体HTML ISO-8859-1 参考手册

6. meta标签

以京东网站为例,右键单击,选择查看网页源代码

1
2
3
4
<meta charset="utf8" version='1'/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes"/>
<meta name="description" content="京东JD.COM-专业的综合网上购物商城,销售家电、数码通讯、电脑、家居百货、服装服饰、母婴、图书、食品等数万个品牌优质商品.便捷、诚信的服务,为您提供愉悦的网上购物体验!"/>
<meta name="Keywords" content="网上购物,网上商城,手机,笔记本,电脑,MP3,CD,VCD,DV,相机,数码,配件,手表,存储卡,京东"/>

meta主要用于设置网页中的一些元数据,元数据并不是给用户看的

  • charset :指定网页的字符集

  • name :指定的数据的名称

    • keywords:表示网站的关键字,可以同时指定多个关键字,关键字间使用,隔开
    • description:表示网站的描述信息

发现除了charsetnamecontent之外,还有一个叫http-equiv的属性

1
If the http-equiv attribute is set, the <meta> element is a pragma directive, providing information equivalent to what can be given by a similarly-named HTTP header.

如果设置了http-equiv属性,<meta>元素就是一个pragma指令,提供的信息相当于一个类似名称的HTTP头所能提供的信息。

  • content-security-policy:允许页面作者为当前页面定义一个内容策略。内容策略主要指定允许的服务器来源和脚本端点,这有助于防范跨站脚本攻击。

  • content-type:声明文档的MIME类型和字符编码。如果指定,content属性必须有 “text/html; charset=utf-8 “的值。这相当于一个指定了charset属性的<meta>元素,并对文档中的位置有同样的限制。注意:只能在使用text/html的文档中使用,不能在使用XML MIME类型的文档中使用。

  • default-style:设置默认的CSS样式表集的名称。

  • x-ua-compatible: 如果指定,内容属性必须有 “IE=edge“的值。用户代理被要求忽略这个pragma。

  • refresh:该指令指定页面重新加载及重定向的方式

    • 直到页面应该被重新加载的秒数—只有当content属性包含一个正整数时。
    • 直到页面重定向到另一个页面的秒数—只有当内容属性包含一个正整数,后面跟着字符串’;url=‘,以及一个有效的URL。

其中我们直接将Examples中的示例代码加入Demo.html中

1
2
3
<meta charset="utf-8">
<!-- Redirect page after 3 seconds -->
<meta http-equiv="refresh" content="3;url=https://www.mozilla.org">

refresh进行测试,发现过了3秒钟之后自动跳转到了指定的网站

7. 语义标签

在网页中HTML专门用来负责网页的结构所以在使用html标签时,应该关注的是标签的语义,而不是它的样式

这里先介绍几个基本的语义标签,还有些常用的标签放在后面具体讲解

标签 作用 描述
块元素 Block Element <h1> <h2> <h3> <h4> <h5> <h6> 标题 一共有六级标题 从h1 ~ h6重要性递减,h1最重要,h6最不重要 h1在网页中的重要性仅次于title标签 一般情况下一个页面中只会有一个h1 一般情况下标题标签只会使用到h1h3h4h6很少用
<hgroup> 标题组 多层次的标题。它将一组<h1><h6>元素分组
<p> 段落 页面中的一个段落。由空行或第一行缩进将相邻的文本块分开
<blockquote> 短引文 用缩进表示所包含文本。 可以用cite属性表示引文来源,用<cite>元素表示来源的文本表述
行内元素 Inline Element <q> 长引文 用一个简短的内联引号包围文本。 大多数浏览器通过在文本周围加上引号来实现。 该元素用于不需要段落分隔的短引文;
<br> 换行
<em> 强调 表示强调作用。<em>元素可以嵌套,每一级嵌套表示更高的强调程度 <i>元素效果与它相同,不过<i>不属于语义标签
<strong> 重要 表示重要性、严肃性或紧迫性。浏览器通常以粗体字呈现内容 <b>元素效果与它相同,不过<b>不属于语义标签
1
2
3
4
5
6
7
<h1>Beetles</h1>
<h2>External morphology</h2>
<h3>Head</h3>
<h4>Mouthparts</h4>
<h3>Thorax</h3>
<h4>Prothorax</h4>
<h4>Pterothorax</h4>

HTML5 提供的新语义元素有

标签 作用 描述
<header> 页眉 介绍性的内容
<footer> 页脚 通常包含有关作者的信息、版权或文件链接
<nav> 导航链接 可以是当前文档内的,也可以是到其他文档的。常见例子是菜单、目录和索引
<main> 文档主内容 中心主题直接相关或扩展的内容
<article> 文章 自成一体,独立分发,可重复使用
<section> 文档中的节 没有一个更具体的语义元素来代表
<aside> 页面内容以外的内容 其内容与文档的主要内容只有间接的关系。经常以边栏或呼出框的形式出现
<mark> 重要或强调的文本 为参考或记事目的而被标记或突出的文本,表明其相关性和重要性
<summary> <details> 标题 <details>指定一个摘要、标题或图例。点击<summary>可以切换<details>打开和关闭
<details> 用户能够查看或隐藏的额外细节 其中的信息只有被切换到 “打开 “状态时才可见。必须使用<summary>提供一个摘要或标签
<figure> 自包含内容 独立的内容,用<figcaption>元素指定一个可选的标题。比如图示、图表、照片、代码清单等
<figcaption> <figure> 的标题 描述其父元素
<time> 定义日期/时间 可能包括datetime属性,将日期翻译成机器可读的格式,以便获得更好的搜索引擎结果或自定义功能。如提醒

这些新语义标签在视觉效果上基本上没有什么区别

8. 块元素与行内元素

块元素(block element)

  • 在网页中一般通过块元素来对页面进行布局

行内元素(inline element)

  • 行内元素主要用来包裹文字

  • 一般情况下会在块元素中放行内元素,而不会在行内元素中放块元素

    • <p>元素中不能放任何的块元素

9. 内容修正

浏览器在解析网页时,会自动对网页中不符合规范的内容进行修正,比如:

  • 标签写在了根元素的外部

  • <p>元素中嵌套了块元素

  • 根元素中出现了除headbody以外的子元素

这个通过浏览器中的查看网页源代码并不能看到效果,但是使用F12进行开发者调试时是能够看到上述几种情况被修正的结果。

不过虽然浏览器能够对不规范的页面内容进行修正,还是不建议编写不规范的代码,因为这对后期代码维护或团队代码协作将是非常不好的后果和体验。

10. 布局标签

结构化语义标签

  • header表示网页的头部(页眉)

  • main表示网页的主体部分(一个页面中只会有一个main)

  • footer表示网页的底部(页脚)

  • nav表示网页中的导航

  • aside和主体相关的其他内容(侧边栏)

  • article表示一个独立的文章

  • section表示一个独立的区块,上边的标签都不能表示时使用section

  • div 块元素,没有任何的语义,就用来表示一个区块。目前来讲,div还是主要的布局元素

  • span 行内元素,没有任何的语义,一般用于在网页中选中文字

11. 列表

1
2
3
4
5
6
7
<ol>
<li>Mix flour, baking powder, sugar, and salt.</li>
<li>In another bowl, mix eggs, milk, and oil.</li>
<li>Stir both mixtures together.</li>
<li>Fill muffin tray 3/4 full.</li>
<li>Bake for 20 minutes.</li>
</ol>

定义列表,使用dl标签来创建定义列表,使用dt表示定义的内容,使用dd来对内容进行解释说明

1
2
3
4
5
6
7
8
9
10
<dl>
<dt>Beast of Bodmin</dt>
<dd>A large feline inhabiting Bodmin Moor.</dd>

<dt>Morgawr</dt>
<dd>A sea serpent.</dd>

<dt>Owlman</dt>
<dd>A giant owl-like creature.</dd>
</dl>

12. 超链接

超链接可以让我们从一个页面跳转到其他页面,或者是当前页面的其他的位置

使用a标签来定义超链接,href属性指定跳转的目标路径,值可以是一个外部网站的地址,也可以写一个内部页面的地址

超链接是也是一个行内元素,在a标签中可以嵌套除它自身外的任何元素

外部地址

  • Linking to an absolute URL:链接一个绝对路径

  • Linking to an email address:链接一个email地址

  • Linking to telephone numbers:链接电话号码

  • Using the download attribute to save a <canvas> as a PNG:下载图片

1
2
3
4
5
<ul>
<li><a href="https://www.baidu.com">Website</a></li>
<li><a href="mailto:example@outlook.com">Email</a></li>
<li><a href="tel:+123456789">Phone</a></li>
</ul>

内部地址

当我们需要跳转一个服务器内部的页面时,一般我们都会使用相对路径,会以./或../开头

●./ 表示当前文件所在目录,可以省略不写
●../表示当前文件所在目录的上一级目录

1
2
3
4
<a href="./test1.html">超链接1</a><br>
<a href="../test2.html">超链接2</a><br>
<a href="./test3/test3.html">超链接3</a><br>
<a href="../test4/test4.html">超链接4</a>

新建页面

target属性,用来指定超链接打开的位置可选值:

  • _self在当前页面中打开超链接,默认值

  • _blank在新建页面中打开超链接

1
2
3
<a href="./test1.html">超链接1——默认</a><br>
<a href="./test1.html" target="_self">超链接1——当前页面</a><br>
<a href="./test1.html" target="_blank">超链接1——新建页面</a><br>

锚点跳转

可以使用javascript:void(0);来作为href的属性,此时点击这个超链接什么也不会发生

可以将#作为超链接的路径的占位符使用。

可以直接将超链接的href属性设置为#,这样点击超链接以后页面不会发生跳转,而是转到当前页面的顶部的位置

可以跳转到页面的指定位置(锚点),只需将href属性设置#目标元素的id属性值(唯一不重复)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<p> 汉皇重色思倾国,御宇多年求不得。</p>
<p> 杨家有女初长成,养在深闺人未识。 </p>
<p> 天生丽质难自弃,一朝选在君王侧。 </p>
<p><a id="Anchor1" href="#Anchor2"> 回眸一笑百媚生,六宫粉黛无颜色。</a></p>
<p> 春寒赐浴华清池,温泉水滑洗凝脂。 </p>
<p> 侍儿扶起娇无力,始是新承恩泽时。 </p>
...
<p> 承欢侍宴无闲暇,春从春游夜专夜。 </p>
<p><a id="Anchor2" href="#Anchor3"> 后宫佳丽三千人,三千宠爱在一身。</a></p>
<p> 金屋妆成娇侍夜,玉楼宴罢醉和春。 </p>
<p> 姊妹弟兄皆列土,可怜光彩生门户。 </p>
...
<p><a id="Anchor3" href="#Anchor4"> 迟迟钟鼓初长夜,耿耿星河欲曙天。 </a></p>
<p> 鸳鸯瓦冷霜华重,翡翠衾寒谁与共。 </p>
<p> 悠悠生死别经年,魂魄不曾来入梦。 </p>
...
<p><a id="Anchor4" href="#Anchor5"> 风吹仙袂飘飖举,犹似霓裳羽衣舞。 </a></p>
<p> 玉容寂寞泪阑干,梨花一枝春带雨。 </p>
<p> 含情凝睇谢君王,一别音容两渺茫。 </p>
...
<p><a id="Anchor5" href="#Anchor6"> 在天愿作比翼鸟,在地愿为连理枝。 </a></p>
<p> 天长地久有时尽,此恨绵绵无绝期。 </p>
<!-- Heading to link to -->
<a href="#">回到顶部</a>

13. 图片

图片标签用于向当前页面中引入一个外部图片

img标签是一个自结束标签,这种元素属于替换元素(块和行内元素之间,具有两种元素的特点)

属性

●src:属性指定的是外部图片的路径(路径规则和超链接是一样的)
●alt:图片的描述,这个描述默认情况下不会显示,有些浏览器会在图片无法加载时显示,搜索引擎会根据alt中的内容来识别图片
●width:图片的宽度(单位是像素)
●height :图片的高度(单位是像素)
●宽度和高度中如果只修改了一个,则另一个会等比例缩放

注意

●一般情况在pc端,不建议修改图片的大小,需要多大的图片就裁多大
●但是在移动端,经常需要对图片进行缩放(大图缩小)

举例

1
2
<img src="https://gitee.com/vectorx/ImageCloud/raw/master/img/20210513002416.png" alt="蒂姆·伯纳斯·李爵士,万维网的发明人">
<img src="https://gitee.com/vectorx/ImageCloud/raw/master/html5/20210514233853.gif" alt="结构、表现、行为">

图片格式

jpeg(jpg)

  • 支持的颜色比较丰富

  • 不支持透明效果

  • 不支持动图

  • 一般用来显示照片

gif

  • 支持的颜色比较单一

  • 支持简单透明

  • 支持动图

png

  • 支持的颜色丰富

  • 支持复杂透明

  • 不支持动图

  • 专为网页而生

webp

  • 这种格式是谷歌新推出的专门用来表示网页中的图片的一种格式

  • 具备其他图片格式的所有优点,而且文件还特别的小

  • 缺点:兼容性不好

base64

  • 将图片使用base64编码,这样可以将图片转换为字符,通过字符的形式来引入图片
    图片格式的选择

  • 图片效果一样的,选文件小的

  • 图片效果不一样的,选图片效果好的

  • 尽可能的兼顾和平衡图片效果和文件大小

14. 内联格式

内联框架iframe,用于向当前页面中引入一个其他页面,

  • src指定要引入的网页的路径

  • frameborder指定内联框架的边框

1
<iframe src="https://www.qq.com" width="800" height="600" frameborder="0"></iframe>

15. 音视频

音频

audio标签用来向页面中引入一个外部的音频文件

音视频文件引入时,默认情况下不允许用户自己控制播放停止

属性

  • controls是否允许用户控制播放

  • autoplay音频文件是否自动播放

    • 如果设置了autoplay,则音乐在打开页面时会自动播放
    • 但是目前来讲大部分浏览器都不会自动对音乐进行播放
  • loop音乐是否循环播放

1
<audio src="./source/audio.mp3" controls autoplay loop></audio>

source

除了通过src属性来指定外部文件的路径以外,还可以通过<source>元素来指定文件的路径

1
2
3
4
5
<audio controls autoplay loop>
对不起,您的浏览器不支持播放音频!请升级浏览器!
<source src="./source/audio.mp3">
<source src="./source/audio.ogg">
</audio>

IE11下,能够正常播放

embed

IE8下不支持audio元素,但是可以使用 <embed> 元素在文档中的指定位置嵌入外部内容。

这个内容是由外部应用程序或其他互动内容的来源提供的,如浏览器插件。

1
<embed src="./source/audio.mp3">

视频

使用video标签来向网页中引入一个视频,使用方式和audio基本上是一样的

1
2
3
4
5
<video controls>
<source src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webm" type="video/webm">
<source src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4" type="video/mp4">
<embed src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4" type="video/mp4">
</video>

IE11下,能够正常播放

16.其他

通过iframeembed的方式引入视频。以某艺为例,提供了视频链接的HTML代码和通用代码

1
2
3
4
<iframe
src="http://open.iqiyi.com/developer/player_js/coopPlayerIndex.html?vid=0c53ddd55f262c6d416afa9d1f49dc55&tvId=1008748400&accessToken=2.ef9c39d6c7f1d5b44768e38e5243157d&appKey=8c634248790d4343bcae1f66129c1010&appId=1368&height=100%&width=100%"
frameborder="0" allowfullscreen="true" width="100%" height="100%">
</iframe>

不过,embed需要flash的支持

1
2
3
4
5
<embed
src="//player.video.iqiyi.com/0c53ddd55f262c6d416afa9d1f49dc55/0/0/v_19rrcuh1jw.swf-albumId=1008748400-tvId=1008748400-isPurchase=0-cnId=undefined"
allowFullScreen="true" quality="high" width="480" height="350" align="middle" allowScriptAccess="always"
type="application/x-shockwave-flash">
</embed>

CSS部分

CSS简介

CSS的发展历程
从HTML被发明开始,样式就以各种形式存在。不同的浏览器结合它们各自的样式语言为用户提供页面效果的控制。最初的HTML只包含很少的显示属性。随着HTML的成长,为了满足页面设计者的要求,HTML添加了很多显示功能。但是随着这些功能的增加,HTML变的越来越杂乱,而且HTML页面也越来越臃肿。于是CSS便诞生了。
CSS样式规则
使用HTML时,需要遵从一定的规范。CSS亦如此,要想熟练地使用CSS对网页进行修饰,首先需要了解CSS样式规则,具体格式如下:

在上面的样式规则中:

1.选择器用于指定CSS样式作用的HTML对象,花括号内是对该对象设置的具体样式。
2.属性和属性值以“键值对”的形式出现。
3.属性是对指定的对象设置的样式属性,例如字体大小、文本颜色等。
4.属性和属性值之间用英文“:”连接。
5.多个“键值对”之间用英文“;”进行区分。
可以用段落 和 表格的对齐的演示。

CSS基本语法

层叠样式表

网页实际上是一个多层的结构,通过CSS可以分别为网页的每一个层来设置样式,而最终我们能看到只是网页的最上边一层

总之一句话,CSS用来设置网页中元素的样式

使用CSS来修改元素样式的方式大致可以分为3种

内联样式(行内样式)

在标签内部通过style属性来设置元素的样式

1
<p style="color:red;font-size:60px;">内联样式(行内样式)</p>

问题:使用内联样式,样式只能对一个标签生效。如果希望影响到多个元素,必须在每一个元素中都复制一遍;并且当样式发生变化时,我们必须要一个一个的修改,非常的不方便。(注意:开发时绝对不要使用内联样式)

内部样式表

将样式编写到head中的style标签里然后通过css的选择器来选中元素并为其设置各种样式可以同时为多个标签设置样式,并且修改时只需要修改一处即可。内部样式表更加方便对样式进行复用

1
2
3
4
5
6
<style>
p{
color:green;
font-size:50px;
}
</style>

问题:我们的内部样式表只能对一个网页起作用,它里边的样式不能跨页面进行复用

外部样式表

可以将css样式编写到一个外部的CSS文件中,然后通过link标签来引入外部的CSS文件

1
<link rel="stylesheet" href="./style.css">

外部样式表需要通过link标签进行引入,意味着只要想使用这些样式的网页都可以对其进行引用使样式,可以在不同页面之间进行复用

将样式编写到外部的CSS文件中,可以使用到浏览器的缓存机制,从而加快网页的加载速度,提高用户的体验。

CSS字体样式属性

font-size:字号大小
font-size属性用于设置字号,该属性的值可以使用相对长度单位,也可以使用绝对长度单位。其中,相对长度单位比较常用,推荐使用像素单位px,绝对长度单位使用较少。具体如下:

font-family:字体
font-family属性用于设置字体。网页中常用的字体有宋体、微软雅黑、黑体等,例如将网页中所有段落文本的字体设置为微软雅黑,可以使用如下CSS样式代码:

p{ font-family:”微软雅黑”;}

可以同时指定多个字体,中间以逗号隔开,表示如果浏览器不支持第一个字体,则会尝试下一个,直到找到合适的字体。

常用技巧:

  1. 现在网页中普遍使用14px+。
  2. 尽量使用偶数的数字字号。ie6等老式浏览器支持奇数会有bug。
  3. 各种字体之间必须使用英文状态下的逗号隔开。
  4. 中文字体需要加英文状态下的引号,英文字体一般不需要加引号。当需要设置英文字体时,英文字体名必须位于中文字体名之前。
  5. 如果字体名中包含空格、#、$等符号,则该字体必须加英文状态下的单引号或双引号,例如font-family: “Times New Roman”;。
  6. 尽量使用系统默认字体,保证在任何用户的浏览器中都能正确显示。

CSS Unicode字体
在 CSS 中设置字体名称,直接写中文是可以的。但是在文件编码(GB2312、UTF-8 等)不匹配时会产生乱码的错误。xp 系统不支持 类似微软雅黑的中文。

方案一: 你可以使用英文来替代。 比如 font-family:”Microsoft Yahei”。

方案二: 在 CSS 直接使用 Unicode 编码来写字体名称可以避免这些错误。使用 Unicode 写中文字体名称,浏览器是可以正确的解析的。font-family: “\5FAE\8F6F\96C5\9ED1”,表示设置字体为“微软雅黑”。

可以通过escape() 来测试属于什么字体。

font-weight:字体粗细

字体加粗除了用 b 和 strong 标签之外,可以使用CSS 来实现,但是CSS 是没有语义的。

1
font-weight属性用于定义字体的粗细,其可用属性值:normal、bold、bolder、lighter、100~900(100的整数倍)。

数字 400 等价于 normal,而 700 等价于 bold。 但是我们更喜欢用数字来表示。

font-style:字体风格

字体倾斜除了用 i 和 em 标签之外,可以使用CSS 来实现,但是CSS 是没有语义的。

font-style属性用于定义字体风格,如设置斜体、倾斜或正常字体,其可用属性值如下:

normal:默认值,浏览器会显示标准的字体样式。

italic:浏览器会显示斜体的字体样式。

oblique:浏览器会显示倾斜的字体样式。

小技巧:

1
平时我们很少给文字加斜体,反而喜欢给斜体标签(em,i)改为普通模式。

font:综合设置字体样式 (重点)

font属性用于对字体样式进行综合设置,其基本语法格式如下:

1
选择器{font: font-style  font-weight  font-size/line-height  font-family;}
1
2
3
使用font属性时,必须按上面语法格式中的顺序书写,不能更换顺序,各个属性以空格隔开。

注意:其中不需要设置的属性可以省略(取默认值),但必须保留font-size和font-family属性,否则font属性将不起作用。

注释

css中的注释

只能使用/**/包裹。即不管是单行注释,还是多行注释,都是以/*开头,以*/结尾

1
2
3
4
5
6
7
/* css中的单行注释 */

/*
css中的多行注释
css中的多行注释
css中的多行注释
*/

我们对比下其他几种前端语言的注释

html中的注释

只能使用<!---->包裹。即不管是单行注释,还是多行注释,都是以<!--开头,以-->结尾

1
2
3
4
5
6
7
<!-- html中的单行注释 -->

<!--
html中的多行注释
html中的多行注释
html中的多行注释
-->

JavaScript中的注释

单行注释使用//。多行注释使用/**/包裹,以<!--开头,以-->结尾

1
2
3
4
5
6
7
/* JS(JavaScript)和JQuery中的单行注释*/

/*
JS(JavaScript)和JQuery中的多行注释
JS(JavaScript)和JQuery中的多行注释
JS(JavaScript)和JQuery中的多行注释
*/

选择器

通过选择器可以选中页面中的指定元素

  • 比如p的作用就是选中页面中所有的p元素声明块

声明块

通过声明块来指定要为元素设置的样式

  • 声明块由一个一个的声明组成,声明是一个名值对结构

  • 一个样式名对应一个样式值,名和值之间以:连接,以;结尾

1
2
3
h1{
color: green;
}

选择器的权重

当我们通过不同的选择器,选中相同的元素,并且为相同的样式设置不同的值时,此时就发生了样式的冲突。

发生样式冲突时,应用哪个样式由选择器的权重(优先级)决定选择器的权重

选择器 权重
内联样式 1, 0, 0, 0
ID选择器 0, 1, 0, 0
类和伪类选择器 0, 0, 1, 0
元素选择器 0, 0, 0, 1
通配选择器 0, 0, 0, 0
继承的样式 没有优先级

通配选择器

  • 作用:选中页面中的所有元素

  • 语法:*

例子:*{}

1
2
3
*{
color: red;
}

元素选择器

也叫类型选择器、标签选择器

  • 作用:根据标签名来选中指定的元素

  • 语法:elementname{}

  • 例子:p{} h1{} div{}

1
2
3
4
5
6
p{
color: red;
}
h1{
color: green;
}

类选择器

  • 作用:根据元素的class属性值选中一组元素

  • 语法:.classname

  • 例子:.blue{}

1
2
3
4
5
6
.blue{
color: blue;
}
.size{
font-size: 20px;
}
1
class`是一个标签的属性,它和`id`类似,不同的是`class
  • 可以重复使用,

  • 可以通过class属性来为元素分组,

  • 可以同时为一个元素指定多个class属性

1
<p class="blue size"> 类选择器(Class selector)</p>

ID选择器

  • 作用:根据元素的id属性值选中一个元素

  • 语法:#idname{}

  • 例子:#box{} #red{}

1
2
3
#red{
color: red;
}

属性选择器

  • 作用:根据元素的属性值选中一组元素

  • 语法1:[属性名] 选择含有指定属性的元素

  • 语法2:[属性名=属性值] 选择含有指定属性和属性值的元素

  • 语法3:[属性名^=属性值] 选择属性值以指定值开头的元素

  • 语法4:[属性名$=属性值] 选择属性值以指定值结尾的元素

  • 语法5:[属性名*=属性值] 选择属性值中含有某值的元素

  • 例子:p[title]{} p[title=e]{} p[title^=e]{} p[title$=e]{} p[title*=e]{}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
p[title]{
color: orange;
}
p[title=e]{
color: orange;
}
p[title^=e]{
color: orange;
}
p[title$=e]{
color: orange;
}
p[title*=e]{
color: orange;
}

复合选择器

交集选择器

  • 作用:选中同时复合多个条件的元素

  • 语法:选择器1选择器2选择器3选择器n{}

  • 注意点:交集选择器中如果有元素选择器,必须使用元素选择器开头

1
2
3
4
5
6
7
div.red{
font-size: 30px;
}

.a.b.c{
color: blue;
}

并集选择器

  • 作用:同时选择多个选择器对应的元素

  • 语法:选择器1,选择器2,选择器3,选择器n{}

  • 例子:#b1,.p1,h1,span,div.red{}

1
2
3
h1,span{
color: green;
}

关系选择器

  • 父元素:直接包含子元素的元素叫做父元素

  • 子元素:直接被父元素包含的元素是子元素

  • 祖先元素:直接或间接包含后代元素的元素叫做祖先元素;一个元素的父元素也是它的祖先元素

  • 后代元素:直接或间接被祖先元素包含的元素叫做后代元素;子元素也是后代元素

  • 兄弟元素:拥有相同父元素的元素是兄弟元素

子元素选择器

  • 作用:选中指定父元素的指定子元素

  • 语法:父元素 > 子元素

  • 例子:A > B

1
2
3
div.box > p > span{
color: orange;
}

后代元素选择器

  • 作用:选中指定元素内的指定后代元素

  • 语法:祖先 后代

  • 例子:A B

1
2
3
div span{
color: skyblue;
}

兄弟元素选择器

  • 作用:选择下一个兄弟

  • 语法:前一个 + 下一个 前一个 + 下一组

  • 例子1:A1 + A2(Adjacent sibling combinator)

  • 例子2: A1 ~ An(General sibling combinator)

1
2
3
4
5
6
7
p + span{
color: red;
}

p ~ span{
color: red;
}

伪类选择器

伪类(不存在的类,特殊的类)

伪类用来描述一个元素的特殊状态,比如:第一个子元素、被点击的元素、鼠标移入的元素.…

伪类一般情况下都是使用:开头

  • :first-child 第一个子元素

  • :last-child 最后一个子元素

  • :nth-child() 选中第n个子元素

    • n:第n个,n的范围0到正无穷
    • 2n或even:选中偶数位的元素
    • 2n+1或odd:选中奇数位的元素

以上这些伪类都是根据所有的子元素进行排序的

  • :first-of-type 同类型中的第一个子元素

  • :last-of-type 同类型中的最后一个子元素

  • :nth-of-type() 选中同类型中的第n个子元素

这几个伪类的功能和上述的类似,不同点是他们是在同类型元素中进行排序的

  • :not()否定伪类,将符合条件的元素从选择器中去除
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* ul下所有li,黑色 */
ul>li {
color: black;
}

/* ul下第偶数个li,黄色 */
ul>li:nth-child(2n) {
color: yellow;
}

/* ul下第奇数个li,绿色 */
ul>li:nth-child(odd) {
color: green;
}

/* ul下第一个li,红色 */
ul>li:first-child {
color: red;
}

/* ul下最后一个li,黄色 */
ul>li:last-child {
color: orange;
}
  • :link 未访问的链接

  • :visited 已访问的链接

    • 由于隐私的原因,所以visited这个伪类只能修改链接的颜色
  • :hover 鼠标悬停的链接

  • :active 鼠标点击的链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* unvisited link */
a:link {
color: red;
}

/* visited link */
a:visited {
color: yellow;
}

/* mouse over link */
a:hover {
color: green;
}

/* selected link */
a:active {
color: blue;
}

伪元素选择器

伪元素,表示页面中一些特殊的并不真实的存在的元素(特殊的位置)

伪元素使用::开头

  • ::first-letter 表示第一个字母

  • ::first-line 表示第一行

  • ::selection 表示选中的内容

  • ::before 元素的开始

  • ::after 元素的最后

  • ::before::after 必须结合content属性来使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/* 段落首字母设置大小为30px */
p::first-letter{
font-size: 30px;
}

/* 段落第一行设置为黄色背景 */
p::first-line{
background-color: yellow;
}

/* 段落选中的部分变绿色 */
p::selection{
background-color: green;
}

/* div前加上内容 */
div::before{
content: 'BEFORE';
color: red;
}

/* div后加上内容 */
div::after{
content: 'AFTER';
color: blue;
}

CSS Dinner游戏

官方地址:CSS Diner - Where we feast on CSS Selectors!

CSS Dinner是一个帮助初学者快速熟悉css各种选择器的网页游戏

样式继承

继承

样式的继承,我们为一个元素设置的样式,同时也会应用到它的后代元素上

继承是发生在祖先后后代之间的,继承的设计是为了方便我们的开发

利用继承,我们可以将一些通用的样式,统一设置到共同的祖先元素上。这样只需设置一次即可让所有的元素都具有该样式

注意,并不是所有的样式都会被继承:

  • 比如背景相关的,布局相关等的这些样式都不会被继承。

我们可以再Zeal手册中,搜索background-color属性,可以看到一个定义的表格。其中就说明了其不可被继承性

选择器的权重

当我们通过不同的选择器,选中相同的元素,并且为相同的样式设置不同的值时,此时就发生了样式的冲突。

发生样式冲突时,应用哪个样式由选择器的权重(优先级)决定选择器的权重

选择器 权重
内联样式 1, 0, 0, 0
ID选择器 0, 1, 0, 0
类和伪类选择器 0, 0, 1, 0
元素选择器 0, 0, 0, 1
通配选择器 0, 0, 0, 0
继承的样式 没有优先级

比较优先级时,需要将所有的选择器的优先级进行相加计算,最后优先级越高,则越优先显示(分组选择器是单独计算的)

选择器的累加不会超过其最大的数量级,类选择器再高也不会超过ID选择器

如果优先级计算后相同,此时则优先使用靠下的样式

可以在某一个样式的后边添加!important,则此时该样式会获取到最高的优先级,甚至超过内联样式,注意:在开发中一定要慎用!

1
2
3
4
5
6
7
8
9
10
11
12
13
<style>
#box1{
background-color: orange;
}
div{
background-color: yellow;
}
.red{
background-color: red;
}
</style>

<div id="box1" class="red" style="background-color: skyblue;">选择器的权重</div>

长度单位

像素

我们先来看下某度上关于像素(pixel,缩写px)的介绍

像素是指由图像的小方格组成的,这些小方块都有一个明确的位置和被分配的色彩数值,小方格颜色和位置就决定该图像所呈现出来的样子。

可以将像素视为整个图像中不可分割的单位或者是元素。不可分割的意思是它不能够再切割成更小单位抑或是元素,它是以一个单一颜色的小格存在 [1] 。每一个点阵图像包含了一定量的像素,这些像素决定图像在屏幕上所呈现的大小。

也就是说,显示器屏幕实际上是由一个一个的小点(单位色块,即像素)构成的

问题1:像素和分辨率有什么关系呢?

1
分辨率 = 水平方向像素 * 垂直方向像素

屏幕分辨率

例如,屏幕分辨率是1920×1080,则该屏幕水平方向有1920个像素,垂直方向有1080个像素

  • 不同屏幕的像素大小是不同的,也就是说像素大小不像我们现行的长度单位(如米/m)那样有着固定的国际标准

  • 所以同样的像素大小在不同的设备上显示效果是不一样的,像素越小的屏幕显示的效果越清晰

图像分辨率

例如,一张图片分辨率是300x200,则该图片在屏幕上按1:1缩放时,水平方向有300个像素,垂直方向有200个像素点

  • 图片分辨率越高,1:1缩放时面积越大

  • 图片分辨率越低,1:1缩放时面积越小

同一台设备像素大小是不变的,那把图片放大超过100%时占的像素点就多了,但是图像也会变得模糊

问题2:屏幕实现图片放大或缩小的原理是什么呢?

  • 其实是设备通过算法对图像进行了像素补足;

  • 同理,把图片按小于100%缩放时,也是通过算法将图片像素减少

百分比

也可以将属性值设置为相对于其父元素属性的百分比,可以使子元素跟随父元素(暂且先理解成父元素,后面会详细说)的改变而改变

em

em是相对于元素的字体大小来计算的,1em = <self>.font-size * 10,也就说em值会根据元素本身的字体大小的改变而改变

rem

rem是相对于根元素的字体大小来计算,1em = <root>.font-size * 10,也就说em值会根据根元素的字体大小的改变而改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<style>
* {
font-size: 24px;
}
.box1{
width: 200px;
height: 200px;
background-color: orange;
}
.box2{
width: 50%;
height: 50%;
background-color: aqua;
}
.box3{
font-size: 20px;
width: 10em;
height: 10em;
background-color: greenyellow;
}
.box4 {
font-size: 20px;
width: 10rem; /*当时用rem时,不管怎么改本元素的font-size都是不会变的。需要定义root元素的font-size才可以 */
height: 10rem;
background-color: red;
}
</style>
<div class="box1">
<div class="box2"></div>
</div>
<div class="box3"></div>
<div class="box4"></div>

颜色单位

颜料三原色(CMYK):品红、黄、青(天蓝)。色彩三原色可以混合出所有颜料的颜色,同时相加为黑色,黑白灰属于无色系。

光学三原色(RGB):红、绿、蓝(靛蓝)。光学三原色混合后,组成显示屏显示颜色,三原色同时相加为白色,白色属于无色系(黑白灰)中的一种。

RGB通过三原色的不同浓度来调配出不同的颜色

  • 语法:RGB(red, green, blue)

  • 范围:每一种颜色的范围在0 ~ 255(0% ~ 100%)之间

RGBA

就是在rgb的基础上增加了一个a表示不透明度

  • 1表示完全不透明

  • 0表示完全透明

  • .5半透明

如果颜色两位两位重复可以进行简写,如#aabbcc => #abc

在vscode中,我们可以看到其会对颜色进行预览展示。并且将鼠标移至color处悬浮,会智能的弹出一个rgb调色板,方便我们进行调色

我们可以直接搜索黄色,哦不是,取色器!有些录制软件也会自带取色功能,如FastStone Capture

下载地址:FastStone Capture - Download

盒模型

文档流

网页是一个多层的结构,一层摁着一层

通过CSS可以分别为每一层来设置样式,作为用户来讲只能看到最顶上一层

这些层中,最底下的一层称为文档流

文档流是网页的基础我们所创建的元素默认都是在文档流中进行排列

对于我们来元素主要有两个状态

  • 在文档流中

  • 不在文档流中(脱离文档流)

那么元素在文档流中有什么特点,我们接着往下看

块元素

  • 块元素会在页面中独占一行

  • 默认宽度是父元素的全部(会把父元素撑满)

  • 默认高度是被内容撑开(子元素)

行内元素

  • 行内元素不会独占页面的一行,只占自身的大小

  • 行内元素在页面中左向右水平排列(书写习惯一致)

  • 如果一行之中不能容纳下所有的行内元素,则元素会换到第二行继续自左向右排列

  • 行内元素的默认宽度和高度都是被内容撑开

盒子模型

网页设计中常听的属性名:内容(content)、内边距(padding)、边框(border)、外边距(margin), CSS盒子模型都具备这些属性。

这些属性我们可以用日常生活中的常见事物——盒子作一个比喻来理解,所以叫它盒子模型。

CSS盒子模型就是在网页设计中经常用到的CSS技术所使用的一种思维模型。

盒模型、盒子模型、框模型

CSS将页面中的所有元素都设置为了一个矩形的盒子

将元素设置为矩形的盒子后,对页面的布局就变成将不同的盒子摆放到不同的位置

每一个盒子都由一下几个部分组成:

  • 内容区(content)

  • 内边距(padding)

  • 边框(border)

  • 外边距(margin)

内容区(content)

内容区是盒子模型的中心,它呈现了盒子的主要信息内容,这些内容可以是文本、图片等多种类型

元素中的所有的子元素和文本内容都在内容区中

  • width和height 设置排列内容区的大小

  • width 设置内容区的宽度

  • height 设置内容区的高度

1
2
3
4
5
.box1{
width: 200px;
height: 200px;
background-color: #bfa;
}

边框(border)

边框属于盒子边缘,边框里边属于盒子内部,出了边框都是盒子的外部

注意:边框的大小会影响到整个盒子的大小

  • border-width 边框的宽度:默认3px

    • border-top-width 上边框的宽度
    • border-right-width 右边框的宽度
    • border-bottom-width 下边框的宽度
    • border-left-width 左边框的宽度
  • border-color 边框的颜色:默认使用color的颜色值

  • border-top-color 上边框的颜色

  • border-right-color 右边框的颜色

  • border-bottom-color 下边框的颜色

  • border-left-color 左边框的颜色

  • border-style 边框的样式:没有默认值,必须指定

    • border-top-style 上边框的样式
    • border-right-style 右边框的样式
    • border-bottom-style 下边框的样式
    • border-left-style 左边框的样式
1
2
3
4
5
6
7
8
9
10
11
.box1{
border-width: 10px;
border-color: red;
/*
solid 实线
dotted 点状虚线
dashed 虚线
double 双线
*/
border-style: solid;
}

效果(solid)

效果(dotted)

效果(dashed)

效果(dashed)

不论是border-widthborder-colorborder-style 还是其衍生出来的属性写法,都可以指定每个方向的边框情况

设定几个值就决定了对应方向的宽度、颜色或样式

  • 四个值:上 右 下 左

  • 三个值:上 左右 下

  • 两个值:上下 左右

  • 一个值:上下左右

其实不管设置几个值,只要记住:其顺序是按顺时针方向设置的,剩下的可以由矩形的对称性推导出来

border:简写属性,通过该属性可以同时设置边框所有的相关样式,并且没有顺序要求

  • border-top 上边框的宽度、颜色和样式

  • border-right 右边框的宽度、颜色和样式

  • border-bottom 下边框的宽度、颜色和样式

  • border-left 左边框的宽度、颜色和样式

1
2
3
.box1{ 
border: 10px red solid;
}

内边距(padding)

内边距,也叫填充,是内容区和边框之间的空间

  • padding-top 上内边距

  • padding-right 右内边距

  • padding-bottom下内边距

  • padding-left 左内边距

padding内边距的简写属性,可以同时指定四个方向的内边距,规则和边框中属性值设置一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<style>
.outer{
width: 200px;
height: 200px;
border: 10px orange solid;
padding-right: 100px;
padding-bottom: 100px;
padding-left: 100px;
}

.inner {
width: 200px;
height: 200px;
background-color: greenyellow;
}
</style>

<div class="outer">
<div class="inner"></div>
</div>

可以看出,当内外div宽度和高度一样时,由于outer设置了一个padding属性,其盒子大小被“撑大了”

盒子可见框的大小,由内容区、内边距和边框共同决定,所以在计算盒子大小时,需要将这三个区域加到一起计算

外边距(margin)

外边距,也叫空白边,位于盒子的最外围,是添加在边框外周围的空间。空白边使盒子之间不会紧凑地连接在一起,是CSS 布局的一个重要手段

注意:外边距不会影响盒子可见框的大小,但是外边距会影响盒子的位置和占用空间

一共有四个方向的外边距:

  • margin-top 上外边距

    • 设置正值,元素自身向下移动
    • 设置负值,元素自身向上移动
  • margin-right 右外边距

    • 设置正值,其右边的元素向右移动
    • 设置负值,其右边的元素向左移动
    • 上述说法并不准确,对于块元素,设置margin-right不会产生任何效果
  • margin-bottom 下外边距

    • 设置正值,其下边的元素向下移动
    • 设置负值,其下边的元素向上移动
    • 上述说法并不准确,对于块元素,会有垂直方向上的边距重叠问题(后面会细说)
  • margin-left 左外边距

    • 设置正值,元素自身向右移动
    • 设置负值,元素自身向左移动

元素在页面中是按照自左向右的顺序排列的,所以默认情况下

  • 如果我们设置的左和上外边距则会移动元素自身

  • 而设置下和右外边距会移动其他元素

1
2
3
4
5
6
7
8
9
10
11
.box1 {
width: 200px;
height: 200px;
background-color: #bfa;
border: 10px orange solid;

margin-top: 100px;
margin-right: 100px;
margin-bottom: 100px;
margin-left: 100px;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.box1 {
width: 200px;
height: 200px;
background-color: #bfa;
border: 10px orange solid;
margin-bottom: 100px;

}

.box2 {
width: 200px;
height: 200px;
background-color: #bfa;
border: 10px red solid;
margin-top: 100px;
}

水平方向布局

元素在其父元素中水平方向的位置由以下几个属性共同决定

  • margin-left

  • border-left

  • padding-left

  • width

  • padding-right

  • border-right

  • margin-right

一个元素在其父元素中,水平布局必须要满足以下的等式

1
margin-left + border-left + padding-left + width + padding-right + border-right + margin-right = 其父元素的宽度

以上等式必须满足,如果相加结果使等式不成立,则称为过渡约束

则等式会自动调整调整的情况:

  • 如果这七个值中没有auto的情况,则浏览器会自动调整margin-right值以使等式满足
    100 + 0 + 0 + 200 + 0 + 0 + 0 = 800 ==> 100 + 0 + 0 + 200 + 0 + 0 + 500 = 800

  • 如果这七个值中有auto的情况,则会自动调整auto值以使等式成立
    这七个值中有三个值可以设置为autowidthmargin-leftmaring-right

    1. 如果某个值为auto,则会自动调整auto的那个值以使等式成立
      200 + 0 + 0 + auto + 0 + 0 + 200 = 600 ==> 200 + 0 + 0 + 400 + 0 + 0 + 200 = 800
      auto + 0 + 0 + 200 + 0 + 0 + 200 = 600 ==> 400 + 0 + 0 + 200 + 0 + 0 + 200 = 800
      200 + 0 + 0 + 200 + 0 + 0 + auto = 600 ==> 200 + 0 + 0 + 200 + 0 + 0 + 400 = 800
    2. 如果宽度为auto,则宽度会调整到最大,其他auto的外边距会自动设置为0
      auto + 0 + 0 + auto + 0 + 0 + 200 = 600 ==> 0 + 0 + 0 + 600 + 0 + 0 + 200 = 800
      200 + 0 + 0 + auto + 0 + 0 + auto = 600 ==> 200 + 0 + 0 + 600 + 0 + 0 + 0 = 800
      auto + 0 + 0 + auto + 0 + 0 + auto = 600 ==> 0 + 0 + 0 + 800 + 0 + 0 + 0 = 800
    1. 如果外边距都为auto,则auto的外边距会自动均分以使等式成立
      auto + 0 + 0 + 200 + 0 + 0 + auto = 600 ==> 300 + 0 + 0 + 200 + 0 + 0 + 300 = 800

垂直方向布局

元素溢出

子元素是在父元素的内容区中排列的,如果子元素的大小超过了父元素,则子元素会从父元素中溢出

使用overflow/overflow-x/overflow-y属性来设置父元素如何处理溢出的子元素

可选值:visible/hidden/scroll/auto

visible 溢出内容会在父元素外部位置显示,默认值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<style>
.box1 {
width: 200px;
height: 200px;
background-color: #bfa;
border: 10px orange solid;
overflow: visible; /* 默认值 */
}
</style>
<div class="box1">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Asperiores aspernatur illo inventore
deleniti laudantium quaerat excepturi sed quidem tempore? Eaque, cumque porro. Fuga quam error cupiditate quasi
eveniet in numquam!
</div>

hidden 溢出内容会被裁剪,不会显示

1
2
3
4
5
6
7
8
9
10
11
12
13
<style>
.box1 {
width: 200px;
height: 200px;
background-color: #bfa;
overflow: hidden; /* 隐藏溢出内容 */
}
</style>
<div class="box1">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Asperiores aspernatur illo inventore
deleniti laudantium quaerat excepturi sed quidem tempore? Eaque, cumque porro. Fuga quam error cupiditate quasi
eveniet in numquam!
</div>

scroll 生成两个滚动条,通过滚动条来查看完整的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
<style>
.box1 {
width: 200px;
height: 200px;
background-color: #bfa;
overflow: scroll;
}
</style>
<div class="box1">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Asperiores aspernatur illo inventore
deleniti laudantium quaerat excepturi sed quidem tempore? Eaque, cumque porro. Fuga quam error cupiditate quasi
eveniet in numquam!
</div>

auto 根据需要生成滚动条

1
2
3
4
5
6
7
8
9
10
11
12
13
<style>
.box1 {
width: 200px;
height: 200px;
background-color: #bfa;
overflow: auto;
}
</style>
<div class="box1">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Asperiores aspernatur illo inventore
deleniti laudantium quaerat excepturi sed quidem tempore? Eaque, cumque porro. Fuga quam error cupiditate quasi
eveniet in numquam!
</div>

边距折叠

垂直外边距的重叠(折叠):相邻的垂直方向外边距会发生重叠现象

兄弟元素

兄弟元素间的相邻,垂直外边距会取两者之间的较大值(两者都是正值)

特殊情况:

  • 如果相邻的外边距一正一负,则取两者的和

  • 如果相邻的外边距都是负值,则取两者中绝对值较大的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.box1,.box2{ 
width:200px;
height:200px;
font-size:100px;
}

.boxl{
background-color: #bfa;
/*设置一个下外边距*/
margin-bottom: 100px;
}

.box2{
background-color: orange;
/*设置一个上外边距*/
margin-top: 100px;
}

疑问

当浏览器缩放比例是100%时,我们使用FastStone Capture工具自带的刻度尺测量,发现“兄弟”之间似乎没有我们想象的那么“亲近”

两者的垂直方向间距是125px,我们明明上下元素设置的都是100px啊,这是为什么呢?

在网页布局中,通过谷歌浏览器或火狐浏览器预览时,发现我们定义的盒模型width,height,margin,padding 值都是不准确的

谷歌、火狐浏览器 缩放为80% 时,margin值才正确[2]

总结

兄弟元素之间的外边距的重叠,对于开发是有利的,所以我们不需要进行处理

父子元素

父子元素间相邻外边距,子元素会传递给父元素(上外边距)

1
2
3
4
5
6
7
8
9
10
11
12
.box3{
width200px;
height:200px;
background-color: #bfa;
}

.box4{
width: 100px;
height: 100px;
background-color: orange;
/* margin-top: 100px; */
}

处理方式1

1、我们转换思路,将对子元素的调整转为对父元素的调整

1
2
3
4
5
6
7
8
9
10
11
12
13
.box3 {
width: 200px;
height: 200px;
background-color: #bfa;
padding-top: 100px; /* 不调整子元素的margin,而是转而调整父元素的padding */
}

.box4 {
width: 100px;
height: 100px;
background-color: orange;
/* margin-top: 100px; */
}

可以看到父元素位置虽然正确了,但是高度却被“撑大了”。我们之前说过,padding属性会影响元素的大小[3]

2、这里我们还需要计算并手动调整下父元素的高度

1
2
3
4
5
6
7
8
9
10
11
12
.box3 {
width: 200px;
height: 100px; /* height: 200px; */
background-color: #bfa;
padding-top: 100px;
}

.box4 {
width: 100px;
height: 100px;
background-color: orange;
}

处理方式2

1、我们仍然保留子元素的margin-top属性,但是给父元素加一个上边框

1
2
3
4
5
6
7
8
9
10
11
12
13
.box3 {
width: 200px;
height: 200px;
background-color: #bfa;
border-top: 1px rebeccapurple solid; /* 在父元素上加一个border-top(上边框) */
}

.box4 {
width: 100px;
height: 100px;
background-color: orange;
margin-top: 100px; /* 不删除,保留 */
}

2、但是因为加了1px的边框,所以父元素盒子的高度也增加了1px。那我们就需要手动调整父元素的高度,同时让边框颜色与父元素盒子颜色保持一致.

1
2
3
4
5
6
7
8
9
10
11
12
13
.box3 {
width: 200px;
height: 199px; /* height: 200px; */
background-color: #bfa;
border-top: 1px #bfa solid;
}

.box4 {
width: 100px;
height: 100px;
background-color: orange;
margin-top: 100px;
}

但是我们没有发现一个问题不难发现一个问题,子元素也往下移动了1px的距离

因为父元素高度少了1px,而子元素的margin-top是从边框下面开始算的

所以,凭借大家朴素的情感,哪个应该怎么判? 应该怎么改?

改法也很简单,margin-top减去一个像素即可

1
2
3
4
5
6
7
8
9
10
11
12
13
.box3 {
width: 200px;
height: 199px;
background-color: #bfa;
border-top: 1px #bfa solid;
}

.box4 {
width: 100px;
height: 100px;
background-color: orange;
margin-top: 99px; /* margin-top: 100px; */
}

脱离文档流

上述示例2中,使用了border属性,就让子元素的外边距不去传递给父元素了,这是为什么呢?

margin (子元素远离父元素边框)[4]

如果父盒子没有设置border框着,那么他的子元素无法利用margin-top 来远离父元素的上边框

如果使用了margin-top会使子元素和父元素一起往下移

(子想离,父不设置border边框 则离得是流 不是父盒子)

行内元素的盒模型

行内元素不支持设置宽度和高度

1
2
3
4
5
6
.s1 {
/* 行内元素设置了宽高也没用,不会生效 */
width: 100px;
height: 100px;
background-color: yellow;
}

行内元素可以设置padding,但是垂直方向padding不会影响页面的布局

1
2
3
4
5
6
7
8
9
10
11
.s1 {
/* 下方的div元素并没有因span设置了padding属性,而受到位置上的影响 */
padding: 100px;
background-color: yellow;
}

.box1 {
width: 200px;
height: 200px;
background-color: #bfa;
}

行内元素可以设置border,垂直方向的border不会影响页面的布局

1
2
3
4
5
6
7
8
9
10
.s1 {
border: 10px orange solid;
background-color: yellow;
}

.box1 {
width: 200px;
height: 200px;
background-color: #bfa;
}

● 行内元素可以设置margin,垂直方向的margin不会影响页面的布局

1
2
3
4
5
6
7
8
9
10
.s1 {
margin: 100px;
background-color: yellow;
}

.box1 {
width: 200px;
height: 200px;
background-color: #bfa;
}

如果我就是想要行内元素对页面布局产生影响呢?

那就拉出去枪毙了!那也是有办法的!

display用来设置元素显示的类型

  • inline将元素设置为行内元素

  • block将元素设置为块元素

1
2
3
4
5
6
.s1 {
margin: 100px;
background-color: yellow;
/* 将行内元素设置为块元素 */
display: block;
}

inline-block 将元素设置为行内块元素行内块,既可以设置宽度和高度又不会独占一行

1
2
3
4
5
6
.s1 {
margin: 100px;
background-color: yellow;
/* 将行内元素设置为行内块元素,兼顾行内元素和块元素的特点 */
display: inline-block;
}
  • table将元素设置为一个表格

  • none元素不在页面中显示

1
2
3
4
5
6
.s1 {
margin: 100px;
background-color: yellow;
/* 将行内元素设置为none:不显示 */
display: none;
}

不显示是不显示了,但是原来属于s1的位置也没了

visibility用来设置元素的显示状态

  • visible默认值,元素在页面中正常显示

  • hidden元素在页面中隐藏不显示,但是依然占据页面的位置

1
2
3
4
5
6
.s1 {
margin: 100px;
background-color: yellow;
display: block;
visibility: hidden;
}

浏览器的默认样式

通常情况,浏览器都会为元素设置一些默认样式

默认样式的存在会影响到页面的布局,通常情况下编写网页时必须要去除浏览器的默认样式(PC端的页面)

在当今网页设计/开发实践中,使用CSS来为语义化的(X)HTML标记添加样式风格是重要的关键。

在设计师们的梦想中都存在着这样的一个完美世界:所有的浏览器都能够理解和适用多有CSS规则,并且呈现相同的视觉效果(没有兼容性问题)。

但是,我们并没有生活在这个完美的世界,现实中发生的失窃却总是恰恰相反,很多CSS样式在不同的浏览器中有着不同的解释和呈现。

当今流行的浏览器(如:Firefox、Opera、Internet Explorer、Chrome、Safari等等)中,有一些都是以自己的方式去理解CSS规范,这就会导致有的浏览器对CSS的解释与设计师的CSS定义初衷相冲突,使得网页的样子在某些浏览器下能正确按照设计师的想法显示

而且有些浏览器却并没有按照设计师想要的样子显示出来,这就导致浏览器的兼容性问题。

更糟的是,有的浏览器完全无视CSS的一些声明和属性。[5]

我们可以尝试编写css样式,以去除浏览器的默认样式

F12看盒子默认样式

段落之间有16px的默认行距

列表外有16px的上下外边距和40px的左内边距,而且每项列表前有一个小黑点

去除默认样式

  1. 去除与浏览器的边缘间距
1
2
3
body {
margin: 0;
}

去除段落之间行距

1
2
3
p {
margin: 0;
}

我们只是去除了列表的内外边距,但是发现前面的黑点也消失了,真的如此吗?

我们先给ul加上一个margin-left

看来黑点并没有自动清除,而只是“缩进”了浏览器的左侧

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

去除列表前的黑点

再将之前加的16px的margin-left样式去除

到这里似乎就大功告成了,但是我们会发现写法似乎 很完美 有点麻烦
有没有简化空间了呢?
答案是肯定的,我们前面介绍过通配选择器的概念,可以直接简化成一个

1
2
3
4
5
* {
margin: 0;
padding: 0;
list-style: none;
}

reset样式

官方地址:reset.css

1
<link rel="stylesheet" href="assets/reset.css">

我们可以看到reset.css的作用就是将各个内外边距置为0,将一些样式置为none

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/* http://meyerweb.com/eric/tools/css/reset/ 
v2.0 | 20110126
License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}

normalize样式

官方地址:normalize.css

1
<link rel="stylesheet" href="assets/normalize.css">

这里并没有去除所有样式,因为normalize的作用不同于reset。reset是将所有默认样式去除,而normalize是将所有默认样式统一,这样在不同的浏览器里显示效果也是统一的

至于文件内容就不再这里赘述了,感兴趣的可以仔细研究

参考资料

  1. CSS盒子模型:https://baike.baidu.com/item/CSS盒子模型/9814562?fr=aladdin ↩︎

  2. 谷歌、火狐浏览器 缩放为80% 时,margin值才正确:https://www.cnblogs.com/taohuaya/p/7642742.html ↩︎

  3. 内边距的设置会影响到盒子的大小,背景颜色会延伸到内边距上 ↩︎

  4. margin (子元素远离父元素边框):https://www.cnblogs.com/FlFtFw/p/9627026.html ↩︎

  5. 目前比较全的CSS重设(reset)方法总结:https://www.cnblogs.com/hnyei/archive/2011/10/04/2198779.html ↩︎ ↩︎

浮动

浮动的简介

通过浮动可以使一个元素向其父元素的左侧或右侧移动

使用float属性来设置于元素的浮动

  • none 默认值,元素不浮动

  • left 元素向左浮动

  • right 元素向右浮动

注意

  • 元素设置浮动以后,水平布局的等式便不需要强制成立

  • 元素设置浮动以后,会完全从文档流中脱离,不再占用文档流的位置,所以元素下边的还在文档流中的元素会自动向上移动

浮动的特点

  1. 浮动元素会完全脱离文档流,不再占据文档流中的位置

  2. 设置浮动以后,元素会向父元素的左侧或右侧移动

  3. 浮动元素默认不会从父元素中移出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<style>
.box1 {
width: 100px;
height: 100px;
background-color: orange;
float: left;
}

.box2 {
width: 200px;
height: 200px;
background-color: red;
}
</style>

<div class="box1"></div>
<div class="box2"></div>

浮动元素向左或向右移动时,不会超过前边的浮动元素(先来后到的顺序)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<style>
.box1 {
width: 200px;
height: 200px;
background-color: orange;
float: left;
}

.box2 {
width: 200px;
height: 200px;
background-color: red;
float: left;
}

.box3 {
width: 200px;
height: 200px;
background-color: yellow;
float: left;
}
</style>

<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>

浮动元素不会超过上边的浮动的兄弟元素,最多就是和它一样高

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<style>
.box1 {
width: 300px;
height: 300px;
background-color: orange;
float: left;
}

.box2 {
width: 400px;
height: 400px;
background-color: red;
float: left;
}

.box3 {
width: 300px;
height: 300px;
background-color: yellow;
float: right;
}
</style>

<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>

如果浮动元素的上边是一个没有浮动的块元素,则浮动元素无法上移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<style>
.box1 {
width: 200px;
height: 200px;
background-color: orange;
}

.box2 {
width: 200px;
height: 200px;
background-color: red;
float: left;
}
</style>

<div class="box1"></div>
<div class="box2"></div>

浮动元素不会盖住文字,文字会自动环绕在浮动元素的周围,所以我们可以利用浮动来设置文字环绕图片的效果

简单总结:

  • 浮动目前来讲它的主要作用就是让页面中的元素可以水平排列,通过浮动可以制作一些水平方向的布局

  • 元素设置浮动以后,将会从文档流中脱离,从文档流中脱离后,元素的一些特点也会发生变化

脱离文档流的特点

块元素:

  • 块元素不再独占页面的一行

  • 脱离文档流以后,块元素的宽度和高度默认都被内容撑开

1
2
3
4
5
6
7
8
<style>
.box1 {
background-color: orange;
/* float: left; */
}
</style>

<div class="box1">hello</div>

行内元素:

  • 行内元素脱离文档流以后会,特点和块元素一样
1
2
3
4
5
6
7
8
9
10
<style>
span {
width: 200px;
height: 200px;
background-color: orange;
float: left;
}
</style>

<span>I am a Span</span>

脱离文档流之后的特点很像行内块元素,不过存在一些差异

1
2
3
4
5
6
7
8
9
10
11
12
<style>
span {
width: 200px;
height: 200px;
background-color: orange;
/* display: inline-block; */
float: left;
}
</style>

<span>I am a Span</span>
<span>I am a Span</span>

简单布局

整体样式

目的

  1. 熟悉布局(块元素、浮动)

  2. 公共css部分复用

  3. 复习语义标签

html代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!-- 页眉 -->
<header></header>
<!-- 主体 -->
<main>
<!-- 左边栏 -->
<nav></nav>
<!-- 中心 -->
<article>
<!-- 内容上 -->
<div class="top"></div>
<!-- 内容下 -->
<div class="bottom">
<!-- 内容左 -->
<div class="left"></div>
<!-- 内容中 -->
<div class="middle"></div>
<!-- 内容右 -->
<div class="right"></div>
</div>
</article>
<!-- 右边栏 -->
<aside></aside>
</main>
<!-- 页脚 -->
<footer></footer>

css代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/* 公共部分 */
header,
main,
footer {
width: 1000px;
margin: 10px auto;
}

main nav,
main article,
main aside {
float: left;
/* 虽然设置浮动了,但整体大小是被内容撑开的,所以设置一个高度 */
height: 100%;
}

.bottom .left,
.bottom .middle,
.bottom .right {
float: left;
width: 220px;
height: 100%;
}

/* ==========整体布局-上========== */
header {
height: 100px;
background-color: silver;
}

/* ==========整体布局-中========== */
main {
height: 400px;
background-color: #bfa;
}


/* ------左边栏------ */
main nav {
width: 150px;
background-color: red;
}

/* ------中心------ */
main article {
width: 680px;
background-color: green;
margin: 0 10px;
}

/* ---上--- */
article .top {
height: 190px;
background-color: yellow;
margin-bottom: 10px;
}

/* ---下--- */
article .bottom {
height: 200px;
background-color: orange;
}


/* 左 */
.bottom .left {
background-color: lightblue;
}

/* 中 */
.bottom .middle {
background-color: gray;
margin: 0 10px;
}

/* 右 */
.bottom .right {
background-color: wheat;
}

/* ------右边栏------ */
main aside {
width: 150px;
background-color: blue;
}

/* ==========整体布局-下========== */
footer {
height: 100px;
background-color: tomato;
}

效果

练习:w3school导航条

去除默认样式,引入reset.css

1
<link rel="stylesheet" href="css/reset.css">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/* 去除默认样式 */
a {
text-decoration: none;
}

/* ul整体布局 */
.menu {
width: 1211px;
height: 48px;
background-color: #E8E7E3;
margin: 100px auto;
}

/* li整体布局 */
.nav {
/* 浮动li元素 */
float: left;
width: 173px;
line-height: 48px;
}

.nav a {
/* 注意点:升级为块元素,使之继承父类宽高
否则鼠标悬浮在li元素上时,鼠标“箭头”不会进入a元素变成“小手” */
display: block;
/* 内容水平居中 */
text-align: center;
/* 字体样式 */
font-size: 14px;
color: #777777;
font-family: Verdana, Arial, '微软雅黑', '宋体';
}

/* 超链接悬浮效果 */
.nav a:hover {
background-color: #3F3F3F;
color: #E8E7E3;
}

html代码

1
2
3
4
5
6
7
8
9
<ul class="menu">
<li class="nav"><a href="#">HTML/CSS</a></li>
<li class="nav"><a href="#">Browser Side</a></li>
<li class="nav"><a href="#">Server Side</a></li>
<li class="nav"><a href="#">Programming</a></li>
<li class="nav"><a href="#">XML</a></li>
<li class="nav"><a href="#">Web Building</a></li>
<li class="nav"><a href="#">Reference</a></li>
</ul>

效果

高度塌陷与BFC

高度塌陷与BFC

在浮动布局中,父元素的高度默认是被子元素撑开的

当子元素浮动后,其会完全脱离文档流,子元素从文档流中脱离将会无法撑起父元素的高度,导致父元素的高度丢失

父元素高度丢失以后,其下的元素会自动上移,导致页面的布局混乱

所以高度塌陷是浮动布局中比较常见的一个问题,这个问题我们必须要进行处理!

BFC

BFC(Block Formatting Context)块级格式化环境

  • BFC是一个CSS中的一个隐含的属性,可以为一个元素开启BFC

  • 开启BFC该元素会变成一个独立的布局区域

元素开启BFC后的特点:

  • 不会被浮动元素覆盖

  • 父子元素外边距不会重叠

  • 可以包含浮动的元素

可以通过一些特殊方式来开启元素的BFC:

  • 设置为浮动(不推荐):很明显下方元素被覆盖了,总不能让所有元素都浮动吧

设置为行内块元素(不推荐):不再独占一行,宽度变了,同时与下方元素产生了一点空隙

设置overflow为非visible值:既没有覆盖元素,也保持了独占一方的特性(保持了宽度),与下方元素也保持了最初的间隙
常用的方式为元素设置overflow:hiddenoverflow:auto也是ok的) 开启其BFC, 以使其可以包含浮动元素
overflow:scroll 会有滚动条,可能并不需要的,所以不太推荐

不过,这种方式也存在一定问题,如下,overflow并没有完全清除div2布局上受到的影响

总结

  • 可以通过变成浮动元素,来防止自身被浮动元素覆盖(有点“以毒攻毒”那味了)

  • 可以设置行内块,来防止自身及其他元素被浮动元素覆盖(如果说浮动是“独善其身”,那行内块就有点“兼济天下”的意思)

  • 可以设置overflow属性,包含浮动元素(既“独善其身”,又“兼济天下”,但仍有缺陷)

我们可以打开Zeal手册(《02-前端开发准备》有介绍),查看关于BFC的说明文档

打开Block formatting context模块后,可以看到有很多开启BFC的方式

我这里大概翻译了一下,并整理了一份表格,应该看起来更直观一点(有些概念因为还没有学习,翻译和理解有误的地方还望谅解)

元素或属性 说明
`` 文档根元素
float: leftfloat: right 浮动元素(float不为none)
position: absolutposition: fixed 绝对定位元素
``display: inline-block 行内块元素
``display: table-cell 表格单元,默认值
``display: table-caption 表格标题,默认值
display: tabledisplay: table-row display: table-row-groupdisplay: table-header-group display: table-footer-groupdisplay: inline-table 匿名的表格单元,分别是HTML表格、表行、表体、表头和表脚的默认值
overflow: hiddenoverflow: scroll ``overflow: auto overflow不为visible和``clip的块元素
``display: flow-root
contain: layoutcontain: content ``contain: paint
display: flexdisplay: inline-flex的直接子元素 Flex项,如果它们本身既不是flex,也不是grid或``table容器
display: griddisplay: inline-grid的直接子元素 Grid项,如果它们本身既不是flex,也不是grid或``table容器
column-count不为auto column-width不为auto Multicol容器,包含``column-count: 1
``column-span: all 应该总是创建一个新的格式化上下文,即使``column-span: all元素不在multicol容器中

但是,注意不管哪种方式,多多少少都会有些隐患、缺陷或者说“副作用”

clear

我们这里设计三个兄弟元素,对前两个元素进行float的浮动属性设置,看下效果

由于box1的浮动,导致box3位置上移也就是box3受到了box1浮动的影响,位置发生了改变(注意,这里文字并没有被覆盖,《09-浮动》一节说过浮动的特点,其中第7点就是“文字环绕”的问题)

如果我们不希望某个元素因为其他元素浮动的影响而改变位置,可以通过clear属性来清除浮动元素对当前元素所产生的影响

clear作用:清除浮动元素对当前元素所产生的影响(本质是为元素添加一个margin-top属性,值由浏览器自动计算)

可选值:

  • left 清除左侧浮动元素对当前元素的影响

  • right 清除右侧浮动元素对当前元素的影响

  • both 清除两侧中影响较大一侧元素的影响(注意,这里不是同时清除两侧的影响)

after

我们学习上面知识后,了解了高度塌陷问题的解决方式,其中主要有

  • 通过overflow: hidden等可以为元素开启BFC

通过clear: both等可以清除浮动对元素产生的影响

同时也了解到,这两种方式都有一定的弊端和隐患。那有没有一种更好的方式去解决高度塌陷的问题呢?

答案当然是:有!

Q1:这里使用了一个伪元素选择器**::after**,那有人会问了,跟在box2下直接定义一个box3有什么区别呢?

A:我们知道,网页的结构思想是:结构+表现+行为。在box2下直接定义一个box3,属于结构;而使用伪元素选择器,属于表现

而高度塌陷问题属于表现问题,定义box3的目的是为了撑起box1的内容,属于表现,而不是结构,所以在css中定义::after更符合网页的编程思想

Q2:为什么需要使用**display: block**呢?

A:因为默认情况下,::after伪元素是一个行内元素,如果不转为块元素,将仍然撑不起box1的高度

clearfix

我们在前面《盒模型》一节中说过垂直布局中边距重叠的问题:相邻的垂直方向外边距会发生重叠现象

如上图所示,子元素设置了一个margin-top之后,父元素跟随子元素一起进行了移动

即我们之前说的父子元素间相邻外边距,子元素会传递给父元素(上外边距)

聪明的小伙伴已经想到了,用刚才说的伪元素选择器啊

好,我们先来看下效果

貌似是没有任何变化,到底是什么地方不对呢?

我们再来回顾下使用after伪元素的心路历程:

  • 使用无内容的box3撑起box1 ==》表现代替结构(::after代替box3)

  • clear清除浮动对元素产生的影响(还记得clear的原理么?)

其实就是给元素设置了一个margin-top属性,不过这个在开发者工具中是看不到的

既然如此,就相当于在box2下面添加一个box3,然后给box3设置一个margin-top属性

到此为止,

∵ 相邻的垂直方向外边距 这个条件仍然满足

∴ 会发生重叠现象这个结论也依然成立

具体点就是,父子元素间相邻外边距,子元素会传递给父元素(上外边距),表现为box1和box2同步往下移动

那我们应该怎么做才能解决这个问题? 凭你们朴素的情感,应该怎么判? 当然就是让上述条件不满足呗!

怎么能够不满足?当然是让两个元素垂直外边距不相邻啊!

好,多说无益,我们直接上代码看效果!

我们用了before伪元素选择器,目的当然是让box1和box2的外边距不相邻,但是好像并没有效果

我们再换成display: inline-block属性看看

好像是解决了父元素布局的问题,但是子元素怎么还往下跑了一段距离? 是谁给的勇气?

因为inline-block兼顾行内元素和块元素的特点,既可以设置宽高也不独占一行

在没有设置宽高时,会存在一个默认高度,所以inline-block仍然行不通

还有一个属性,display: table

Bingo!实现了我们最终想要的效果

Q1:为什么没有使用clear属性?

A:不是说了吗?clear是为了清除浮动对布局的影响,我们现在没有浮动的元素啊,我们要讨论的也不是浮动的问题

Q2:display不是还有一个**none**属性么,为什么不用呢?

A:none属性是不占据位置,但是也不能让元素相邻的外边距分离啊

Q3:为什么**table**值就可以呢?

A:这个问题问的非常好,算是问到点上了!我们上面在讲开启BFC的一些方法的时候,也提到了该属性。而且,应该牢记的是,元素开启BFC后的其中一个特点就是 父子元素外边距不会重叠。当然,这里也需要合理选择伪元素选择器,使其外边距不相邻才行

另外,总结一下:

  • 高度塌陷问题,一般用::after

  • 外边距重叠问题,一般用::before

不知道到这里,大家能不能想明白这两件事情

那么问题来了,有没有一个两全其美的办法,既可以解决高度塌陷,又可以解决外边距重叠呢?

当然有!clearfix 这个样式就可以同时解决高度塌陷和外边距重叠的问题

当你在遇到这些问题时,直接使用clearfix这个类即可,他就可以帮你轻松搞定css中的两大难题

1
2
3
4
5
6
.clearfix::before,
.clearfix::after{
content: '';
display: table;
clear: both;
}

其中.clearfix::before是为了解决外边距重叠问题

1
2
3
4
.clearfix::before{
content: '';
display: table;
}

.clearfix::after是为了解决高度塌陷问题

1
2
3
4
5
.clearfix::after{
content: '';
display: table;
clear: both;
}

两者合在一起,就可以完美地解决高度塌陷和外边距重叠这两大“世纪难题”了

定位

定位是一种更加高级的布局手段

通过定位可以将元素摆放到页面的任意位置

使用position属性来设置定位

可选值 含义
static 不开启定位,元素是静止的,默认值
relative 开启元素的相对定位
absolute 开启元素的绝对定位
fixed 开启元素的固定定位
sticky 开启元素的粘滞定位

相对定位

当元素的position属性值设置为relative时,则开启了元素的相对定位

偏移量(offset)

当元素开启相对定位以后,可以通过偏移量来设置元素的位置

offset属性 含义
top 定位元素和定位位置的上边距离
bottom 定位元素和定位位置的下边距离
left 定位元素和定位位置的左侧距离
right 定位元素和定位位置的右侧距离

定位元素垂直方向的位置由topbottom两个属性控制,通常情况下只会使用其中之一

  • top值越大,定位元素越靠下

  • bottom值越大,定位元素靠上

定位元素水平方向的位置由leftright两个属性控制,通常情况下只会使用其中之一

  • left越大,定位元素越靠右

  • right越大,定位元素越靠左

ok,介绍完相对布局,我们的需求是不是变得so easy!

1
2
3
4
5
6
7
8
9
.box2 {
width: 200px;
height: 200px;
background-color: yellow;
/* 开启相对定位 */
position: relative;
top: -200px;
left: 200px;
}

可以看出,使用了相对定位后,只会移动自身的布局位置,而不会对已存在的其他元素产生任何影响

现在我们所举的例子不是很明显,但当页面布局比较复杂,特别是页面元素很多的时候,其优越性就可以大大体现出来

相对定位的特点

  1. 当元素开启相对定位以后,如果不设置偏移量元素,则元素不会发生任何变化(这里注意,不仅仅是位置)
  2. 相对定位是参照于元素在文档流中的位置进行定位的(可以理解为相对于自身原始位置)
  3. 相对定位会提升元素的层级(表现为可以覆盖其他元素)
  4. 相对定位不会改变元素的性质:块还是块,行内还是行内

Q1:如果给上述三个div都设置相对定位,那么它们的层级关系会是什么样的呢?或者说谁会被谁覆盖呢?

A:百闻不如一见,光说不练假把式,我们直接进行测试验证

可以看到覆盖关系是:box3 >> box2 >> box1

我们再稍微调整下box3和box2的前后位置

会发现覆盖关系变成了:box2 >> box3 >> box1

可以大概猜测:在页面文档流中,越靠下的元素开启相对定位后,其层级越高 (这里也只是我个人的揣测,待后续学习中验证)(在后续学习中已得到验证:没有设置层级或层级z-index设置相同值时,优先显示靠下的元素)

Q2:相对定位的第三个特点相对定位会提升元素的层级,是不是就类似于浮动一样脱离了文档流?

A:我们可以对比下,浮动和相对定位的区别

  • 参考系不同:浮动的参考系是其父元素;相对定位是相对于自身

  • 可移动方向不同:浮动只能左右移动;相对定位是上下左右移动

  • 影响不同:浮动会影响页面布局(包括下方元素位置影响和高度塌陷问题);相对定位不对影响页面布局

  • 性质不同:浮动会改变元素的性质(不再独占一行,其宽高都会被内容撑开);相对定位不会改变元素的性质

  • 文字环绕:浮动不会覆盖文字;相对定位可以覆盖文字(这个可以自行验证,不再赘述)

当然,浮动和相对定位也有其相似之处

  • 浮动和相对定位都是移动位置(貌似是废话)

  • 浮动和相对定位不会从父元素中移出

可以看出,浮动和相对定位的区别是更多的

最后回答一点:浮动脱离了文档流,不再占据页面位置;相对定位仍然占据页面位置(所以怎么能够叫 脱离文档流 呢?)

Q3:相对定位的第四个特点相对定位不会改变元素的性质:块还是块,行内还是行内,但是上述例子中元素开启相对定位后好像就不再独占一行了,这个怎么理解?

A:相比于浮动元素的特点,相对定位不会改变元素的性质其实是一个相对不容易理解的问题。但其实也不难,可以把相对定位认为是元素的灵魂出窍。其位置发生改变以后,布局并没有产生影响,因为它的肉体(结构)仍然占据着原来的那个位置。只是其灵魂(内容)发生了移动。

Q4:相对定位的第四个特点中块还是块,行内还是行内,意味着行内元素也可以使用相对定位是吗?

A:眼见为实,耳听为虚,直接看示例效果

善于思考是好事,但也别忘了自动动手,丰衣足食。自己实操一遍,胜过千言万语

绝对定位

当元素的position属性值设置为absolute时,则开启了元素的绝对定位

  1. 开启绝对定位后,如果不设置偏移量,元素的位置不会发生变化
  2. 开启绝对定位后,元素会从文档流中脱离
  3. 绝对定位会改变元素的性质:行内变成块,块的宽高被内容撑开(与相对定位相反)
  4. 绝对定位会使元素提升一个层级
  5. 绝对定位元素是相对于其包含块进行定位的(与相对定位不同)

包含块

正常情况下:

  • 包含块就是离当前元素最近的开启了定位的祖先块元素

  • 如果所有的祖先元素都没有开启定位,则html(根元素、初始包含块)就是它的包含块

1
2
3
4
5
6
7
8
9
10
11
12
13
<body>
<!-- 如果box1开启定位,则box2的包含块是box1,否则就是body -->
<div class="box1">
<div class="box2"></div>
</div>

<!-- 如果box3开启定位,则em的包含块是box3,否则就是body -->
<div class="box3">
<span>
<em>hello</em>
</span>
</div>
</body>

示例

1
2
3
4
5
<div class="box2">2
<div class="box3">3
<div class="box4">4</div>
</div>
</div>

  • 不给box2、box3开起定位,box4的包含块是html

  • 只给box3开启定位之后,box4的包含块是box3

  • 只给box2开启定位之后,box4的包含块是box2

  • 给box2、box3都开起定位之后,box4的包含块是box3

注意:这里上述的条件是开启定位,也就是说只要position不是static(默认值),那么就满足了其成为包含块的必要条件

上述示例中,我们给其祖先元素都设置了相对定位。其实改成其他几种定位方式也是可行的,我们可以看下面示例

这里就不一一举例了,大家可以对另外几种定位方式进行验证

水平方向的布局

我们之前说过,水平方向的布局等式:

1
margin-left + border-left + padding-left + width + padding-right + border-right + margin-right = 其父元素的宽度

当使用绝对定位时,需要添加leftright两个值(此时规则和之前一样,只是多添加了两个值)

1
left + margin-left + border-left + padding-left + width + padding-right + border-right + margin-right + right = 其父元素的宽度

当发生过度约束时

  • 如果9个值中没有auto,则自动调整right值以使等式满足(之前7个值是margin-right

  • 如果9个值中有auto,则自动调整auto的值以使等式满足

可设置auto的值:margin-left/margin-right /width/left/right

因为leftright的值默认是auto,所以如果没有设置leftright,当等式不满足时,则会自动调整这两个值

水平居中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<style>
.box1 {
width: 500px;
height: 500px;
background-color: #bfa;
position: relative;
}

.box2 {
width: 100px;
height: 100px;
background-color: orange;
/* 左右外边距设置为auto */
margin-left: auto;
margin-right: auto;
/* 绝对定位 */
position: absolute;
left: 0;
right: 0;
}
</style>

<div class="box1">
<div class="box2"></div>
</div>

垂直方向的布局

垂直方向布局的等式的也必须要满足

1
top + margin-top + border-top + padding-top + height + padding-bottom + border-bottom + margin-bottom + top = 其父元素的高度
1
2
3
4
5
6
7
8
9
10
11
12
.box2 {
width: 100px;
height: 100px;
background-color: orange;
/* 左右外边距设置为auto */
margin-top: auto;
margin-bottom: auto;
/* 绝对定位 */
position: absolute;
top: 0;
bottom: 0;
}

水平垂直居中

目前,我们可以根据绝对定位进行元素的水平垂直双方向居中,所以这个方法只是其中之一

1
2
3
4
5
6
7
8
9
10
11
12
13
.box2 {
width: 100px;
height: 100px;
background-color: orange;
/* 左右外边距设置为auto */
margin: auto;
/* 绝对定位 */
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}

小结

  • 水平布局等式:left + margin-left + border-left + padding-left + width + padding-right + border-right + margin-right + right = 其父元素的宽度

  • 垂直布局等式:top + margin-top + border-top + padding-top + height + padding-bottom + border-bottom + margin-bottom + top = 其父元素的高度

  • 上述等式的过度约束规则与《06-盒模型》中介绍的规则基本一致

  • 只是在没有auto时,会自动调整top/bottom/left/right

固定定位

固定定位也是一种绝对定位,所以固定定位的大部分特点都和绝对定位一样

唯一不同的是,固定定位永远参照于浏览器的视口(viewport,可视窗口)进行定位,不会随网页的滚动条滚动

示例

我们再给body设置一个较大的高度,让浏览器滚动起来,看下效果

会发现,box4并没有因为滚动而发生未知的变化,这也验证了上述知识,同时也应该明白了视口的概念

我们再对比下绝对定位

相信到这里,大家应该又进一步地理解了固定定位与绝对定位的区别

因为固定定位跟绝对定位除了具有上述差别之后,其他的特点跟绝对定位是一样的,所以这里便不再赘述了

粘滞定位

将元素的position属性设置为sticky,则开启了元素的固定定位

这次,我们换个方式,直接来看粘滞定位的效果

不要慌,这里大概翻译一下(我这里稍微进行了下省略精简和整理总结)

  • 该元素是根据文档流进行定位的,即相对于包含块进行偏移

  • 偏移量不会影响任何其他元素的位置

  • 粘性元素总是“粘”到其最近的具有“滚动机制”的祖先元素(当overflowhiddenscrollautooverlay时创建),即使该祖先不是最近的实际滚动祖先

这里可能最后一点比较难理解,别着急,我们接着往下看

示例

我们拿之前的w3cschool顶部导航栏进行下魔改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* 设置一个高度 */
body {
height: 3000px;
}

.menu {
width: 1211px;
height: 48px;
background-color: #E8E7E3;
margin: 100px auto;
/* 开启粘滞定位 */
position: sticky;
top: 10px;
}

因为在视频中老师并没有对sticky属性做过多的介绍,只是要求我们了解一下,因为在实际开发中,也是结合js去实现的,所以我这里同样也就不再深入带大家一起看了

粘滞定位的特点

  • 粘滞定位和相对定位的特点基本一致(视频中说是和相对定位一致,不过我对比了一下,很多特点是不同的,感觉倒是和固定定位更相似,这里存疑)

  • 不同的是粘滞定位可以在元素到达某个位置时将其固定

需要注意的是,sticky属性并不兼容IE(PS:不过微软官方已经宣布将在2022年停止对IE的维护,IE将成为历史。虽然我们经常诟病IE,但作为当年浏览器的一霸,在废弃多年后,不知道还会不会有所怀念,毕竟它代表着我们不断逝去的青春)

几种定位的对比

我们通过上面的学习,知道position属性有五个可选值

static是默认值,即不开启定位,所以我们只需要对比4种定位方式即可

定位方式 是否不设置偏移量,元素不会发生改变 是否脱离文档流 是否改变元素性质 是否提升元素层级 参考系
relative(相对定位) × × 参照于元素在文档流中的位置
absolute(绝对定位) × 参照于其包含块
fixed(固定定位) × 参照于浏览器的视口
sticky(粘滞定位) × 参照于浏览器的视口

元素层级

对于开启了定位元素,可以通过z-index属性来指定元素的层级

  • z-index需要一个整数作为参数,值越大元素的层级越高,元素的层级越高越优先显示

  • 如果元素的层级一样,则优先显示靠下的元素

  • 祖先的元素的层级再高,也不会盖住后代元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<style>
div {
font-size: 40px;
}

.box1 {
width: 200px;
height: 200px;
background-color: #bfa;
position: absolute;
top: 0;
left: 0;
}

.box2 {
width: 200px;
height: 200px;
background-color: orange;
position: absolute;
top: 50px;
left: 50px;
}

.box3 {
width: 200px;
height: 200px;
background-color: salmon;
position: absolute;
top: 100px;
left: 100px;
}

.box4 {
width: 100px;
height: 100px;
background-color: skyblue;
position: absolute;
bottom: 0;
left: 0;
}
</style>

<div class="box1">1</div>
<div class="box2">2</div>
<div class="box3">3
<div class="box4">4</div>
</div>

存疑问题

Q:浮动也有层级概念吗?如果有,浮动和定位的层级关系是什么样的?

A:null / none / undefined 调了一下,出现几种现象

  • float设置z-index多大都没用,还是会被覆盖

  • 默认情况,没有设置z-index或设置z-index大小≥0时,浮动层级没有定位的层级高

  • 设置z-index<0时,浮动层级可以定位的层级高

浮动层级(不知道有没有这个概念,本身就是存疑问题,现在这种情况看起来应该是没有这个概念了)

字体背景

字体样式

我们前面讲过字体的两个属性

  • color用来设置字体颜色

  • font-size字体的大小

    • em 相当于当前元素的一个font-size
    • rem 相对于根元素的一个font-size

当然,字体的属性并不止这些

font-family 字体族(字体的格式)

sans-serif 非衬线字体

monospace 等宽字体

cursive 手写体

fantasy 梦幻字体

上述字体均不表示具体的某种字体,而是字体的分类

我们经常使用的一些字体,如微软雅黑黑体楷体宋体Consolas等,才是具体的某种字体

也就是说, 指定字体的类别,浏览器会自动使用该类别下的字体 font-family

font-family可以同时指定多个字体,多个字体间使用隔开

字体生效时优先使用第一个,第一个无法使用则使用第二个,以此类推

1
font-family: 'Courier New', Courier, monospace

@font-face

我们除了可以使用系统自带的字体样式外,还可以在服务器端自定义字体位置

@font-face可以将服务器中的字体直接提供给用户去使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@font-face {
/* 指定字体名字 */
font-family: 'myFont1';
/* 服务器中字体路径 */
src: url('/font/ZCOOLKuaiLe-Regular.woff'),
url('/font/ZCOOLKuaiLe-Regular.otf'),
url('/font/ZCOOLKuaiLe-Regular.ttf') format('truetype');/* 指定字体格式,一般不写 */
}

p {
font-size: 30px;
color: salmon;
font-family: myFont1;
}

问题

  1. 加载速度:受网络速度影响,可能会出现字体闪烁一下变成最终的字体

  2. 版权:有些字体是商用收费的,需要注意

  3. 字体格式:字体格式也有很多种(woff、otf、ttf),未必兼容,可能需要指定多个

图标字体(iconfont)

fontawesome

官方网站:https://fontawesome.com/

下载解压完毕之后,直接将css和webfonts移动到项目中即可使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<link rel="stylesheet" href="/font/fontawesome/css/all.css">
<style>
i {
color: green;
}
.fa-venus-mars,
.fa-mars-double {
color: red;
}
.fa-html5 {
color: #E34D22;
}
.fa-css3 {
color: blue;
}
.fa-js {
color: #D1B514;
}
</style>
<!-- 大小 -->
<i class="fab fa-weixin fa-lg"></i>
<i class="fab fa-weixin fa-2x"></i>
<i class="fab fa-weixin fa-3x"></i>
<br>
<!-- 边框 -->
<i class="fab fa-weixin fa-2x fa-border"></i>
<br>
<!-- 旋转 -->
<i class="fab fa-weixin fa-2x fa-rotate-90 "></i>
<!-- 水平对称 -->
<i class="fab fa-weixin fa-2x fa-flip-horizontal "></i>
<!-- 垂直对称 -->
<i class="fab fa-weixin fa-2x fa-flip-vertical "></i>
<br>
<!-- 动画 -->
<i class="fa fa-venus-mars fa-3x fa-spin"></i>
<i class="fa fa-mars-double fa-3x fa-pulse"></i>
<br>
<!-- 列表 -->
<ul class="fa-ul">
<li><i class="fa-li fa fa-check-square"></i>can be used</li>
<li><i class="fa-li fa fa-spinner fa-spin"></i>as bullets</li>
<li><i class="fa-li fa fa-square"></i>in lists</li>
</ul>
<br><br><br>
<!-- 组合 -->
<span class="fa-stack fa-lg">
<i class="fab fa-html5 fa-stack-1x fa-10x"></i>
<i class="fab fa-css3 fa-stack-1x fa-4x"></i>
<i class="fab fa-js fa-stack-1x fa-2x"></i>
</span>

背景

  • background-color 设置背景颜色

  • background-image 设置背景图片

    • 如果背景图片大小小于元素,则背景图片会自动在元素中平铺将元素铺满
    • 如果背景图片大小大于元素,则背景图片一部分会无法完全显示
    • 如果背景图片大小等于元素,则背景图片会直接正常显示
  • background-repeat 设置背景图片的重复方式

    • repeat 默认值,背景图片沿着x轴和y轴双方向重复
    • repeat-x 背景图片沿着x轴方向重复
    • repeat-y 背景图片沿着y轴方向重复
    • no-repeat 背景图片不重复
  • background-position 设置背景图片的位置

    • 通过top left right bottom center几个表示方位的词来设置背景图片的位置:使用方位词时必须要同时指定两个值,如果只写一个则第二个默认就是center
    • 通过偏移量来指定背景图片的位置:水平方向偏移量、垂直方向变量
  • background-clip 设置背景的范围

    • border-box 默认值,背景会出现在边框的下边
    • padding-box 背景不会出现在边框,只出现在内容区和内边距
    • content-box 背景只会出现在内容区
  • background-origin 背景图片的偏移量计算的原点

    • border-box 背景图片的变量从边框处开始计算
    • padding-box 默认值,background-position从内边距处开始计算
    • content-box 背景图片的偏移量从内容区处计算
  • background-size 设置背景图片的大小

    • 第一个值表示宽度,第二个值表示高度;如果只写一个,则第二个值默认是auto
    • cover 图片的比例不变,将元素铺满
    • contain 图片比例不变,将图片在元素中完整显示
  • background-attachment 背景图片是否跟随元素移动

    • scroll 默认值,背景图片会跟随元素移动
    • fixed 背景会固定在页面中,不会随元素移动

可以同时设置背景图片和背景颜色,这样背景颜色将会成为图片的背景色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
.box1 {
height: 500px;
width: 500px;
overflow: auto;
border: 20px red double;
padding: 10px;
/* 背景色 */
background-color: darksalmon;
/* 背景图 */
background-image: url('/assets/背景.png');
/* 背景图重复方式 */
background-repeat: no-repeat;
/* 背景图偏移位置 */
background-position: 0 0;
/* 背景图偏移量计算的原点 */
background-origin: content-box;
/* 背景范围 */
background-clip: content-box;
/* 背景图片大小 */
background-size: contain;
}

.box2 {
width: 100px;
height: 1000px;
background-color: orange;
background-image: url("assets/背景2.jpg");
background-repeat: no-repeat;
background-position: 50px 50px;
/* 背景图片是否跟随移动 */
background-attachment: fixed;
}

backgound 背景相关的简写属性,所有背景相关的样式都可以通过该样式来设置并且该样式没有顺序要求,也没有哪个属性是必须写的

注意

  • background-size必须写在background-position的后边,并且使用/隔开background-position/background-size

  • background-origin background-clip 两个样式,orgin要在clip的前边

雪碧图与渐变

雪碧图

解决图片闪烁的问题:

可以将多个小图片统一保存到一个大图片中,然后通过调整background-position来显示响应的图片

这样图片会同时加载到网页中就可以有效的避免出现闪烁的问题

这个技术在网页中应用十分广泛,被称为CSS-Sprite,这种图我们称为雪碧图

雪碧图的使用步骤:

  1. 先确定要使用的图标
  2. 测量图标的大小
  3. 根据测量结果创建一个元素
  4. 将雪碧图设置为元素的背景图片
  5. 设置一个偏移量以显示正确的图片

雪碧图的特点:

  • 一次性将多个图片加载进页面,降低请求的次数,加快访问速度,提升用户的体验

示例1

解决图片闪烁的问题:

可以将多个小图片统一保存到一个大图片中,然后通过调整background-position来显示响应的图片

这样图片会同时加载到网页中就可以有效的避免出现闪烁的问题

这个技术在网页中应用十分广泛,被称为CSS-Sprite,这种图我们称为雪碧图

雪碧图的使用步骤:

  1. 先确定要使用的图标
  2. 测量图标的大小
  3. 根据测量结果创建一个元素
  4. 将雪碧图设置为元素的背景图片
  5. 设置一个偏移量以显示正确的图片

雪碧图的特点:

  • 一次性将多个图片加载进页面,降低请求的次数,加快访问速度,提升用户的体验

示例1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
a:link {
display: block;
width: 93px;
height: 29px;
background: url("assets/背景/练习2-背景/btn.png");
/* 默认值,可以不设置 */
background-position: 0 0;
}

a:hover {
/* 设置水平方向的一个偏移量;注意是向左移动,所以是负值 */
background-position: -93px 0;
}

a:active {
/* 设置水平方向的一个偏移量;注意是向左移动,所以是负值 */
background-position: calc(-93px*2) 0;
}

示例2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.box1 {
width: 109px;
height: 33px;
background: url("assets/背景/练习3-雪碧图/amazon-sprite_.png");
/* 设置水平和垂直方向的一个偏移量;注意移动方向 */
background-position: -10px -10px;
}

.box2 {
width: 42px;
height: 30px;
background: url("assets/背景/练习3-雪碧图/amazon-sprite_.png");
/* 设置水平和垂直方向的一个偏移量;注意移动方向 */
background-position: -58px -338px;
}

线性渐变

通过渐变可以设置一些复杂的背景颜色,可以实现从一个颜色向其他颜色过渡的效果

!!渐变是图片,需要通过background-image来设置

线性渐变,颜色沿着一条直线发生变化 linear-gradient()

1
2
# 红色在开头,黄色在结尾,中间是过渡区域
background-image: linear-gradient(red, yellow);

线性渐变的开头,我们可以指定一个渐变的方向

  • to left

  • to right

  • to bottom

  • to top

  • deg deg表示度数

  • turn 表示圈

1
2
3
4
background-image: linear-gradient(to left, red, yellow);
background-image: linear-gradient(to right, red, yellow);
background-image: linear-gradient(to top, red, yellow);
background-image: linear-gradient(to bottom, red, yellow);

上面基本的4个方向的渐变很好理解,我们就不再做过多的一一解释了

我们来看度数的渐变效果

1
background-image: linear-gradient(45deg, red, yellow);

总结:线性渐变的边上的某一点为起点,以一定角度渐变的;渐变方向的颜色是线性变化的,而其垂线方向的颜色是一致的

然后看下圈数的表示方法

1
background-image: linear-gradient(0.4turn, red, yellow);

因为圈数和角度之间可以相互转换,所以这里就不再进行赘述了

另外,渐变可以同时指定多个颜色,多个颜色默认情况下平均分布,也可以手动指定渐变的分布情况

repeating-linear-gradient() 可以平铺的线性渐变

1
background-image: repeating-linear-gradient(red, yellow);

默认情况下,跟linear-gradient(red, yellow)效果一样,我们稍作改动

1
background-image: repeating-linear-gradient(red 0px, yellow 50px);

由于我们设置的div宽高为200px,所以会有4次重复的渐变效果

所以默认情况下,下列几种写法是一致的,效果相同

1
2
3
4
background-image: linear-gradient(red, yellow);
background-image: repeating-linear-gradient(red, yellow);
/* 因为我们设置的div盒子的宽高为200px,所以这里[height]=200px */
background-image: repeating-linear-gradient(red 0, yellow [height]);

径向渐变

radial-gradient() 径向渐变(放射性的效果)

1
background-image: radial-gradient(red, yellow);

默认情况下,circleellipse是自动适配盒子的,我们也可以手动指定径向渐变的形状

形状

  • circle 圆形

  • ellipse椭圆

1
background-image: radial-gradient(circle, red, yellow);

位置

  • top

  • right

  • left

  • center

  • bottom

1
background-image: radial-gradient(at left, red, yellow);

当然,除了上述值,还可以指定像素

大小

  • closest-side 近边

  • farthest-side 远边

  • closest-corner 近角

  • farthest-corner 远角

同时对其形状/大小和位置进行指定

1
radial-gradient(形状/大小 at 位置, 颜色 位置, 颜色 位置, 颜色 位置)
1
background-image: radial-gradient(circle at 50px 100px, red 50px, yellow 100px);

表格

表格

在现实生活中,我们经常需要使用表格来表示一些格式化数据:

●课程表、人名单、成绩单…

同样在网页中我们也需要使用表格,我们通过table标签来创建一个表格

在table中使用tr表示表格中的一行,有几个tr就有几行

在tr中使用td表示一个单元格,有几个td就有几个单元格

●rowspan 纵向的合并单元格
●colspan 横向的合并单元格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<table border="1" width="50%" align=" center">
<!--在table中使用tr表示表格中的一行,有几个tr就有几行-->
<tr>
<!--在tr中使用td表示一个单元格,有几个td就有几个单元格-->
<td>A1</td>
<td>B1</td>
<td>C1</td>
<td>D1</td>
</tr>
<tr>
<td>A2</td>
<td>B2</td>
<td>C2</td>
<!--rouspan 纵向的合并单元格-->
<td rowspan="2">D2</td>
</tr>
<tr>
<td>AB</td>
<td>B3</td>
<td>C3</td>
</tr>
<tr>
<td>A4</td>
<td>B4</td>
<!-- colspan横向的合并单元格 -->
<td colspan="2">C4</td>
</tr>
</table>

长表格

可以将一个表格分成三个部分:

  • 头部 thead

  • 主体 tbody

  • 底部 tfoot

th 表示头部的单元格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<table>
<thead>
<tr>
<td>日期</td>
<td>收入</td>
<td>支出</td>
<td>合计</td>
</tr>
</thead>
<tbody>
<tr>
<td>2000.1.1</td>
<td>500</td>
<td>200</td>
<td>300</td>
</tr>
<tr>
<td>2000.1.1</td>
<td>500</td>
<td>200</td>
<td>300</td>
</tr>
<tr>
<td>2000.1.1</td>
<td>500</td>
<td>200</td>
<td>300</td>
</tr>
</tbody>
<tfoot>
<tr>
<td></td>
<td></td>
<td>合计</td>
<td>1200</td>
</tr>
</tfoot>
</table>

表格的样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<table>
<tr>
<td>学号</td>
<td>姓名</td>
<td>性别</td>
<td>年龄</td>
<td>地址</td>
</tr>
<tr>
<td>1</td>
<td>孙悟空</td>
<td></td>
<td>18</td>
<td>花果山</td>
</tr>
<tr>
<td>2</td>
<td>猪八戒</td>
<td></td>
<td>28</td>
<td>高老庄</td>
</tr>
<tr>
<td>3</td>
<td>沙和尚</td>
<td></td>
<td>38</td>
<td>流沙河</td>
</tr>
<tr>
<td>4</td>
<td>唐僧</td>
<td></td>
<td>16</td>
<td>女儿国</td>
</tr>
<tr>
<td>1</td>
<td>孙悟空</td>
<td></td>
<td>18</td>
<td>花果山</td>
</tr>
<tr>
<td>2</td>
<td>猪八戒</td>
<td></td>
<td>28</td>
<td>高老庄</td>
</tr>
<tr>
<td>3</td>
<td>沙和尚</td>
<td></td>
<td>38</td>
<td>流沙河</td>
</tr>
<tr>
<td>4</td>
<td>唐僧</td>
<td></td>
<td>16</td>
<td>女儿国</td>
</tr>
<tr>
<td>4</td>
<td>唐僧</td>
<td></td>
<td>16</td>
<td>女儿国</td>
</tr>
<tr>
<td>1</td>
<td>孙悟空</td>
<td></td>
<td>18</td>
<td>花果山</td>
</tr>
<tr>
<td>2</td>
<td>猪八戒</td>
<td></td>
<td>28</td>
<td>高老庄</td>
</tr>
<tr>
<td>3</td>
<td>沙和尚</td>
<td></td>
<td>38</td>
<td>流沙河</td>
</tr>
<tr>
<td>4</td>
<td>唐僧</td>
<td></td>
<td>16</td>
<td>女儿国</td>
</tr>
</table>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
table {
width: 50%;
margin: 0 auto;
border: 1px black solid;

/* border-spacing:指定边框之间的距离;边框之间虽然没有距离了,但是实际上是两条边框的和,看起来是变粗了 */
/* border-spacing: 0; */

/*border-collapse:collapse;设置边框的合并;真正的将两条边框合并成一条边框 */
border-collapse: collapse;

/* 默认情况下元素在td中是垂直居中的,可以通过vectical-align来修改 */
vertical-align: middle;
text-align: center;
}

/* 如果表格中没有使用tbody而是直接使用tr,那么浏览器会自动创建一个tbody,并且将tr全都放到tbody中
所以说,tr不是table的子元素 */
tbody tr:nth-child(odd) {
background-color: rgb(211, 216, 188);
}

td {
border: 1px black solid;
}

其中

  • border-spacing:指定边框之间的距离

  • border-collapse:设置边框的合并

表单

表单

  • 在现实生活中表单用于提交数据

  • 在网页中也可以使用表单,网页中的表单用于将本地的数据提交给远程的服务器

form的属性

  • action:表单要提交的服务器的地址

文本框

注意:数据要提交到服务器中,必须要为元素指定一个属性值name

1
文本框<input type="text" name="username">

密码框

1
密码框<input type="password" name="password">

提交按钮

1
<input type="submit" value="注册">

单选框

像这种选择框,必须要措定一个value属性,value属性最终会作为用户填写的值传递给服务器

1
2
3
单选框
<input type="radio" name="hello" value="a">
<input type="radio" name="hello" value="b" checked>

多选框

1
2
3
4
多选框
<input type="checkbox" name="test" value="1">
<input type="checkbox" name="test" value="2">
<input type="checkbox" name="test" value="3" checked>

下拉列表

1
2
3
4
5
6
下拉列表
<select name="haha">
<option value="i">选项一</option>
<option value="ii" selected>选项二</option>
<option value="iii">选项三</option>
</select>

按钮

上面两种写法实际上效果是一致的,区别在于:

  • input是自闭合标签,不需要</input>就能结束;button不是自闭合标签,跟一般标签一样是成对出现的

  • button因为不是自闭合标签,所以使用起来更灵活,可以嵌套其他的标签

过渡与动画

过渡

过渡(transition)

  • 通过过渡可以指定一个属性发生变化时的切换方式

  • 通过过渡可以创建一些非常好的效果,提升用户的体验

属性值

transition-property:指定要执行过渡的属性

  • 多个属性间使用,隔开;

  • 如果所有属性都需要过渡,则使用all关键字;

  • 大部分属性都支持过渡效果;

  • 注意过渡时必须是从一个有效数值向另外一个有效数值进行过渡;

transition-duration:指定过渡效果的持续时间

  • 时间单位:s和ms(1s=1000ms)

transition-delay:过渡效果的延迟,等待一段时间后在执行过渡

transition-timing-function:过渡的时序函数

  • linear匀速运动

  • ease 默认值,慢速开始,先加速后减速

  • ease-in 加速运动

  • ease-out 减速运动

  • ease-in-out 先加速后减速

  • cubic-bezier()来指定时序函数 https://cubic-bezier.com

  • steps()分步执行过渡效果,可以设置第二个值:

    • end,在时间结束时执行过渡(默认值)
    • start,在时间开始时执行过渡

transition:可以同时设置过渡相关的所有属性

  • 只有一个要求,如果要写延迟,则两个时间中第一个是持续时间,第二个是延迟时间
1
2
3
4
/* transition: margin-left 2s 1s; */
transition-property: margin-left;
transition-duration: 2s;
transition-delay: 1s;

几种过渡效果对比

linear匀速运动

1
transition-timing-function: linear;

ease 默认值,慢速开始,先加速后减速

1
transition-timing-function: ease;

ease-in 加速运动

1
transition-timing-function: ease-in;

ease-out 减速运动

1
transition-timing-function: ease-out;

ease-in-out 先加速后减速

1
transition-timing-function: ease-in-out;

cubic-bezier()来指定时序函数

1
transition-timing-function: cubic-bezier(.17, 1.79, .68, -0.69);

steps()分步执行过渡效果

1
2
/* transition-timing-function: steps(2, end); */
transition-timing-function: steps(2);

1
transition-timing-function: steps(2, start);

动画

动画和过渡类似,都是可以实现一些动态的效果,不同的是

  • 过渡需要在某个属性发生变化时才会触发

  • 动画可以自动触发动态效果

设置动画效果,必须先要设置一个关键帧,关键帧设置了动画执行每一个步骤

1
2
3
4
5
6
7
8
9
@keyframes test {
from {
margin-left: 0;
}

to {
margin-left: 900px;
}
}

animation-name 指定动画的关键帧名称

animation-duration:指定动画效果的持续时间

animation-delay:动画效果的延迟,等待一段时间后在执行动画

animation-timing-function:动画的时序函数

animation-iteration-count 动画执行的次数

  • infinite 无限执行

animation-direction 指定动画运行的方向

  • normalfromto运行,每次都是这样,默认值

  • reversetofrom运行,每次都是这样

  • alternatefromto运行,重复执行动画时反向执行

  • alternate-reversetofrom运行,重复执行动画时反向执行

animation-play-state 设置动画的执行状态

  • running 动画执行,默认值

  • paused 动画暂停

animation-fill-mode 动画的填充模式

  • none 动画执行完毕,元素回到原来位置,默认值

  • forwards 动画执行完毕,元素会停止在动画结束的位置

  • backwards 动画延时等待时,元素就会处于开始位置

  • both 结合了forwardsbackwards

1
2
3
4
5
6
7
8
9
/* animation-name: test;
animation-duration: 2s;
animation-delay: 2s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-fill-mode: both; */

animation: test 2s 2s linear infinite alternate both;

实战

1
2
3
4
5
6
7
8
9
10
11
.box {
height: 271px;
width: 132px;
background-image: url("/assets/米兔/bigtap-mitu-queue-big.png");
margin: 100px auto;
transition: background-position 1s steps(4);
}

.box:hover {
background-position: -528px 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.box {
height: 256px;
width: calc(1536px/6);
background-image: url("/assets/奔跑的少年/bg2.png");
margin: 100px auto;
animation: run 1s steps(6) infinite;

}

/* 关键帧 */
@keyframes run {
from {
background-position: 0 0;
}

to {
background-position: -1536px 0;
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
.outer {
width: 100%;
height: 700px;
border-bottom: 10px solid #000;
/* 外边距重叠,开启BFC */
overflow: hidden;
}

.ball {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: gray;
animation: bounce 6s ease-in;
}

@keyframes bounce {
from {
margin-top: 0;
}

5%,
15%,
25%,
35%,
45%,
55%,
65%,
75%,
85%,
95%,
98%,
to {
margin-top: 600px;
animation-timing-function: ease-out;
}

10%,
20%,
30%,
40%,
50%,
60%,
70%,
80%,
90% {
animation-timing-function: ease-in;
}

10% {
margin-top: 60px;
}

20% {
margin-top: 120px;
}

30% {
margin-top: 180px;
}

40% {
margin-top: 240px;
}

50% {
margin-top: 300px;
}

60% {
margin-top: 360px;
}

70% {
margin-top: 420px;
}

80% {
margin-top: 480px;
}

90% {
margin-top: 540px;
}

96% {
margin-top: 580px;
}

99% {
margin-top: 590px;
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
div {
float: left;
width: 100px;
height: 100px;
border-radius: 50%;
animation: bounce .5s infinite ease-in alternate;
}

.ball1 {
background-color: red;
animation-delay: .1s;
}

.ball2 {
background-color: yellow;
animation-delay: .2s;
}

.ball3 {
background-color: green;
animation-delay: .3s;
}

.ball4 {
background-color: blue;
animation-delay: .4s;
}

.ball5 {
background-color: pink;
animation-delay: .5s;
}

.ball6 {
background-color: orange;
animation-delay: .6s;
}

.ball7 {
background-color: fuchsia;
animation-delay: .7s;
}

.ball8 {
background-color: gray;
animation-delay: .8s;
}

.ball9 {
background-color: darkcyan;
animation-delay: .9s;
}

.ball10 {
background-color: indigo;
animation-delay: 1s;
}

.ball11 {
background-color: black;
animation-delay: 1.1s;
}

.ball12 {
background-color: darkcyan;
animation-delay: 1.2s;
}

.ball13 {
background-color: darkkhaki;
animation-delay: 1.3s;
}

.ball14 {
background-color: brown;
animation-delay: 1.4s;
}

.ball15 {
background-color: mediumpurple;
animation-delay: 1.5s;
}

@keyframes bounce {
from {
margin-top: 0;
}

to {
margin-top: 500px;
}

}

变形

变形就是指通过css来改变元素的形状或位置

变形不会影响到页面的布局

transform用来设置元素的变形效果

平移

  • translateX() 沿着由方向平移

  • translateY() 沿着y轴方向平移

  • translateZ() 沿着z轴方向平移平移元素

百分比是相对于自身计算的

几种水平垂直双方向居中的方式对比

1 绝对定位的方式

1
2
3
4
5
6
7
/* 这种居中方式,只适用于元素的大小确定 */
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;

2table-cell的方式

1
2
3
4
/* table-cell的方式具有一定局限性 */
display: table-cell;
vertical-align: middle;
text-align: center;

3 transform的方式

1
2
3
4
5
/* transform变形平移的方式 */
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);

浮出效果

1
2
3
4
5
6
7
8
9
10
11
12
13
div {
float: left;
width: 200px;
height: 300px;
background-color: silver;
margin: 100px 50px auto 50px;
transition: all .3s;
}

div:hover {
box-shadow: 0 0 10px rgba(0, 0, 0, .2);
transform: translateY(-5px);
}

Z轴平移

z轴平移,调整元素在z轴的位置,正常情况就是调整元素和人眼之间的距离,距离越大,元素离人越近

z轴平移属于立体效果(近大远小),默认情况下网页是不支持透视,如果需要看见效果必须要设置网页的视距

透视效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
html {
background-color: rgb(71, 44, 32);
perspective: 800px;
}

.box {
width: 200px;
height: 300px;
background-color: silver;
margin: 100px auto;
transition: all .3s;
}

.box:hover {
box-shadow: 0 0 10px rgba(0, 0, 0, .2);
transform: translateZ(200px);
}

旋转

通过旋转可以使元素沿着x、y或z旋转指定的角度

  • rotateX()

  • rotateY()

  • rotateZ()

1
2
/* transform: rotateY(0.5turn); */
transform: rotateY(180deg);

缩放

对元素进行缩放的函数

  • scalex() 水平方向缩放

  • scaleY() 垂直方向缩放

  • scale() 双方向的缩放

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.box {
height: 200px;
width: 200px;
background-color: #bfa;
margin: 200px auto;
transition: 2s;
}

.box:hover {
/* transform: scaleX(2); */
/* transform: scaleY(2); */
transform: scale(2);
/* 变形的原点 */
transform-origin: 0 0;
}

实战

鸭子表

1
2
3
4
5
6
7
8
9
10
11
<div class="clock">
<div class="hour-wrapper">
<div class="hour"></div>
</div>
<div class="minute-wrapper">
<div class="minute"></div>
</div>
<div class="second-wrapper">
<div class="second"></div>
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
.clock {
width: 500px;
height: 500px;
background-image: url("assets/鸭子表/clock.png");
background-image: url("assets/鸭子表/clock_duck.jpg");
background-size: cover;
margin: 100px auto;
position: relative;
}

.clock>div {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}

.clock>div>div {
height: 50%;
margin: 0 auto;
}

/* 时针 */
.hour-wrapper {
height: 60%;
width: 60%;
animation: clock-run 720s infinite;
}

.hour {
width: 8px;
background-color: black;
}

/* 分针 */
.minute-wrapper {
height: 75%;
width: 75%;
animation: clock-run 60s steps(60) infinite;
}

.minute {
width: 4px;
background-color: black;
}

/* 秒针 */
.second-wrapper {
height: 90%;
width: 90%;
animation: clock-run 1s steps(60) infinite;
}

.second {
width: 2px;
background-color: red;
}

@keyframes clock-run {
from {
transform: rotateZ(0);
}

to {
transform: rotateZ(360deg);
}
}

复仇者联盟

1
2
3
4
5
6
7
8
<div class="cube">
<div class="surface1"></div>
<div class="surface2"></div>
<div class="surface3"></div>
<div class="surface4"></div>
<div class="surface5"></div>
<div class="surface6"></div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
html {
perspective: 800px;
}

.cube {
height: 200px;
width: 200px;
margin: 200px auto;
position: relative;
/* 设置3d变形效果 */
transform-style: preserve-3d;
animation: cube-rotate 12s infinite linear;
}

.cube div {
height: 200px;
width: 200px;
background-size: cover;
position: absolute;
top: 0;
left: 0;
/* 为元素设置透明效果 */
opacity: .85;
}

.surface1 {
background-image: url("/assets/复仇者联盟/1.jpg");
transform: translateX(-100px) rotateY(90deg);
}

.surface2 {
background-image: url("/assets/复仇者联盟/2.jpg");
transform: translateX(100px) rotateY(90deg);
}

.surface3 {
background-image: url("/assets/复仇者联盟/3.jpg");
transform: translateY(-100px) rotateX(90deg);
}

.surface4 {
background-image: url("/assets/复仇者联盟/4.jpg");
transform: translateY(100px) rotateX(90deg);
}

.surface5 {
background-image: url("/assets/复仇者联盟/5.jpg");
transform: translateZ(-100px);
}

.surface6 {
background-image: url("/assets/复仇者联盟/6.jpg");
transform: translateZ(100px);
}

@keyframes cube-rotate {
from {
transform: rotateX(0) rotateY(0) rotateZ(0);
}

to {
transform: rotateX(1turn) rotateY(2turn) rotateZ(3turn);
}
}

less简介

less是一门css的预处理语言

  • less是一个css的增强版,通过less可以编写更少的代码实现更强大的样式

  • less中添加了许多的新特性:像对变量的支持、对mixin的支持…

  • less的语法大体上和css语法一致,但是less中增添了许多对css的扩展,所以浏览器无法直接执行less代码,要执行必须向将less转换为css,然后再由浏览器执行

安装插件

vscode中搜索less,点击安装

编写less

html代码

使用快捷方式创建html代码

回车生成html代码

1
2
3
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>

less代码

创建style.less文件,编写less代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
body {
--height: calc(200px / 2);
--width: 100px;
div {
height: var(--height);
width: var(--width);
}
.box1 {
background-color: #bfa;
}
.box2 {
background-color: red;
}
.box3 {
background-color: yellow;
}
}

我们直接在HTML中引入生成的style.css

1
<link rel="stylesheet" href="/css/style.css">

less语法

less注释

less中的单行注释,注释中的内容不会被解析到css

css中的注释,内容会被解析到css文件中

1
2
3
4
5
// `less`中的单行注释,注释中的内容不会被解析到`css`中

/*
`css`中的注释,内容会被解析到`css`文件中
*/

父子关系嵌套

less中,父子关系可以直接嵌套

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// `less`中的单行注释,注释中的内容不会被解析到`css`中

/*
`css`中的注释,内容会被解析到`css`文件中
*/
body {
--height: calc(200px / 2);
--width: 100px;
div {
height: var(--height);
width: var(--width);
}
.box1 {
background-color: #bfa;
.box2 {
background-color: red;
.box3 {
background-color: yellow;
}
>.box4{
background-color: green;
}
}
}
}

对应的css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
`css`中的注释,内容会被解析到`css`文件中
*/
body {
--height: calc(200px / 2);
--width: 100px;
}
body div {
height: var(--height);
width: var(--width);
}
body .box1 {
background-color: #bfa;
}
body .box1 .box2 {
background-color: red;
}
body .box1 .box2 .box3 {
background-color: yellow;
}
body .box1 .box2 > .box4 {
background-color: green;
}

变量

变量,在变量中可以存储一个任意的值

并且我们可以在需要时,任意的修改变量中的值

变量的语法:@变量名

  • 直接使用使用变量时,则以@变量名的形式使用即可

  • 作为类名、属性名或者一部分值使用时,必须以@{变量名}的形式使用

  • 可以在变量声明前就使用变量(可以但不建议)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@b1:box1;
@b2:box2;
@b3:box3;
@size:200px;
@bc:background-color;
@bi:background-image;
@color:red;
@path:image/a/b/c;

.@{b1}{
width: @size;
height: $width;
@{bc}: @color;
@{bi}: url("@{path}/1.png");
}

.@{b2}{
width: @size;
height: $width;
@{bc}: @color;
@{bi}: url("@{path}/2.png");
}

.@{b3}{
width: @size;
height: $width;
@{bc}: @color;
@{bi}: url("@{path}/3.png");
}

生成的css代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.box1 {
width: 200px;
height: 200px;
background-color: red;
background-image: url("image / a / b / c/1.png");
}
.box2 {
width: 200px;
height: 200px;
background-color: red;
background-image: url("image / a / b / c/2.png");
}
.box3 {
width: 200px;
height: 200px;
background-color: red;
background-image: url("image / a / b / c/3.png");
}

注意:在中使用语法需要用引号包裹url``less

其他

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
.p1{
width: @size;
height: $width;
&-wrapper{
background-color: peru;
}
// &:hover{
// background-color: blue;
// }
:hover{
background-color: blue;
}
}
.p2:extend(.p1){
color:@color;
}
.p3{
.p1();
}
.p4(){
width: @size;
height: $width;
}
.p5{
// .p4();
.p4;
}

生成的css代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.p1,
.p2 {
width: 200px;
height: 200px;
}
.p1-wrapper {
background-color: peru;
}
.p1 :hover {
background-color: blue;
}
.p2 {
color: red;
}
.p3 {
width: 200px;
height: 200px;
}
.p5 {
width: 200px;
height: 200px;
}
  • & 拼接

  • 伪元素

  • :extend() 对当前选择器扩展指定选择器的样式(选择器分组)

  • .p1() 直接对指定的样式进行引用,这里就相当于将p1的样式在这里进行了复制(mixin 混合)

  • 使用类选择器时可以在选择器后边添加一个括号,这时我们实际上就创建了一个mixins混合函数

混合函数

在混合函数中可以直接设置变量,并且可以指定默认值

1
2
3
4
5
6
7
8
9
10
11
12
.test(@w:200px, @h:100px, @bc:red){
width: @w;
height: @h;
background-color: @bc;
}

.p6{
// .test(200px, 100px, red); // 对应参数位传值
// .test(@h:200px,@w:100px,@bc:red); // 写明对应属性,可变换顺序
// .test();
.test(300px);
}

生成的css代码

1
2
3
4
5
.p6 {
width: 300px;
height: 100px;
background-color: red;
}

其他

average混合函数
生成的css代码

1
2
3
.h1{
color:average(red,yellow);
}
1
2
3
.h1 {
color: #ff8000;
}

darken混合函数
生成的css代码

1
2
3
body{
background-color: darken(#bfa, 50%);
}
1
2
3
body{
background-color: #22aa00;
}

补充

创建all.less文件,将我们之前编写的less文件通过@import引入进来

可以通过import来将其他的less引入到当前的less

1
2
@import "style.less";
@import "syntax.less";

查看生成的all.css代码,会发现其他的内容囊括了两个less文件的内容

所以,我们可以利用@import来对less文件进行整合,然后引入生成的css文件使用即可

这样,每次修改的时候直接对某个模块的less文件进行修改,就会非常简单

如果我们观察过之前fontawesome源码文件,会发现其中也有less代码文件

不同的less文件里都有其自己的职责,如

  • _animated.less中专门存放动画的混合函数

  • _variables.less中专门存放定义的变量

但是也有个问题,通过F12调试时显示的也是css中对应的行号

如果我们要改,需要找一下,太麻烦了,能不能直接显示less中行号呢?这样我们直接定位到对应less中直接进行修改,维护起来也会比较方便

我们需要在Easy LESS插件中修改settings.json文件,在其中添加如下配置

1
2
3
4
5
"less.compile": {
"compress": true, // true => remove surplus whitespace
"sourceMap": true, // true => generate source maps (.css.map files)
"out": true // false => DON'T output .css files (overridable per-file, see below)
}

修改完毕后,会发现多生成出来一个all.css.map文件,说明配置生效

再刷新下页面,通过F12会发现变成了less文件对应的行号

我们来逐一解释下配置的less.compile项中每一个属性的含义

  • compress 生成的css文件代码会被压缩(作用相当于我们之前安装的JS & CSS Minifier (Minify)插件的效果)

  • sourceMap 生成.css.map文件,通过F12可以查看了less文件对应行号

  • out 生成对应css文件(当然是需要了)

弹性盒

flex(弹性盒、伸缩盒)

  • css中的又一种布局手段,它主要用来代替浮动来完成页面的布局

  • flex可以使元素具有弹性,让元素可以跟随页面的大小的改变而改变

弹性容器

要使用弹性盒,必须先将一个元素设置为弹性容器

我们通过display 来设置弹性容器

  • display:flex 设置为块级弹性容器

  • display:inline-flex 设置为行内的弹性容器

1
2
/* 设置弹性容器 */
display: flex;

弹性元素

弹性容器的子元素是弹性元素(弹性项)

弹性元素可以同时是弹性容器

弹性容器的属性

主轴与侧轴

  • 主轴:弹性元素的排列方向称为主轴

  • 侧轴:与主轴垂直方向的称为侧轴

主轴属性

排列方式

flex-direction 指定容器中弹性元素的排列方式

  • row默认值,弹性元素在容器中水平排列(自左向右)

  • row-reverse 弹性元素在容器中反向水平排列(自右向左)

  • column 弹性元素纵向排列(自上向下)

  • column-reverse 弹性元素反向纵向排列(自下向上)

1
2
/* 设置弹性元素排列方式 */
flex-direction: column;

自动换行

flex-wrap 设置弹性元素是否在弹性容器中自动换行

  • nowrap 默认值,元素不会自动换行

  • wrap 元素沿着辅轴方向自动换行

1
2
3
4
/* 设置弹性元素排列方式 */
flex-direction: row;
/* 设置自动换行 */
flex-wrap: wrap;

简写属性

flex-flowwrapdirection的简写属性

1
2
/* 简写属性 */
flex-flow: row wrap;

空白空间

justify-content 如何分配主轴上的空白空间(主轴上的元素如何排列)

  • flex-start 元素沿着主轴起边排列

flex-end 元素沿着主轴终边排列

center 元素居中排列

space-around 空白分布到元素两侧

space-between 空白均匀分布到元素间

space-evenly 空白分布到元素的单侧

辅轴属性

辅轴对齐

align-items元素在辅轴上如何对齐

  • stretch 默认值,将元素的长度设置为相同的值

flex-start 元素不会拉伸,沿着辅轴起边对齐

flex-end 沿着辅轴的终边对齐

center 居中对齐

baseline 基线对齐

空白空间

align-content 如何分配辅轴上的空白空间(辅轴上的元素如何排列)

  • flex-start 元素沿着辅轴起边排列

flex-end 元素沿着辅轴终边排列

center 元素居中排列

space-around 空白分布到元素两侧

space-between 空白均匀分布到元素间

space-evenly 空白分布到元素的单侧

弹性居中

利用弹性盒对元素进行水平垂直双方向居中

1
2
justify-content: center;
align-items: center;

弹性元素的属性

伸展系数

flex-grow 指定弹性元素的伸展系数,默认值为0

  • 当父元素有多余空间的时,子元素如何伸展

  • 父元素的剩余空间,会按照比例进行分配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
li:nth-child(1) {
background-color: #bfa;
flex-grow: 1;
}

li:nth-child(2) {
background-color: red;
flex-grow: 2;
}

li:nth-child(3) {
background-color: green;
flex-grow: 3;
}

缩减系数

flex-shrink 指定弹性元素的收缩系数,默认值为1

  • 当父元素中的空间不足以容纳所有的子元素时,如何对子元素进行收缩

  • 缩减系数的计算方式比较复杂,缩减多少是根据 缩减系数元素大小 来计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
li:nth-child(1) {
background-color: #bfa;
flex-shrink: 1;
}

li:nth-child(2) {
background-color: red;
flex-shrink: 2;
}

li:nth-child(3) {
background-color: green;
flex-shrink: 3;
}

基础长度

flex-basis 指定的是元素在主轴上的基础长度

  • 如果主轴是横向的,则该值指定的就是元素的宽度

  • 如果主轴是纵向的,则该值指定的就是元素的高度

  • 默认值是auto,表示参考元素自身的高度或宽度

  • 如果传递了一个具体的数值,则以该值为准

1
2
3
4
li:nth-child(1) {
background-color: #bfa;
flex-basis: 200px;
}

简写属性

1
flex`可以设置弹性元素所有的三个样式 `flex: 增长 缩减 基础
  • initialflex: 0 1 auto

  • autoflex: 1 1 auto

  • noneflex: 0 0 auto 弹性元素没有弹性

排列顺序

order 决定弹性元素的排列顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
li:nth-child(1) {
background-color: #bfa;
order: 2;
}

li:nth-child(2) {
background-color: red;
order: 3;
}

li:nth-child(3) {
background-color: green;
order: 1;
}

覆盖辅轴

1
align-self` 用来覆盖当前弹性元素上的`align-items
1
2
3
4
li:nth-child(1) {
background-color: #bfa;
align-self: flex-end;
}