HTML & CSS
NOTE_HTML5
介绍
✨尚硅谷Web前端HTML5 CSS3初学者零基础入门全套完整版学习笔记
软件
✨视频中使用到的软件和资源,还有一些其他的开发工具,仅供参考(eg. 考虑到部分下载速度的问题,特意整理了部分软件到Software仓库下,大家可以自取)
Zeal
NotePad
- 官方地址:notepad-plus-plus.org
- Softonic地址:Notepad++ - Download (softonic.com)
Sublime
VS Code
- 官方地址:Visual Studio Code - Code Editing. Redefined
- 安装的插件
- Chinese (Simplified) Language Pack for Visual Studio Code
- Ayu
- vscode-icons
- Live Server
- JS & CSS Minifier (Minify)
Atom
-
官方地址:Atom
WebStorm
FastStone Capture
Photoshop精简版
网址
字符实体
CSS Dinner
reset样式
- 官方地址:reset.css
normalize样式
- 官方地址:normalize.css
贝叶斯曲线
实战
- ✅ 京东图片列表
- ✅ 京东左侧导航条
- ✅ 网易新闻列表
- ⬜田径场(这个是我自己学完盒模型之后突发奇想的,大家可以忽略跳过)
- ✅ w3school顶部导航栏
- ✅ 京东轮播图
- ✅ 京东顶部导航条
- ✅ 背景按钮
- ✅ 电影卡片
- ✅ 小米商城
- ✅ 米兔
- ✅ 奔跑的少年
- ✅ 奔跑的川普
- ✅ 弹力球
- ✅ 酷炫球
- ✅ 鸭子表
- ✅ 复仇者联盟
字体
demo\font\
- ZCOOLKuaiLe-Regular.ttf
- ZCOOLQingKeHuangYou-Regular.ttf
- ZCOOLXiaoWei-Regular.ttf
前端简介
1. 软件的分类
1.1. 系统软件
- Windows
- Linux
- macOS
1.2. 应用软件
- Office
1.3. 游戏软件
- 绝地求生
- 王者荣耀
2. 客户端与服务器
通常情况下,现在的软件一般由两个部分组成:
- 客户端:用户通过客户端来使用软件。
- 服务器:服务器负责在远程处理业务逻辑。
2.1. 服务器
服务器开发的语言:
- Java
- PHP
- C#
- Python
- Node.js
- ……
2.2. 客户端
客户端的形式
- 文字客户端:占老的方式,通过命令行来使用软件
- 图形化界面:通过点击拖动等来使用软件。Windows 中、macOS 中、Android、iOS 中的大部分应用。(C/S 架构)
- 网页:通过访问网页来使用软件。所有的网站都属于这个范畴。(B/S 架构)
3. 网页的特点
相较于传统的图形化界面,网页具有如下一些优点:
- 不需要安装
- 无需更新
- 跨平台
网页中使用的语言:
- HTML、CSS、JavaScript
4. 网页简史
蒂姆·伯纳斯·李爵士,万维网的发明人。
1991 年 8 月 6 日,世界上第一个服务器和第一个网站在欧洲核子研究中心上线。
第一个网站:http://info.cern.ch/hypertext/WWW/TheProject.html
5. 浏览器和网页
有了浏览器我们只需要一个网址便可以访问任何的网站。
而浏览器中所显示的内容正是我们所说的网页。
网页原本的样子:
1 | ... |
浏览器渲染后的样子:
前端工程师负责编写网页的源代码。
浏览器负责将网页渲染成我们想要的样子。
5.1. 浏览器的问题
市面上存在有很多不同的浏览器。
在万维网的初期,网页编写并没有标准。
于是就出现了这种情况:
5.2. W3C 的建立
伯纳斯李 1994 年建立万维网联盟(W3C)
W3C 的出现为了制订网页开发的标准,以使同一个网页在不同的浏览器中有相同的效果。
所以,我们需要制订我们编写的网页都需要遵循 W3C 的规范!
5.3. 网页的结构思想
根据 W3C 标准,一个网页主要由三部分组成:结构、表现还有行为。
结构、表现、行为
- 结构(骨架):HTML 用于描述页面的结构
- 表现(皮肤):CSS 用于控制页面中元素的样式
- 行为(交互):JavaScript 用于响应用户操作
6. 网页的基本结构
6.1. 迭代
网页的版本
- HTML4
- XHTML2.0
- HTML5
6.2. 文档声明(doctype)
文档声明用来告诉浏览器当前网页的版本
1 | <!-- html5的文档声明 --> |
6.3. 字符编码
所有的数据在计算机中存储时都是以二进制形式存储的,文字也不例外。
所以一段文字在存储到内存中时,都需要转换为二进制编码当我们读取这段文字时,计算机会将编码转换为字符,供我们阅读
编码
将字符转换为二进制码的过程称为编码
解码
将二进制码转换为字符的过程称为解码
字符集(charset)
编码和解码所采用的规则称为字符集(相当于密码本)
乱码
如果编码和解码所采用的字符集不同就会出现乱码问题。
可以通过 meta 标签来设置网页的字符集,避免乱码问题
1 | <meta charset="utf-8" /> |
6.4. 常见的字符集
ASCII
ASCII(American Standard Code for Information Interchange):美国信息交换标准代码
在所有字符集中,最知名的可能要数被称为 ASCII 的8 位字符了。美国信息交换标准代码是由美国国家标准学会(American National Standard Institute , ANSI )制定的,是一种标准的单字节字符编码方案,用于基于文本的数据。它最初是美国国家标准,供不同计算机在相互通信时用作共同遵守的西文字符编码标准,后来它被国际标准化组织(International Organization for Standardization, ISO)定为国际标准,称为 ISO 646 标准。适用于所有拉丁文字字母
ASCII 码使用指定的 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 就是世界各国合作开发的一种语言。
6.5. HTML5 的基本结构
1 | <!-- 文档声明,声明当前网页的版本 --> |
前端开发准备
1. 离线文档的下载
离线文档:Zeal - Offline Documentation Browser
如果安装报错,需安装:Visual C++ Redistributable
下载安装完成之后,会在“开始”屏幕或者桌面生成快捷键,双击打开
在第一次使用时,并不是直接就有 HTML 文档的,还需要 Download。
这里点击工具栏的 Tools-Assets 或者下方的“Install and update docsets”都是 OK 的
按照步骤安装即可
由于服务器在国外,网络较慢,耐心等待 download 完毕
在 Installed 中出现 HTML,同时左侧导航栏有了 HTML,至此安装完毕
离线使用,在左侧导航栏可以查询 HTML 标签和属性,右侧显示元素的详细信息
2. 文本编辑器的选择
Notepad++
Notepad++是 Windows 操作系统下的一套文本编辑器,功能比 Windows 中的 Notepad 强大,除了可以用来制作一般的纯文字说明文件,也十分适合编写计算机程序代码。
有语法高亮度显示、语法折叠功能,并且支持宏以及扩充基本功能的外挂模组。
完全免费,支持众多计算机程序语言:C,C++,Java,C#,XML,SQL,HTML,PHP,ASP 等
Softonic 地址:Notepad++ - Download (softonic.com)
不过因为国外服务器原因,而且貌似被墙了,所以建议从 Softonic 下载
- 优点:免费开源,轻量流畅,支持插件
- 缺点:界面丑,虽然可以下载皮肤插件(PS:个人感觉皮肤插件也不好用)
Sublime
Sublime Text 是一个文本编辑器(收费软件,可以无限期试用,但是会有激活提示弹窗),同时也是一个先进的代码编辑器。
主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。
跨平台,同时支持 Windows、Linux、Mac OS X 等操作系统。
强大的命令面板功能,可以模糊匹配命令。
官方地址:Sublime Text - A sophisticated text editor for code, markup and prose
- 优点:轻量流畅,支持插件,界面简洁,运行速度特别快
- 缺点:不开源,商用收费
VS Code √
Microsoft 出品,轻量但强大,针对于编写现代 Web 和云应用的跨平台源代码编辑器。可以在 Mac OS X、Windows 和 Linux 等操作平台使用。
具有对 JavaScript、TypeScript 和 Node.js 的内置支持,并具有丰富的其他语言(例如 C++,C#,Java,Python,PHP,Go)和运行时(例如.NET 和 Unity)扩展的生态系统。
官方地址:Visual Studio Code - Code Editing. Redefined
- 优点:免费开源,轻量流畅,功能丰富,支持插件,界面简洁,智能代码补全,运行速度很快
- 缺点:几乎没有什么太大的缺点(PS:撤销恢复之前的编辑时出现过问题,希望官方能够尽快修复)
Atom
Atom 是 Github 专门为程序员推出的一个跨平台文本编辑器。完全免费开源的代码编辑器,具有简洁和直观的图形用户界面。
支持 CSS,HTML,JavaScript 等网页编程语言。支持宏,自动完成分屏功能,集成了文件管理器。
官方地址:Atom
Github 地址:atom/atom: The hackable text editor (github.com)
中文地址:Atom 中文网 (baisheng999.com)
- 优点:功能丰富,免费开源,支持插件,界面简洁
- 缺点:相对重量级;打开大文件卡死(PS:产品上经常用它写 amWiki,使用时经常卡死;而且安装过程没有任何选项和提示,默认装到 C 盘)
WebStorm
JetBrains 出品的智能 JavaScript IDE。誉为“Web 前端开发神器”、“最强大的 HTML5 编辑器”、“最智能的 JavaScript IDE”等。与 IntelliJ IDEA 同源,继承了 IntelliJ IDEA 强大的 JS 部分的功能。
IntelliJ IDEA 是 java 编程语言开发的集成环境。IntelliJ 在业界被公认为最好的 java 开发工具,尤其在智能代码助手、代码自动提示、重构、JavaEE 支持、各类版本工具(git、svn 等)、JUnit、CVS 整合、代码分析、 创新的 GUI 设计等方面的功能可以说是超常的。它的旗舰版本还支持 HTML,CSS,PHP,MySQL,Python 等。免费版只支持 Java,Kotlin 等少数语言。
官方地址:Download WebStorm: The Smartest JavaScript IDE by JetBrains
- 优点:功能强大,支持插件,界面美观,智能代码补全,快速搜索
- 缺点:重量级,占内存;收费
除以之外,市面上还有很多功能强大的前端编辑器。
HBuilder:DCloud(数字天堂)推出一款支持 HTML5 的 Web 开发 IDE。在语法提示、转到定义、重构、调试等方面都非常高效。缺点是不太稳定,有时会出现卡顿。
Dreamweaver:简称“DW,老牌的 IDE ,国人开发,号称为编码极客而生的 IDE。曾经 PS+DW+FW(号称网页三剑客)称霸网页领域。然而之前的版本更新较慢,版本陈旧,已经满足不了广大前端开发者的项目需求,逐渐被市场淘汰。
这两款及其他编辑器在这里就不再赘述了(PS:本人没怎么用过,没有太多发言权)
这里我选择以 VSCode 作为接下来学习的开发编辑器了。当然每个人有每个人的偏好,你也可以选择自己心仪的编辑器进行开发。
3. 开发前准备
为 VSCode 安装以下插件,便于我们进行更好的开发工作
- Chinese (Simplified) Language Pack for Visual Studio Code:中文(简体)语言包(PS1:不完全显示中文,但是大多数都会译为英文;PS2:喜欢原生态或者英文 OK 的话,可忽略)
- Ayu:简单的主题与明亮的颜色
- vscode-icons:好看的图标
- Live Server:A Quick Development Live Server with live browser reload,即提供一个 live 服务器,并且支持代码与浏览器之间的实时同步刷新(PS:这样我们在写前端代码时就能实时看到效果了)
4. 使用 Live-Server
在当前 HTML 中右键单击,选择Open With Live Server
踩坑 1
Open a folder or workspace...(File -> Open Folder)
解决方式:需要打开 HTML 所在的文件夹,通过导航栏 文件-打开文件夹
,选择我们编写的 HTML,再去Open With Live Server
即可
踩坑 2
1 | Server is started at 5500 but failed to open in Browser Preview. |
解决方式:在 liveserver 设置中,找到Live Server>Settings:Use Browser Preview
,取消对 Open in Browser Preview inside VS Code,instead of default browser
的勾选即可
踩坑 3
1 | Error: connect ECONNREFUSED 127.0.0.1:80 |
解决方式:取消使用代理,修改 enable 为 false(这里我一直以为是 live-server 服务器本身的代理端口)。live-server 默认使用 5500 端口
实际上,配置端口要在Live Server › Settings: Port
选项进行设置
自定义端口号
按照上述说明,点击在settings.json中编辑
会打开settings.json
文件
这里如果将liveServer.settings.port
配置为 0,会随机选择端口号
字符实体与语义标签
1. 字符实体
有些时候,在 HTML 中不能直接书写一些特殊符号,如:
- 多个连续的空格(在网页中编写的多个空格默认情况会自动被浏览器解析为一个空格)
- 比如字母两侧的大于小于号(可能会被认为是标签并解析)
如果我们需要在网页中书写这些特殊的符号,则需要使用 html 中的实体(转义字符)实体的语法:&实体的名字;
,如:
实体名称 | 显示结果 | 描述 |
---|---|---|
|
|
空格 |
> |
> | 大于号 |
< |
< | 小于号 |
& |
& | 与 |
© |
© | 版权 |
® |
® | 注册商标 |
™ |
™ | 商标 |
× |
× | 乘号 |
÷ |
÷ | 除号 |
¿ |
¿ | 倒问号 |
更多的字符实体,可参考:HTML 字符实体、HTML ISO-8859-1 参考手册
2. meta 标签
以京东网站为例,右键单击,选择查看网页源代码
1 | <meta charset="utf8" version="1" /> |
meta 主要用于设置网页中的一些元数据,元数据并不是给用户看的
-
charset :指定网页的字符集
-
name :指定的数据的名称
-
keywords:表示网站的关键字,可以同时指定多个关键字,关键字间使用
,
隔开 -
description:表示网站的描述信息
-
-
content :指定的数据的内容,会作为搜索结果的超链接上的文字显示
打开 Zeal 手册(前端开发准备中做过介绍)
发现除了charset
、name
、content
之外,还有一个叫http-equiv
的属性
1 | If the http-equiv attribute is set, the <meta /> element is a pragma directive, |
如果设置了http-equiv
属性,<meta>
元素就是一个 pragma 指令,提供的信息相当于一个类似名称的 HTTP 头所能提供的信息。
点击http-equiv
的链接,查看其更详细信息。
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 | <meta charset="utf-8" /> |
对refresh
进行测试,发现过了 3 秒钟之后自动跳转到了指定的网站
3. 语义标签
在网页中 HTML 专门用来负责网页的结构所以在使用 html 标签时,应该关注的是标签的语义,而不是它的样式
这里先介绍几个基本的语义标签,还有些常用的标签放在后面具体讲解
标签 | 作用 | 描述 | |
---|---|---|---|
块元素 Block Element |
<h1> <h2> <h3> <h4> <h5> <h6> |
标题 | 一共有六级标题 从 h1 ~ h6 重要性递减,h1 最重要,h6 最不重要h1 在网页中的重要性仅次于 title 标签一般情况下一个页面中只会有一个 h1 一般情况下标题标签只会使用到 h1 ~ h3 ,h4 ~ h6 很少用 |
<hgroup> |
标题组 | 多层次的标题。它将一组<h1> ~ <h6> 元素分组 |
|
<p> |
段落 | 页面中的一个段落。由空行或第一行缩进将相邻的文本块分开 | |
<blockquote> |
短引文 | 用缩进表示所包含文本。 可以用 cite 属性表示引文来源,用<cite> 元素表示来源的文本表述 |
|
行内元素 Inline Element |
<q> |
长引文 | 用一个简短的内联引号包围文本。 大多数浏览器通过在文本周围加上引号来实现。 该元素用于不需要段落分隔的短引文; |
<br> |
换行 | ||
<em> |
强调 | 表示强调作用。<em> 元素可以嵌套,每一级嵌套表示更高的强调程度<i> 元素效果与它相同,不过<i> 不属于语义标签 |
|
<strong> |
重要 | 表示重要性、严肃性或紧迫性。浏览器通常以粗体字呈现内容<b> 元素效果与它相同,不过<b> 不属于语义标签 |
举例
1 | <h1>Beetles</h1> |
效果
HTML5 提供的新语义元素有
标签 | 作用 | 描述 |
---|---|---|
<header> |
页眉 | 介绍性的内容 |
<footer> |
页脚 | 通常包含有关作者的信息、版权或文件链接 |
<nav> |
导航链接 | 可以是当前文档内的,也可以是到其他文档的。常见例子是菜单、目录和索引 |
<main> |
文档主内容 | 中心主题直接相关或扩展的内容 |
<article> |
文章 | 自成一体,独立分发,可重复使用 |
<section> |
文档中的节 | 没有一个更具体的语义元素来代表 |
<aside> |
页面内容以外的内容 | 其内容与文档的主要内容只有间接的关系。经常以边栏或呼出框的形式出现 |
<mark> |
重要或强调的文本 | 为参考或记事目的而被标记或突出的文本,表明其相关性和重要性 |
<summary> |
<details> 标题 |
为<details> 指定一个摘要、标题或图例。点击<summary> 可以切换<details> 打开和关闭 |
<details> |
用户能够查看或隐藏的额外细节 | 其中的信息只有被切换到 "打开 "状态时才可见。必须使用<summary> 提供一个摘要或标签 |
<figure> |
自包含内容 | 独立的内容,用<figcaption> 元素指定一个可选的标题。比如图示、图表、照片、代码清单等 |
<figcaption> |
<figure> 的标题 |
描述其父元素 |
<time> |
定义日期/时间 | 可能包括datetime 属性,将日期翻译成机器可读的格式,以便获得更好的搜索引擎结果或自定义功能。如提醒 |
这些新语义标签在视觉效果上基本上没有什么区别
4. 块元素与行内元素
块元素(block element)
- 在网页中一般通过块元素来对页面进行布局
行内元素(inline element)
- 行内元素主要用来包裹文字
- 一般情况下会在块元素中放行内元素,而不会在行内元素中放块元素
- 如
<p>
元素中不能放任何的块元素,不过
- 如
5. 内容修正
浏览器在解析网页时,会自动对网页中不符合规范的内容进行修正,比如:
- 标签写在了根元素的外部
<p>
元素中嵌套了块元素- 根元素中出现了除
head
和body
以外的子元素
这个通过浏览器中的查看网页源代码
并不能看到效果,但是使用 F12 进行开发者调试
时是能够看到上述几种情况被修正的结果。
不过虽然浏览器能够对不规范的页面内容进行修正,还是不建议编写不规范的代码,因为这对后期代码维护或团队代码协作将是非常不好的后果和体验。
6. 布局标签
结构化语义标签
header
表示网页的头部(页眉)main
表示网页的主体部分(一个页面中只会有一个 main)footer
表示网页的底部(页脚)nav
表示网页中的导航aside
和主体相关的其他内容(侧边栏)article
表示一个独立的文章section
表示一个独立的区块,上边的标签都不能表示时使用 section
div
块元素,没有任何的语义,就用来表示一个区块。目前来讲,div 还是主要的布局元素span
行内元素,没有任何的语义,一般用于在网页中选中文字
7. 列表
在 html 中可以创建列表,html 列表一共有三种:
-
有序列表,使用
ol
标签来创建有序列表,使用li
表示列表项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> -
无序列表,使用
ul
标签来创建无序列表,使用li
表示列表项1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<ul>
<li>Milk</li>
<li>
Cheese
<ul>
<li>
Blue cheese
<ul>
<li>Sweet blue cheese</li>
<li>Sour blue cheese</li>
</ul>
</li>
<li>Feta</li>
</ul>
</li>
</ul>可以看出,列表元素之间是可以互相嵌套的
-
定义列表,使用
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>
8. 超链接
超链接可以让我们从一个页面跳转到其他页面,或者是当前页面的其他的位置
使用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 | <ul> |
效果
内部地址
当我们需要跳转一个服务器内部的页面时,一般我们都会使用相对路径,会以./
或../
开头
./
表示当前文件所在目录,可以省略不写../
表示当前文件所在目录的上一级目录
1 | <a href="./test1.html">超链接1</a><br /> |
效果
新建页面
target
属性,用来指定超链接打开的位置可选值:
_self
在当前页面中打开超链接,默认值_blank
在新建页面中打开超链接
1 | <a href="./test1.html">超链接1——默认</a><br /> |
锚点跳转
可以使用javascript:void(0);
来作为href
的属性,此时点击这个超链接什么也不会发生
可以将#
作为超链接的路径的占位符使用。
可以直接将超链接的href
属性设置为#
,这样点击超链接以后页面不会发生跳转,而是转到当前页面的顶部的位置
可以跳转到页面的指定位置(锚点),只需将href
属性设置#目标元素的id属性值
(唯一不重复)
1 | <p>汉皇重色思倾国,御宇多年求不得。</p> |
效果
9. 图片
图片标签用于向当前页面中引入一个外部图片
img
标签是一个自结束标签,这种元素属于替换元素(块和行内元素之间,具有两种元素的特点)
属性
src
:属性指定的是外部图片的路径(路径规则和超链接是一样的)alt
:图片的描述,这个描述默认情况下不会显示,有些浏览器会在图片无法加载时显示,搜索引擎会根据 alt 中的内容来识别图片width
:图片的宽度(单位是像素)height
:图片的高度(单位是像素)- 宽度和高度中如果只修改了一个,则另一个会等比例缩放
注意
- 一般情况在 pc 端,不建议修改图片的大小,需要多大的图片就裁多大
- 但是在移动端,经常需要对图片进行缩放(大图缩小)
举例
1 | <img |
效果
图片格式
jpeg(jpg)
- 支持的颜色比较丰富
- 不支持透明效果
- 不支持动图
- 一般用来显示照片
gif
- 支持的颜色比较单一
- 支持简单透明
- 支持动图
png
- 支持的颜色丰富
- 支持复杂透明
- 不支持动图
- 专为网页而生
webp
- 这种格式是谷歌新推出的专门用来表示网页中的图片的一种格式
- 具备其他图片格式的所有优点,而且文件还特别的小
- 缺点:兼容性不好
base64
-
将图片使用 base64 编码,这样可以将图片转换为字符,通过字符的形式来引入图片
1
2
3
4<img
width="300"
src="data:image/png;base64,AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAxVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zda/P9qhPz/mKr9/7bC/f/Fz/7/ydL+/8HM/v+tu/3/jaH9/156/P8zV/z/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/z9h/P+gsP3/8fP+/////////////////////////////////////////////////+ru/v+Zqv3/PV/8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P9lgPz/6+/+///////////////////////////////////////////////////////////////////////s7/7/Y378/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/aoT8//r6/v///////////////////////v7+/+Po/v/R2f7/y9T+/9rg/v/3+f7////////////////////////////j6P7/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/0Zm/P/w8/7/////////////////5+v+/4ab/f9AYvz/MVX8/zFV/P8xVfz/MVX8/zVY/P9kf/z/tsP9//39/v////////////T2/v8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/sL79/////////////////87W/v8/Yfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/ZYD8//L0/v//////n7D9/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/0Bh/P/6+/7////////////v8v7/QmP8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/TWz8/3GJ/P8yVvz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/e5L8/////////////////5qr/f8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P+mtv3/////////////////XHn8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/7/L/f////////////////87Xfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/ydL+////////////+/v+/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P/Ezv7////////////9/f7/M1b8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/7G//f////////////////9HZ/z/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/kqX9/////////////////22H/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P9kf/z/////////////////pbX9/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zRX/P/v8v7////////////s7/7/Nln8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/6Ky/f////////////////+Inf3/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/RWb8//f4/v////////////H0/v9Kafz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/PV/8/1Jw/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/kKT9/////////////////9vh/v9DZPz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/1Fv/P/m6/7//v7+/3aO/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8zVvz/xM79/////////////////+fr/v9viPz/MVX8/zFV/P8xVfz/MVX8/zRX/P+Emf3/8/X+////////////xc/+/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P87Xfz/ztf+///////////////////////i5/7/sL79/5+w/f+ywP3/6u3+//////////////////////+uvP3/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P83Wvz/sL79//7+/v//////////////////////////////////////////////////////3OL+/0Vl/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/aYP8/9Pb/v//////////////////////////////////////9fb+/5yu/f84W/z/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/1d0/P+Spf3/t8T9/8fR/v/Dzv7/qrn9/3uS/P88Xvz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/MVX8/zFV/P8xVfz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
/>图片格式的选择
-
图片效果一样的,选文件小的
-
图片效果不一样的,选图片效果好的
-
尽可能的兼顾和平衡图片效果和文件大小
10. 内联格式
内联框架iframe
,用于向当前页面中引入一个其他页面,
src
指定要引入的网页的路径frameborder
指定内联框架的边框
举例
1 | <iframe |
效果
11. 音视频
音频
audio
标签用来向页面中引入一个外部的音频文件
音视频文件引入时,默认情况下不允许用户自己控制播放停止
属性:
controls
是否允许用户控制播放autoplay
音频文件是否自动播放- 如果设置了
autoplay
,则音乐在打开页面时会自动播放 - 但是目前来讲大部分浏览器都不会自动对音乐进行播放
- 如果设置了
loop
音乐是否循环播放
1 | <audio src="./source/audio.mp3" controls autoplay loop></audio> |
source
除了通过src
属性来指定外部文件的路径以外,还可以通过<source>
元素来指定文件的路径
1 | <audio controls autoplay loop> |
IE11 下,能够正常播放
IE8 下,出现我们自定义的提示信息
embed
IE8 下不支持audio
元素,但是可以使用 <embed>
元素在文档中的指定位置嵌入外部内容。
这个内容是由外部应用程序或其他互动内容的来源提供的,如浏览器插件。
1 | <embed src="./source/audio.mp3" /> |
视频
使用video
标签来向网页中引入一个视频,使用方式和audio
基本上是一样的
1 | <video controls> |
IE11 下,能够正常播放
IE8 下,也能正常播放
其他
通过iframe
和embed
的方式引入视频。以某艺为例,提供了视频链接的 HTML 代码和通用代码
1 | <iframe |
不过,embed
需要 flash 的支持
1 | <embed |
CSS 语法与选择器
1. CSS 简介
层叠样式表
网页实际上是一个多层的结构,通过 CSS 可以分别为网页的每一个层来设置样式,而最终我们能看到只是网页的最上边一层
总之一句话,CSS 用来设置网页中元素的样式
使用 CSS 来修改元素样式的方式大致可以分为 3 种
内联样式(行内样式)
在标签内部通过style
属性来设置元素的样式
1 | <p style="color:red;font-size:60px;">内联样式(行内样式)</p> |
问题:使用内联样式,样式只能对一个标签生效。如果希望影响到多个元素,必须在每一个元素中都复制一遍;并且当样式发生变化时,我们必须要一个一个的修改,非常的不方便。(注意:开发时绝对不要使用内联样式)
内部样式表
将样式编写到head
中的style
标签里然后通过 css 的选择器来选中元素并为其设置各种样式可以同时为多个标签设置样式,并且修改时只需要修改一处即可。内部样式表更加方便对样式进行复用
1 | <style> |
问题:我们的内部样式表只能对一个网页起作用,它里边的样式不能跨页面进行复用
外部样式表
可以将 css 样式编写到一个外部的 CSS 文件中,然后通过link
标签来引入外部的 CSS 文件
1 | <link rel="stylesheet" href="./style.css" /> |
外部样式表需要通过link
标签进行引入,意味着只要想使用这些样式的网页都可以对其进行引用使样式,可以在不同页面之间进行复用
将样式编写到外部的 CSS 文件中,可以使用到浏览器的缓存机制,从而加快网页的加载速度,提高用户的体验。
2. CSS 基本语法
注释
css 中的注释
只能使用/*
和*/
包裹。即不管是单行注释,还是多行注释,都是以/*
开头,以*/
结尾
1 | /* css中的单行注释 */ |
我们对比下其他几种前端语言的注释
html 中的注释
只能使用<!--
和-->
包裹。即不管是单行注释,还是多行注释,都是以<!--
开头,以-->
结尾
1 | <!-- html中的单行注释 --> |
JS(JavaScript)和 JQuery 中的注释
单行注释使用//
。多行注释使用/*
和*/
包裹,以<!--
开头,以-->
结尾
1 | /* JS(JavaScript)和JQuery中的单行注释*/ |
基本语法
选择器 声明块
选择器
通过选择器可以选中页面中的指定元素
- 比如
p
的作用就是选中页面中所有的p
元素声明块
声明块
通过声明块来指定要为元素设置的样式
-
声明块由一个一个的声明组成,声明是一个名值对结构
-
一个样式名对应一个样式值,名和值之间以
:
连接,以;
结尾
1 | h1 { |
3. CSS 选择器
通配选择器(Universal selector)
- 作用:选中页面中的所有元素
- 语法:
*
- 例子:
*{}
1 | * { |
元素选择器(Type selector)
也叫类型选择器、标签选择器
- 作用:根据标签名来选中指定的元素
- 语法:
elementname{}
- 例子:
p{}
h1{}
div{}
1 | p { |
类选择器(Class selector)
- 作用:根据元素的 class 属性值选中一组元素
- 语法:
.classname
- 例子:
.blue{}
1 | .blue { |
class
是一个标签的属性,它和id
类似,不同的是class
- 可以重复使用,
- 可以通过
class
属性来为元素分组, - 可以同时为一个元素指定多个
class
属性
1 | <p class="blue size">类选择器(Class selector)</p> |
ID 选择器(ID selector)
- 作用:根据元素的
id
属性值选中一个元素 - 语法:
#idname{}
- 例子:
#box{}
#red{}
1 | #red { |
属性选择器(Attribute selector)
- 作用:根据元素的属性值选中一组元素
- 语法 1:
[属性名]
选择含有指定属性的元素 - 语法 2:
[属性名=属性值]
选择含有指定属性和属性值的元素 - 语法 3:
[属性名^=属性值]
选择属性值以指定值开头的元素 - 语法 4:
[属性名$=属性值]
选择属性值以指定值结尾的元素 - 语法 5:
[属性名*=属性值]
选择属性值中含有某值的元素 - 例子:
p[title]{}
p[title=e]{}
p[title^=e]{}
p[title$=e]{}
p[title*=e]{}
1 | p[title] { |
4. 复合选择器
交集选择器
- 作用:选中同时复合多个条件的元素
- 语法:
选择器1选择器2选择器3选择器n{}
- 注意点:交集选择器中如果有元素选择器,必须使用元素选择器开头
1 | div.red { |
并集选择器(选择器分组)
- 作用:同时选择多个选择器对应的元素
- 语法:
选择器1,选择器2,选择器3,选择器n{}
- 例子:
#b1,.p1,h1,span,div.red{}
1 | h1, |
5. 关系选择器
- 父元素:直接包含子元素的元素叫做父元素
- 子元素:直接被父元素包含的元素是子元素
- 祖先元素:直接或间接包含后代元素的元素叫做祖先元素;一个元素的父元素也是它的祖先元素
- 后代元素:直接或间接被祖先元素包含的元素叫做后代元素;子元素也是后代元素
- 兄弟元素:拥有相同父元素的元素是兄弟元素
子元素选择器(Child combinator)
- 作用:选中指定父元素的指定子元素
- 语法:
父元素 > 子元素
- 例子:
A > B
1 | div.box > p > span { |
后代元素选择器(Descendant combinator)
- 作用:选中指定元素内的指定后代元素
- 语法:
祖先 后代
- 例子:
A B
1 | div span { |
兄弟元素选择器(Sibling combinator)
- 作用:选择下一个兄弟
- 语法:
前一个 + 下一个
前一个 + 下一组
- 例子 1:
A1 + A2
(Adjacent sibling combinator) - 例子 2:
A1 ~ An
(General sibling combinator)
1 | p + span { |
6. 伪类选择器
伪类(不存在的类,特殊的类)
伪类用来描述一个元素的特殊状态,比如:第一个子元素、被点击的元素、鼠标移入的元素.…
伪类一般情况下都是使用:
开头
: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 | /* ul下所有li,黑色 */ |
:link
未访问的链接:visited
已访问的链接- 由于隐私的原因,所以
visited
这个伪类只能修改链接的颜色
- 由于隐私的原因,所以
:hover
鼠标悬停的链接:active
鼠标点击的链接
1 | /* unvisited link */ |
7. 伪元素选择器
伪元素,表示页面中一些特殊的并不真实的存在的元素(特殊的位置)
伪元素使用::
开头
::first-letter
表示第一个字母::first-line
表示第一行::selection
表示选中的内容::before
元素的开始::after
元素的最后::before
和::after
必须结合content
属性来使用
1 | /* 段落首字母设置大小为30px */ |
8. CSS Dinner 游戏
官方地址:CSS Diner - Where we feast on CSS Selectors!
CSS Dinner 是一个帮助初学者快速熟悉 css 各种选择器的网页游戏
样式继承与其他概念
1. 继承
样式的继承,我们为一个元素设置的样式,同时也会应用到它的后代元素上
继承是发生在祖先后后代之间的,继承的设计是为了方便我们的开发
利用继承,我们可以将一些通用的样式,统一设置到共同的祖先元素上。这样只需设置一次即可让所有的元素都具有该样式
注意,并不是所有的样式都会被继承:
- 比如背景相关的,布局相关等的这些样式都不会被继承。
我们可以再 Zeal 手册中,搜索background-color
属性,可以看到一个定义的表格。其中就说明了其不可被继承性
2. 选择器的权重
当我们通过不同的选择器,选中相同的元素,并且为相同的样式设置不同的值时,此时就发生了样式的冲突。
发生样式冲突时,应用哪个样式由选择器的权重(优先级)决定选择器的权重
选择器 | 权重 |
---|---|
内联样式 | 1, 0, 0, 0 |
ID 选择器 | 0, 1, 0, 0 |
类和伪类选择器 | 0, 0, 1, 0 |
元素选择器 | 0, 0, 0, 1 |
通配选择器 | 0, 0, 0, 0 |
继承的样式 | 没有优先级 |
比较优先级时,需要将所有的选择器的优先级进行相加计算,最后优先级越高,则越优先显示(分组选择器是单独计算的)
选择器的累加不会超过其最大的数量级,类选择器再高也不会超过 ID 选择器
如果优先级计算后相同,此时则优先使用靠下的样式
可以在某一个样式的后边添加!important
,则此时该样式会获取到最高的优先级,甚至超过内联样式,注意:在开发中一定要慎用!
1 | <style> |
3. 长度单位
像素
我们先来看下某度上关于像素(pixel,缩写 px)的介绍
像素是指由图像的小方格组成的,这些小方块都有一个明确的位置和被分配的色彩数值,小方格颜色和位置就决定该图像所呈现出来的样子。
可以将像素视为整个图像中不可分割的单位或者是元素。不可分割的意思是它不能够再切割成更小单位抑或是元素,它是以一个单一颜色的小格存在 [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 | <style> |
4. 颜色单位
人眼能够识别多少种颜色?
正常人有三种视椎细胞,是三色视觉者(红绿蓝),总共能看到大约 100 万种颜色
男的大约 130 万 女的大约 180 万
大概有经验的油漆工人辨别 1000 种左右,再高就难以分辨了。
比如红色,可以分为 50 个等级,邻近的两个等级能够别出来,说明他的眼睛辨别能力就很不错了。
过去的老工人,凭肉眼可辨别 50 种黑色,当然都要有特定的样板色做对比。
我引用了网上的一些答案,也是众说纷纭。不过我的理解是
- 人眼能至少接收 100 多万种颜色,因人而异
- 但最多只能够对 1000 多种颜色做出识别,因人而异
css 中的颜色名称
我们生活中会使用各种颜色名称去描述看到的各种颜色,在 css 中当然也可以直接使用颜色名来设置颜色,比如:red、orange、yellow、blue、green 等等
其中有 140 种颜色名称是所有浏览器都支持的,但是有个问题,就是在 css 中直接使用颜色名非常不方便
而且世界上有无数种颜色,人眼也不能分辨出所有颜色,更不可能对每一种颜色都进行命名
而且就算能够有办法对那么多种颜色进行命名,我们也不可能一个一个的去记或去查这种对应关系。试问下,有多少人看一眼某个颜色,就能够在调色板上快速准确的定位那个颜色或者直接叫出那种颜色的名称?这显然不现实,至少现在如此
另外,那么 css 中还可以怎么调和出更多的颜色呢?
在介绍 css 的颜色单位之前,我们首先来了解下光的三原色,因为 css 的颜色单位就是按照光的三原色来调和的
发现光的色散奥妙之后,牛顿开始推论:既然白光能被分解及合成,那么这七种色光是否也可以被分解或合成。于是,纷繁的实验和不停的计算充斥着他日后的生活。
一段时间后,牛顿通过计算,得出了一个结论:七种色光中只有红、绿、蓝三种色光无法被分解,于是也就谈不到合成了。
而其他四种色光均可由这三种色光以不同比例相合而成。于是红、绿、蓝则被称为“三原色光”或“光的三原色”(注意,这有别于我们熟知的三原色“红黄蓝”)。
牛顿通过计算得出上述结论后,未能完成实验,便与世长辞。
这里再科普下光的三原色和颜料的三原色的区别
颜料三原色(CMYK):品红、黄、青(天蓝)。色彩三原色可以混合出所有颜料的颜色,同时相加为黑色,黑白灰属于无色系。
光学三原色(RGB):红、绿、蓝(靛蓝)。光学三原色混合后,组成显示屏显示颜色,三原色同时相加为白色,白色属于无色系(黑白灰)中的一种。
那看到这里有人会问了,css 为什么不按照颜料的三原色来调和呢?
因为道理很简单,聪明的小伙伴应该已经知道答案了。上面我们也说过,屏幕是由像素组成的,每个像素就是一个单位色块。而这个单位色块之所以能显示颜色,就是靠发光来实现的
既然光是由三种色光组成的,任何一种颜色均可以由这三种颜色调和出来的,那么为什么我们不能用三原色来表示一种颜色呢?
RGB 值
RGB 通过三原色的不同浓度来调配出不同的颜色
- 语法:
RGB(red, green, blue)
- 范围:每一种颜色的范围在 0 ~ 255(0% ~ 100%)之间
RGBA
就是在 rgb 的基础上增加了一个 a 表示不透明度
1
表示完全不透明0
表示完全透明.5
半透明
十六进制的 RGB 值
就是 RGB 值的十六进制写法
- 语法:
#RRGGBB
- 范围:每一种颜色的范围在 00 ~ ff 之间
如果颜色两位两位重复可以进行简写,如#aabbcc
=> #abc
在 vscode 中,我们可以看到其会对颜色进行预览展示。并且将鼠标移至 color 处悬浮,会智能的弹出一个 rgb 调色板,方便我们进行调色
如果我们看到某种颜色,非常喜欢,那么在哪里才能买得到呢? 怎么知道这个颜色的 rgb 值呢?
我们可以直接搜索黄色,哦不是,取色器!有些录制软件也会自带取色功能,如 FastStone Capture
下载地址:FastStone Capture - Download
盒模型
1. 文档流(normalflow)
网页是一个多层的结构,一层摁着一层
通过 CSS 可以分别为每一层来设置样式,作为用户来讲只能看到最顶上一层
这些层中,最底下的一层称为文档流
文档流是网页的基础我们所创建的元素默认都是在文档流中进行排列
对于我们来元素主要有两个状态
- 在文档流中
- 不在文档流中(脱离文档流)
那么元素在文档流中有什么特点,我们接着往下看
2. 块元素
- 块元素会在页面中独占一行
- 默认宽度是父元素的全部(会把父元素撑满)
- 默认高度是被内容撑开(子元素)
3. 行内元素
- 行内元素不会独占页面的一行,只占自身的大小
- 行内元素在页面中左向右水平排列(书写习惯一致)
- 如果一行之中不能容纳下所有的行内元素,则元素会换到第二行继续自左向右排列
- 行内元素的默认宽度和高度都是被内容撑开
4. 盒子模型
网页设计中常听的属性名:内容(content)、内边距(padding)、边框(border)、外边距(margin), CSS 盒子模型都具备这些属性。
这些属性我们可以用日常生活中的常见事物——盒子作一个比喻来理解,所以叫它盒子模型。
CSS 盒子模型就是在网页设计中经常用到的 CSS 技术所使用的一种思维模型。[^1]
盒模型、盒子模型、框模型(box model)
CSS 将页面中的所有元素都设置为了一个矩形的盒子
将元素设置为矩形的盒子后,对页面的布局就变成将不同的盒子摆放到不同的位置
每一个盒子都由一下几个部分组成:
- 内容区(content)
- 内边距(padding)
- 边框(border)
- 外边距(margin)
内容区(content)
内容区是盒子模型的中心,它呈现了盒子的主要信息内容,这些内容可以是文本、图片等多种类型
元素中的所有的子元素和文本内容都在内容区中
width和height
设置排列内容区的大小width
设置内容区的宽度height
设置内容区的高度
示例
1 | .box1 { |
效果
边框(border)
边框属于盒子边缘,边框里边属于盒子内部,出了边框都是盒子的外部
注意:边框的大小会影响到整个盒子的大小
border-width
边框的宽度:默认 3pxborder-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 | .box1 { |
效果(solid)
效果(dotted)
效果(dashed)
效果(double)
不论是border-width
、 border-color
、border-style
还是其衍生出来的属性写法,都可以指定每个方向的边框情况
设定几个值就决定了对应方向的宽度、颜色或样式
- 四个值:
上 右 下 左
- 三个值:
上 左右 下
- 两个值:
上下 左右
- 一个值:
上下左右
其实不管设置几个值,只要记住:其顺序是按顺时针方向设置的,剩下的可以由矩形的对称性推导出来
border
:简写属性,通过该属性可以同时设置边框所有的相关样式,并且没有顺序要求
border-top
上边框的宽度、颜色和样式border-right
右边框的宽度、颜色和样式border-bottom
下边框的宽度、颜色和样式border-left
左边框的宽度、颜色和样式
1 | .box1 { |
内边距(padding)
内边距,也叫填充,是内容区和边框之间的空间
padding-top
上内边距padding-right
右内边距padding-bottom
下内边距padding-left
左内边距
padding 内边距的简写属性,可以同时指定四个方向的内边距,规则和边框中属性值设置一样
注意:内边距的设置会影响到盒子的大小,背景颜色会延伸到内边距上
示例
1 | <style> |
效果
可以看出,当内外 div 宽度和高度一样时,由于 outer 设置了一个 padding 属性,其盒子大小被“撑大了”
盒子可见框的大小,由内容区、内边距和边框共同决定,所以在计算盒子大小时,需要将这三个区域加到一起计算
外边距(margin)
外边距,也叫空白边,位于盒子的最外围,是添加在边框外周围的空间。空白边使盒子之间不会紧凑地连接在一起,是 CSS 布局的一个重要手段
注意:外边距不会影响盒子可见框的大小,但是外边距会影响盒子的位置和占用空间
一共有四个方向的外边距:
margin-top
上外边距- 设置正值,元素自身向下移动
- 设置负值,元素自身向上移动
margin-right
右外边距- 设置正值,其右边的元素向右移动
- 设置负值,其右边的元素向左移动
- 上述说法并不准确,对于块元素,设置
margin-right
不会产生任何效果
margin-bottom
下外边距- 设置正值,其下边的元素向下移动
- 设置负值,其下边的元素向上移动
- 上述说法并不准确,对于块元素,会有垂直方向上的边距重叠问题(后面会细说)
margin-left
左外边距- 设置正值,元素自身向右移动
- 设置负值,元素自身向左移动
元素在页面中是按照自左向右的顺序排列的,所以默认情况下
- 如果我们设置的左和上外边距则会移动元素自身
- 而设置下和右外边距会移动其他元素
示例 1
1 | .box1 { |
效果
示例 2
1 | .box1 { |
效果
5. 水平方向布局
元素在其父元素中水平方向的位置由以下几个属性共同决定
margin-left
border-left
padding-left
width
padding-right
border-right
margin-right
一个元素在其父元素中,水平布局必须要满足以下的等式
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
值以使等式成立这七个值中有三个值可以设置为
auto
:width
、margin-left
、maring-right
-
如果某个值为 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
-
如果宽度为
auto
,则宽度会调整到最大,其他auto
的外边距会自动设置为 0auto + 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
-
如果外边距都为
auto
,则auto
的外边距会自动均分以使等式成立auto + 0 + 0 + 200 + 0 + 0 + auto = 600
==>300 + 0 + 0 + 200 + 0 + 0 + 300 = 800
-
示例
1 | <style> |
效果
6. 垂直方向布局
元素溢出
子元素是在父元素的内容区中排列的,如果子元素的大小超过了父元素,则子元素会从父元素中溢出
使用overflow
/overflow-x
/overflow-y
属性来设置父元素如何处理溢出的子元素
可选值:visible
/hidden
/scroll
/auto
visible
溢出内容会在父元素外部位置显示,默认值
示例
1 | <style> |
效果
hidden
溢出内容会被裁剪,不会显示
示例
1 | <style> |
效果
scroll
生成两个滚动条,通过滚动条来查看完整的内容
示例
1 | <style> |
效果
auto
根据需要生成滚动条
示例
1 | <style> |
效果
边距折叠
垂直外边距的重叠(折叠):相邻的垂直方向外边距会发生重叠现象
兄弟元素
兄弟元素间的相邻,垂直外边距会取两者之间的较大值(两者都是正值)
特殊情况:
- 如果相邻的外边距一正一负,则取两者的和
- 如果相邻的外边距都是负值,则取两者中绝对值较大的
示例
1 | .box1, |
效果
疑问
当浏览器缩放比例是 100%时,我们使用FastStone Capture工具自带的刻度尺测量,发现“兄弟”之间似乎没有我们想象的那么“亲近”
两者的垂直方向间距是 125px,我们明明上下元素设置的都是 100px 啊,这是为什么呢?
在网页布局中,通过谷歌浏览器或火狐浏览器预览时,发现我们定义的盒模型 width,height,margin,padding 值都是不准确的
谷歌、火狐浏览器 缩放为 80% 时,margin 值才正确[^2]
总结
兄弟元素之间的外边距的重叠,对于开发是有利的,所以我们不需要进行处理
父子元素
父子元素间相邻外边距,子元素会传递给父元素(上外边距)
示例
1 | .box3{ |
效果
不加 margin-top
加 margin-top
父子外边距的折叠会影响到页面的布局,必须要进行处理
处理方式 1
1、我们转换思路,将对子元素的调整转为对父元素的调整
1 | .box3 { |
效果
可以看到父元素位置虽然正确了,但是高度却被“撑大了”。我们之前说过,padding 属性会影响元素的大小
2、这里我们还需要计算并手动调整下父元素的高度
1 | .box3 { |
效果
处理方式 2
1、我们仍然保留子元素的margin-top
属性,但是给父元素加一个上边框
1 | .box3 { |
效果
2、但是因为加了 1px 的边框,所以父元素盒子的高度也增加了 1px。那我们就需要手动调整父元素的高度,同时让边框颜色与父元素盒子颜色保持一致
1 | .box3 { |
但是我们没有发现一个问题不难发现一个问题,子元素也往下移动了 1px 的距离
因为父元素高度少了 1px,而子元素的 margin-top 是从边框下面开始算的
所以,凭借大家朴素的情感,哪个应该怎么判? 应该怎么改?
改法也很简单,margin-top 减去一个像素即可
1 | .box3 { |
效果
同时,我们用刻度尺测量,父子元素底部是在一条水平线上的
脱离文档流
上述示例 2 中,使用了 border 属性,就让子元素的外边距不去传递给父元素了,这是为什么呢?
margin (子元素远离父元素边框)[^3]
如果父盒子没有设置 border 框着,那么他的子元素无法利用 margin-top 来远离父元素的上边框
如果使用了 margin-top 会使子元素和父元素一起往下移
(子想离,父不设置 border 边框 则离得是流 不是父盒子)
应该是 border 让元素脱离了文档流(margin 塌陷)
好吧好吧,至于什么是 margin 塌陷,我也是问了度娘,有兴趣的可以自行百度,这里就不再赘述了
7. 行内元素的盒模型
-
行内元素不支持设置宽度和高度
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;
}
8. 浏览器的默认样式
通常情况,浏览器都会为元素设置一些默认样式
默认样式的存在会影响到页面的布局,通常情况下编写网页时必须要去除浏览器的默认样式(PC 端的页面)
在当今网页设计/开发实践中,使用 CSS 来为语义化的(X)HTML 标记添加样式风格是重要的关键。
在设计师们的梦想中都存在着这样的一个完美世界:所有的浏览器都能够理解和适用多有 CSS 规则,并且呈现相同的视觉效果(没有兼容性问题)。
但是,我们并没有生活在这个完美的世界,现实中发生的失窃却总是恰恰相反,很多 CSS 样式在不同的浏览器中有着不同的解释和呈现。
当今流行的浏览器(如:Firefox、Opera、Internet Explorer、Chrome、Safari 等等)中,有一些都是以自己的方式去理解 CSS 规范,这就会导致有的浏览器对 CSS 的解释与设计师的 CSS 定义初衷相冲突,使得网页的样子在某些浏览器下能正确按照设计师的想法显示
而且有些浏览器却并没有按照设计师想要的样子显示出来,这就导致浏览器的兼容性问题。
更糟的是,有的浏览器完全无视 CSS 的一些声明和属性。[^4]
我们可以尝试编写 css 样式,以去除浏览器的默认样式
示例
html 代码
1 | <div class="box1"></div> |
css 代码
1 | .box1 { |
效果
F12 看盒子默认样式
-
段落之间有 16px 的默认行距
-
列表外有 16px 的上下外边距和 40px 的左内边距,而且每项列表前有一个小黑点
去除默认样式
-
去除与浏览器的边缘间距
1
2
3body {
margin: 0;
} -
去除段落之间行距
1
2
3p {
margin: 0;
} -
去除列表的上下外边距和左内边距
1
2
3
4ul {
margin: 0;
padding: 0;
}我们只是去除了列表的内外边距,但是发现前面的黑点也消失了,真的如此吗?
我们先给
ul
加上一个margin-left
1
2
3
4
5ul {
margin: 0;
padding: 0;
margin-left: 16px;
}看来黑点并没有自动清除,而只是“缩进”了浏览器的左侧
-
去除列表前的黑点
1
2
3
4
5
6ul {
margin: 0;
padding: 0;
margin-left: 16px;
list-style: none;
}再将之前加的 16px 的
margin-left
样式去除1
2
3
4
5
6ul {
margin: 0;
padding: 0;
/* margin-left: 16px; */
list-style: none;
}到这里似乎就大功告成了,但是我们会发现写法似乎
很完美有点麻烦1
2
3
4
5
6
7
8
9
10
11
12
13body {
margin: 0;
}
p {
margin: 0;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}有没有简化空间了呢?
答案是肯定的,我们前面介绍过通配选择器的概念,可以直接简化成一个
-
简化写法
1
2
3
4
5* {
margin: 0;
padding: 0;
list-style: none;
}效果是一样的
去除浏览器的默认样式的需求是非常普遍的,我们难道每次都需要手动去除浏览器的默认样式?
这样岂不是很麻烦,难道官方就没有想到解决方案吗?
答案也是肯定的,有!
正因为上述冲突和问题依然存在于这个”不完美的世界”,所以一些设计师想到了一种避免浏览器兼容性问题的方法,那就是 CSS Reset
什么是 CSS Reset?
我们可以把它叫做 CSS 重设,也有人叫做 CSS 复位、默认 CSS、CSS 重置等。
CSS 重设就是先定义好一些 CSS 样式,来让所有浏览器都按照同样的规则解释 CSS,这样就能避免发生这种问题。[^4]
下方两种 css 样式,我们引入其中一个即可
reset 样式
官方地址:reset.css
1 | <link rel="stylesheet" href="assets/reset.css" /> |
效果
我们可以看到 reset.css 的作用就是将各个内外边距置为 0,将一些样式置为 none
1 | /* http://meyerweb.com/eric/tools/css/reset/ |
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]: margin(子元素远离父元素边框):https://www.cnblogs.com/FlFtFw/p/9627026.html
[^4]: 目前比较全的 CSS 重设(reset)方法总结:https://www.cnblogs.com/hnyei/archive/2011/10/04/2198779.html
实战练习
1. 京东图片列表
开发准备
本来我们是想直接右键图片另存为
的,但是发现并没有该选项,应该是京东对图片做了一定的限制
不过,这不妨碍我们获取这些图片,当然你也可以采用截图的方式获取,这里我们采用另外一种方式
通过 F12 可以看到,img
元素的src
属性,我们将三张图片的这些地址 copy 出来,直接在地址栏进行访问
1 | //img14.360buyimg.com/babel/s380x300_jfs/t1/168591/2/9328/64891/603ddb1aE93567699/3e4e717eeac051b2.jpg.webp |
这里就可以进行图片另存为
了,当然你也可以直接在src
上填写这些地址
不过,细心的同学会发现,这张图片的格式是jpg.webp
后缀结尾的
因为我是在谷歌浏览器中访问的,而谷歌浏览器有自己的特有的一种图片格式 webp(这个我们在第三节-字符实体与语义标签中介绍过)
当然这个格式不是谷歌自己进行转换的,而应该是京东做了不同浏览器之间的适配,即不同的浏览器传递不同格式的图片
Q:怎么验证这种说法呢?
A:我们可以打开非 Chrome 内核的浏览器,使用 F12 查看img
的src
地址就会发现不一样的地方了
这里我用微软自带的 IE 浏览器(温馨提示:微软官宣定于 2022 年 6 月 15 日完全停止对 IE 的支持)
对比就可以发现,无非就是在 Chrome 浏览器里后缀名多了一个.webp
而已
1 | <!-- IE中的src地址 --> |
知道这个原理,我们除了可以直接在图片另存为
保存为jpg
格式,其实还可以直接修改 url 地址
最后,我们将下载的图片放入assets
(自定义目录)工程目录下即可
布局剖析
我们使用 F12 进行调试,可以看到京东图片列表的具体元素及属性
- 整体使用一个
li
元素包裹,里面又套了一层 div`元素,宽高比:190:470 - 每张图片使用一个
img
元素,同时分别用a
元素包裹,宽高比:190:150 - 三张图片高度和为 150*3=450 < 470,注意到图片之间存在 2*10px 的外边距
这样,整个京东的图片列表的整体布局就非常清晰了
但是,我们不会那么去实现代码。因为li
元素应该包裹在ul
元素或者ol
元素中,而这里并没有遵循 css 中的语义标签使用规范
我们先看一下这么写会有什么问题
1 | <link rel="stylesheet" href="assets/reset.css" /> |
效果
由于使用了 reset 样式,浏览器的默认样式被我们去除了。但是使用ul
包裹的li
元素和使用div
包裹的li
元素存在明显的区别:
- 使用
ul
包裹的li
元素是没有默认样式的 - 使用
div
包裹的li
元素前仍然存在黑点
我想是因为京东在这里实现了自己的样式替换,所以为了避免重复 reset 默认样式,我们采用正常的列表标签
结构搭建
1 | <ul> |
到这里我们基本骨架已经有了,不过因为没有写 css 样式,图片几乎占据了整个浏览器页面
样式添加
方式 1
还记得上面分析对布局结构的分析吗?
我们首先调整整体的宽高比和单个图片的宽高比
1 | ul { |
当然这只是其中写法,我们还可以换个思路,退一步来思考
方式 2
我们呢不去限制图片的宽或高,而是对超出ul
元素部分(溢出部分)进行隐藏
1 | ul { |
但是因为图片本身的大小还没有做限制,所以图片保持了原来的图片比例和大小
小剧场:
我们发现下载下来的图片分辨率大小为 380*300,宽和高都刚好是浏览器中图片宽高的 2 倍
这只是巧合么?
不!这是京东为了高分辨率设备而做的适配,保证在一些高清屏下也能够保持清晰
那我们再对图片添加固定的宽或高不就行了?
不!我们直接指定宽或高的话,overflow
属性不就显得多此一举嘛
我们给 img 元素设定一个100%
的width
属性
1 | ul > li img { |
Q:为什么不能用auto
呢?
A:我们前一节-盒模型中讲过,水平布局必须要满足一个等式,不满足即存在过渡约束,会做自动调整
而ul
元素是块元素,块元素什么特点?独占一行啊!
图片宽度为 380px,浏览器宽度为 1920px(我本机中最大化浏览器的宽度)
现在的等式为0 + 0 + 0 + 380px + 0 + 0 + 0 = 1920px
这七个值中没有auto
的情况,所以浏览器会自动调整margin-right
值以使等式满足
0 + 0 + 0 + 380px + 0 + 0 + (1920-380)px = 1920px
所以如果使用auto
属性值,整个过程中图片的width
不会发生变化,展现出来的效果就依然是裁剪的样式
Q:为什么100%
可以呢?
A:我们知道100%
是会按照父元素计算的,img
的父元素是a
,a的
父元素是li
,li
的父元素是ul
也就是说,由于我们没有给a
和li
单独设置样式,因此img
最终会根据ul
的宽度计算
而如果只调整图片的宽或高,图片是会保持原比例进行缩放的
所以这个时候就相当于给img
设置了一个width=190px
的属性值
细节完善
背景色
通过颜色拾取器,识别背景色(我这里使用的是FastStone Capture中自带的Screen Color Picker
)
1 | ul{ |
外边距
根据布局剖析结果,我们给每个li
元素添加一个 10px 的下边距
1 | ul > li { |
Q:为什么是给li
元素添加呢?
A:我们在调整布局结构的时候,特别是设置外边距,一般是设置块元素的,而不建议去调整行内元素或行内块元素
最终效果
核心代码
1 | <link rel="stylesheet" href="css/reset.css" /> |
2. 京东左侧导航条
开发准备
我们需要的就是这些文字,事先复制下来
1 | 家用电器 手机 / 运营商 / 数码 电脑 / 办公 家居 / 家具 / 家装 / 厨具 男装 / 女装 |
布局剖析
- 整体使用
ul
和li
元素,宽高比=190px:470px,其中上下存在 10px 的内边距(影响盒子大小)和 10px 的外边距(影响盒子布局)
li
中每个元素也比较简单,用a
包裹文字,用span
包裹斜杠- 每个
li
元素的宽高比=190px:25px,其中左边存在 18px 的内边距(注意右边是不存在的)
- a 元素没有什么大的布局,
span
元素左右存在 2px 的内边距
结构搭建
1 | <ul> |
我们引入reset.css样式来去除浏览器的默认样式
1 | <link rel="stylesheet" href="css/reset.css" /> |
到这里,基本的骨架就有了
Q:那有些人会问了,我们不是引入了reset.css
重置了浏览器的默认样式吗?为什么超链接还有样式?
A:其实,如果仔细看 reset.css 的源代码,会发现a
元素只是重置了一些基本的内外边距、边框和字体大小,并没有做完全把a
元素的样式去除。这个下面会具体介绍
样式添加
根据布局剖析,我们可以直接设置整体的样式
1 | body { |
到这里整体样式就添加完毕,但我们发现有点问题
别急!我们继续进行细节上的样式调整和优化
细节完善
要求效果
目前的效果
两个主要问题
- 要求效果文字居中显示,而我们的文字偏左上角,底部有一定间距
- 文字存在换行和重叠现象
我们一个一个处理
文字调整
只需要给li
元素添加一行属性
1 | line-height: 25px; |
文字虽然在一行上了,但是依然有重叠问题啊,需要怎么处理呢?
要知道文字有几个属性:
- 文字大小
- 文字颜色
- 文字样式
我们通过 F12 看下这些属性
废话少说,直接写代码
1 | font-size: 14px; |
我们这里先不写text-decoration
属性,看下效果
写上text-decoration
属性,再看下效果
1 | text-decoration: none; |
这里可以看到文字下划线消失了,因为我们使用的a
标签包裹文字,而超链接具有一定的文字样式(就是蓝色字体带下划线),所以text-decoration
属性就是调整文字样式的
到这里,我们的重叠问题还是没有解决
稳住,我们能赢! 我们再对比下要求的效果和我们现在的效果
看出来区别了吗?(当然重点不是我们的背景色,这无关紧要)
我们是把/
符号用span
包裹起来的,但是我们的/
符号似乎又大又粗
符号调整
废话少说,上代码
1 | ul > li span { |
不过到这里,还是存在问题,我把span
元素的内边距去除才可以 (这里我没搞清楚为什么,知道的小伙伴可以评论或私信我哦;不过对比各个元素的盒子模型没什么区别,而且字体样式我也调整了;而且总感觉/
符号之间间隙大了一点,这里存疑先不管了,我们继续往下)
悬浮样式
我们注意到,当鼠标悬浮在某一行时,其背景颜色会有变化;同时,悬浮在某一个超链接上时,字体颜色变红
这里要用到一个伪类选择器:hover
,我们还是直接上代码
1 | ul > li { |
至此,我们的京东左侧导航栏
的前端样式就基本完成了
最终效果
核心代码
1 | <link rel="stylesheet" href="css/reset.css" /> |
存疑问题
通过一番折腾和研究,终于发现问题的关键所在
因为在编写 HTML 代码时,每个li
元素中的a
的span
标签都是换行的
而 HTML 中会将多个空格合并成一个,所以a
的span
之间都多了一个空格
有几种解决这个问题的方式
-
一是调整 HTML 中每个
li
元素中的代码,使之在一行上 -
二是给 ul 元素或 li 元素设置一个
font-size: 0
的属性值 -
三是通过 js 去除多余的换行字符(目前还没有学习到,所以不用这种方式,而且较麻烦)
我这里采用第二种方式
1 | ul > li { |
到这里,我们往往会忍不住赞叹一下自己:Nice !
3. 网易新闻列表
有了上面的实战步骤,对于网易新闻列表,我们就不进行那么详细的剖析了,直接上代码
结构搭建
1 | <div class="news_money"> |
样式添加
1 | /* ====================整体==================== */ |
盒模型补充
1. 盒子大小
默认情况下,盒子可见框的大小由内容区、内边距和边框共同决定
box-sizing
用来设置盒子尺寸的计算方式(设置 width 和 height 的作用)
1 | .box { |
可选值:
-
content-box
默认值,宽度和高度用来设置内容区的大小 -
border-box
宽度和高度用来设置整个盒子可见框的大小
width
和height
指的是内容区、内边距和边框的总大小
2. 轮廓
outline
用来设置元素的轮廓线,用法和border
一模一样
轮廓和边框不同点是,轮廓不会影响到可见框的大小
边框
1 | .box { |
轮廓
1 | .box { |
可以很明显看到outline
与border
的区别
我们一般不会直接这么设置轮廓,而是下面这种场景
1 | .box:hover { |
从上面的动态图也可以很清晰地看出,outline
属性并没有改变盒子的布局
3. 阴影
box-shadow
属性用于在一个元素的框架周围添加阴影效果你可以设置多个由逗号分隔的效果
一个盒状阴影由相对于元素的 X 和 Y 的偏移量、模糊和扩散半径以及颜色来描述
box-shadow
用来设置元素的阴影效果,阴影不会影响页面布局
1 | .box { |
1 | box-shadow: 10px 10px 5px orange; |
1 | box-shadow: 10px 10px 5px rgba(0, 0, 0, 0.2); |
- 第一个值-水平偏移量:设置阴影的水平位置
- 正值向右移动
- 负值向左移动
- 第二个值-垂直偏移量:设置阴影的垂直位置
- 正值向下移动
- 负值向上移动
- 第三个值-阴影的模糊半径
- 第四个值-阴影的颜色
4. 圆角
border-radius
属性使一个元素的外边框边缘的角变圆你可以设置一个半径来做圆角,或者设置两个半径来做椭圆角
border-radius
用来设置圆角,圆角设置的是圆的半径大小
border-top-left-radius
border-top-right-radius
border-bottom-left-radius
border-bottom-right-radius
1 | border-radius: 20px; |
1 | border-top-right-radius: 50px 100px; |
border-radius
可以分别指定四个角的圆角
- 四个值:
左上
右上
右下
左下
- 三个值:
左上
右上/左下
右下
- 两个值:
左上/右下
右上/左下
- 一个值:
左上/右上/右下/左下
这里同样不需要死记硬背,只要记住遵循顺时针方向和矩形中心点对称原则
与border
不同的是,border
是从上
开始顺时针设置,而圆角是从左上
开始
圆
原理很简单,就是绘制正方形,并将四个圆角半径设置为正方形的一半
1 | .box { |
椭圆
只需要对上述样式对一点点的改动,设置width
和height
属性不相等即可
1 | .box { |
田径场实战
html 代码
1 | <div class="box1"> |
css 样式
1 | .box1 { |
效果图
由于因为到目前为止,还没有学习更多的布局定位知识,所以一些其他的细节地方比较难绘制
这里就大概绘制一个雏形出来,等后面学习了绝对定位和相对定位之后再做补充和完善,会相对容易一些
绿茵足球场完善
学完了浮动,我们终于可以继续完善绿茵足球场了
废话不多说,直接上代码
1 |
|
这次主要的改动如下:
- 提取公共 css 代码
- 使用
float
属性进行布局 - 删除重叠部分边框样式(叠加之后颜色会变粗,这里去掉同一侧的边框样式)
不过需要注意的是由于boxColLine
不是float
元素,应该放置最下方
这样可以利用浮动的特点,防止对布局产生影响
最终效果
终于可以愉快的踢球了
搞错了,再来
浮动
1. 浮动的简介
通过浮动可以使一个元素向其父元素的左侧或右侧移动
使用float
属性来设置于元素的浮动
none
默认值,元素不浮动left
元素向左浮动right
元素向右浮动
注意
- 元素设置浮动以后,水平布局的等式便不需要强制成立
- 元素设置浮动以后,会完全从文档流中脱离,不再占用文档流的位置,所以元素下边的还在文档流中的元素会自动向上移动
2. 浮动的特点
-
浮动元素会完全脱离文档流,不再占据文档流中的位置
-
设置浮动以后,元素会向父元素的左侧或右侧移动
-
浮动元素默认不会从父元素中移出
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> -
浮动元素不会盖住文字,文字会自动环绕在浮动元素的周围,所以我们可以利用浮动来设置文字环绕图片的效果
简单总结:
- 浮动目前来讲它的主要作用就是让页面中的元素可以水平排列,通过浮动可以制作一些水平方向的布局
- 元素设置浮动以后,将会从文档流中脱离,从文档流中脱离后,元素的一些特点也会发生变化
3. 脱离文档流的特点
块元素:
- 块元素不再独占页面的一行
- 脱离文档流以后,块元素的宽度和高度默认都被内容撑开
1 | <style> |
行内元素:
- 行内元素脱离文档流以后会,特点和块元素一样
1 | <style> |
脱离文档流之后的特点很像行内块元素,不过存在一些差异
1 | <style> |
4. 简单布局
整体样式
目的
- 熟悉布局(块元素、浮动)
- 公共 css 部分复用
- 复习语义标签
代码
html 代码
1 | <!-- 页眉 --> |
css 代码
1 | /* 公共部分 */ |
效果
5. 练习:w3school 导航条
去除默认样式,引入 reset.css
1 | <link rel="stylesheet" href="css/reset.css" /> |
css 样式
1 | /* 去除默认样式 */ |
html 代码
1 | <ul class="menu"> |
效果
高度塌陷与 BFC
1. 高度塌陷
在浮动布局中,父元素的高度默认是被子元素撑开的
当子元素浮动后,其会完全脱离文档流,子元素从文档流中脱离将会无法撑起父元素的高度,导致父元素的高度丢失
父元素高度丢失以后,其下的元素会自动上移,导致页面的布局混乱
所以高度塌陷是浮动布局中比较常见的一个问题,这个问题我们必须要进行处理!
别急,我们接着往下看
2. BFC
BFC(Block Formatting Context)块级格式化环境
- BFC 是一个 CSS 中的一个隐含的属性,可以为一个元素开启 BFC
- 开启 BFC 该元素会变成一个独立的布局区域
元素开启 BFC 后的特点:
- 不会被浮动元素覆盖
- 父子元素外边距不会重叠
- 可以包含浮动的元素
可以通过一些特殊方式来开启元素的 BFC:
-
设置为浮动(不推荐):很明显下方元素被覆盖了,总不能让所有元素都浮动吧
-
设置为行内块元素(不推荐):不再独占一行,宽度变了,同时与下方元素产生了一点空隙
-
设置
overflow
为非visible
值:既没有覆盖元素,也保持了独占一方的特性(保持了宽度),与下方元素也保持了最初的间隙常用的方式为元素设置
overflow:hidden
(overflow:auto
也是 ok 的) 开启其 BFC, 以使其可以包含浮动元素overflow:scroll
会有滚动条,可能并不需要的,所以不太推荐不过,这种方式也存在一定问题,如下,
overflow
并没有完全清除 div2 布局上受到的影响
总结
- 可以通过变成浮动元素,来防止自身被浮动元素覆盖(有点“以毒攻毒”那味了)
- 可以设置行内块,来防止自身及其他元素被浮动元素覆盖(如果说浮动是“独善其身”,那行内块就有点“兼济天下”的意思)
- 可以设置
overflow
属性,包含浮动元素(既“独善其身”,又“兼济天下”,但仍有缺陷)
我们可以打开Zeal
手册(《02-前端开发准备》有介绍),查看关于 BFC 的说明文档
打开Block formatting context
模块后,可以看到有很多开启 BFC 的方式
我这里大概翻译了一下,并整理了一份表格,应该看起来更直观一点(有些概念因为还没有学习,翻译和理解有误的地方还望谅解)
元素或属性 | 说明 |
---|---|
<html> |
文档根元素 |
float: left float: right |
浮动元素(float 不为none ) |
position: absolut position: fixed |
绝对定位元素 |
display: inline-block |
行内块元素 |
display: table-cell |
表格单元,默认值 |
display: table-caption |
表格标题,默认值 |
display: table display: table-row display: table-row-group display: table-header-group display: table-footer-group display: inline-table |
匿名的表格单元,分别是 HTML 表格、表行、表体、表头和表脚的默认值 |
overflow: hidden overflow: scroll overflow: auto |
overflow 不为visible 和clip 的块元素 |
display: flow-root |
|
contain: layout contain: content contain: paint |
|
display: flex display: inline-flex 的直接子元素 |
Flex 项,如果它们本身既不是flex ,也不是grid 或table 容器 |
display: grid display: inline-grid 的直接子元素 |
Grid 项,如果它们本身既不是flex ,也不是grid 或table 容器 |
column-count 不为auto column-width 不为auto |
Multicol 容器,包含column-count: 1 |
column-span: all |
应该总是创建一个新的格式化上下文,即使column-span: all 元素不在 multicol 容器中 |
但是,注意不管哪种方式,多多少少都会有些隐患、缺陷或者说“副作用”
3. clear
我们这里设计三个兄弟元素,对前两个元素进行float
的浮动属性设置,看下效果
由于 box1 的浮动,导致 box3 位置上移也就是 box3 受到了 box1 浮动的影响,位置发生了改变(注意,这里文字并没有被覆盖,《09-浮动》一节说过浮动的特点,其中第 7 点就是“文字环绕”的问题)
如果我们不希望某个元素因为其他元素浮动的影响而改变位置,可以通过clear
属性来清除浮动元素对当前元素所产生的影响
clear
作用:清除浮动元素对当前元素所产生的影响(本质是为元素添加一个margin-top
属性,值由浏览器自动计算)
可选值:
left
清除左侧浮动元素对当前元素的影响right
清除右侧浮动元素对当前元素的影响both
清除两侧中影响较大一侧元素的影响(注意,这里不是同时清除两侧的影响)
4. after
我们学习了上面知识后,了解了高度塌陷问题的解决方式,其中主要有
-
通过
overflow: hidden
等可以为元素开启 BFC -
通过
clear: both
等可以清除浮动对元素产生的影响
同时也了解到,这两种方式都有一定的弊端和隐患。那有没有一种更好的方式去解决高度塌陷的问题呢?
答案当然是:有!
我们直接上效果图
Q1:这里使用了一个伪元素选择器::after
,那有人会问了,跟在 box2 下直接定义一个 box3 有什么区别呢?
A:我们知道,网页的结构思想是:结构+表现+行为。在 box2 下直接定义一个 box3,属于结构;而使用伪元素选择器,属于表现
而高度塌陷问题属于表现问题,定义 box3 的目的是为了撑起 box1 的内容,属于表现,而不是结构,所以在 css 中定义::after
更符合网页的编程思想
Q2:为什么需要使用display: block
呢?
A:因为默认情况下,::after
伪元素是一个行内元素,如果不转为块元素,将仍然撑不起 box1 的高度
5. clearfix
我们在前面《06-盒模型》一节中说过垂直布局中边距重叠的问题:相邻的垂直方向外边距会发生重叠现象
如上图所示,子元素设置了一个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 | .clearfix::before, |
其中.clearfix::before
是为了解决外边距重叠问题
1 | .clearfix::before { |
.clearfix::after
是为了解决高度塌陷问题
1 | .clearfix::after { |
两者合在一起,就可以完美地解决高度塌陷和外边距重叠这两大“世纪难题”了
定位的简介
需求分析
按照我们之前所学知识,可以怎么实现呢?
应该来说不难,很容易实现
1 | .box2 { |
我们分别给 box2 和 box3 添加了外边距之后,就可以达到需求效果
当然也可以使用浮动来解决上述问题,但稍微麻烦一点
不管怎样,问题也是显而易见。我们实际开发中,页面上的元素可能很多,这样改必然是 牵一发而动全身
那么仅仅靠我们之前学习的布局知识,不足以轻松应对这种场景
那么就势必需要一个方便我们处理这种场景的办法,它就是定位
呸!不是!糟老头子
定位(position)
定位是一种更加高级的布局手段
通过定位可以将元素摆放到页面的任意位置
使用position
属性来设置定位
可选值 | 含义 |
---|---|
static |
不开启定位,元素是静止的,默认值 |
relative |
开启元素的相对定位 |
absolute |
开启元素的绝对定位 |
fixed |
开启元素的固定定位 |
sticky |
开启元素的粘滞定位 |
1. 相对定位
当元素的 position 属性值设置为relative
时,则开启了元素的相对定位
偏移量(offset)
当元素开启相对定位以后,可以通过偏移量来设置元素的位置
offset 属性 | 含义 |
---|---|
top |
定位元素和定位位置的上边距离 |
bottom |
定位元素和定位位置的下边距离 |
left |
定位元素和定位位置的左侧距离 |
right |
定位元素和定位位置的右侧距离 |
定位元素垂直方向的位置由top
和bottom
两个属性控制,通常情况下只会使用其中之一
top
值越大,定位元素越靠下bottom
值越大,定位元素靠上
定位元素水平方向的位置由left
和right
两个属性控制,通常情况下只会使用其中之一
left
越大,定位元素越靠右right
越大,定位元素越靠左
ok,介绍完相对布局,我们的需求是不是变得 so easy!
1 | .box2 { |
我们给 box2 设置相对定位,就得到了我们想要的页面效果
可以看出,使用了相对定位后,只会移动自身的布局位置,而不会对已存在的其他元素产生任何影响
现在我们所举的例子不是很明显,但当页面布局比较复杂,特别是页面元素很多的时候,其优越性就可以大大体现出来
相对定位的特点
-
当元素开启相对定位以后,如果不设置偏移量元素,则元素不会发生任何变化(这里注意,不仅仅是位置)
-
相对定位是参照于元素在文档流中的位置进行定位的(可以理解为相对于自身原始位置)
-
相对定位会提升元素的层级(表现为可以覆盖其他元素)
-
相对定位不会改变元素的性质:块还是块,行内还是行内
Q1:如果给上述三个 div 都设置相对定位,那么它们的层级关系会是什么样的呢?或者说谁会被谁覆盖呢?
A:百闻不如一见
,光说不练假把式
,我们直接进行测试验证
可以看到覆盖关系是:box3 >> box2 >> box1
我们再稍微调整下 box3 和 box2 的前后位置
会发现覆盖关系变成了:box2 >> box3 >> box1
可以大概猜测:在页面文档流中,越靠下的元素开启相对定位后,其层级越高 (这里也只是我个人的揣测,待后续学习中验证)(在后续学习中已得到验证:没有设置层级或层级z-index
设置相同值时,优先显示靠下的元素)
Q2:相对定位的第三个特点相对定位会提升元素的层级
,是不是就类似于浮动一样脱离了文档流?
A:我们可以对比下,浮动和相对定位的区别
- 参考系不同:浮动的参考系是其父元素;相对定位是相对于自身
- 可移动方向不同:浮动只能左右移动;相对定位是上下左右移动
- 影响不同:浮动会影响页面布局(包括下方元素位置影响和高度塌陷问题);相对定位不对影响页面布局
- 性质不同:浮动会改变元素的性质(不再独占一行,其宽高都会被内容撑开);相对定位不会改变元素的性质
- 文字环绕:浮动不会覆盖文字;相对定位可以覆盖文字(这个可以自行验证,不再赘述)
当然,浮动和相对定位也有其相似之处
- 浮动和相对定位都是移动位置(貌似是废话)
- 浮动和相对定位不会从父元素中移出
可以看出,浮动和相对定位的区别是更多的
最后回答一点:浮动脱离了文档流,不再占据页面位置;相对定位仍然占据页面位置(所以怎么能够叫 脱离文档流
呢?)
Q3:相对定位的第四个特点相对定位不会改变元素的性质:块还是块,行内还是行内
,但是上述例子中元素开启相对定位后好像就不再独占一行了,这个怎么理解?
A:相比于浮动元素的特点,相对定位不会改变元素的性质其实是一个相对不容易理解的问题。但其实也不难,可以把相对定位认为是元素的灵魂出窍
。其位置发生改变以后,布局并没有产生影响,因为它的肉体
(结构)仍然占据着原来的那个位置。只是其灵魂
(内容)发生了移动。
Q4:相对定位的第四个特点中块还是块,行内还是行内
,意味着行内元素也可以使用相对定位是吗?
A:眼见为实,耳听为虚
,直接看示例效果
善于思考是好事,但也别忘了自动动手,丰衣足食
。自己实操一遍,胜过千言万语
2. 绝对定位
当元素的position
属性值设置为absolute
时,则开启了元素的绝对定位
绝对定位的特点
- 开启绝对定位后,如果不设置偏移量,元素的位置不会发生变化
- 开启绝对定位后,元素会从文档流中脱离
- 绝对定位会改变元素的性质:行内变成块,块的宽高被内容撑开(与相对定位相反)
- 绝对定位会使元素提升一个层级
- 绝对定位元素是相对于其包含块进行定位的(与相对定位不同)
包含块(containing block)
正常情况下:
- 包含块就是离当前元素最近的开启了定位的祖先块元素
- 如果所有的祖先元素都没有开启定位,则
html(根元素、初始包含块)
就是它的包含块
1 | <body> |
示例
1 | <div class="box2"> |
- 不给 box2、box3 开起定位,box4 的包含块是
html
- 只给 box3 开启定位之后,box4 的包含块是 box3
- 只给 box2 开启定位之后,box4 的包含块是 box2
- 给 box2、box3 都开起定位之后,box4 的包含块是 box3
注意:这里上述的条件是开启定位,也就是说只要position
不是static
(默认值),那么就满足了其成为包含块的必要条件
上述示例中,我们给其祖先元素都设置了相对定位。其实改成其他几种定位方式也是可行的,我们可以看下面示例
这里就不一一举例了,大家可以对另外几种定位方式进行验证
水平方向的布局
我们之前说过,水平方向的布局等式:
margin-left + border-left + padding-left + width + padding-right + border-right + margin-right = 其父元素的宽度
当使用绝对定位时,需要添加left
和right
两个值(此时规则和之前一样,只是多添加了两个值)
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
因为left
和right
的值默认是auto
,所以如果没有设置left
和right
,当等式不满足时,则会自动调整这两个值
水平居中
1 | <style> |
垂直方向的布局
垂直方向布局的等式的也必须要满足
top + margin-top + border-top + padding-top + height + padding-bottom + border-bottom + margin-bottom + top = 其父元素的高度
垂直居中
1 | .box2 { |
水平垂直居中
目前,我们可以根据绝对定位进行元素的水平垂直双方向居中,所以这个方法只是其中之一
1 | .box2 { |
小结
- 水平布局等式:
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
3. 固定定位
将元素的position
属性设置为fixed
,则开启了元素的固定定位
固定定位的特点
固定定位也是一种绝对定位,所以固定定位的大部分特点都和绝对定位一样
唯一不同的是,固定定位永远参照于浏览器的视口(viewport,可视窗口)进行定位,不会随网页的滚动条滚动
示例
我们再给body
设置一个较大的高度,让浏览器滚动起来,看下效果
会发现,box4 并没有因为滚动而发生未知的变化,这也验证了上述知识,同时也应该明白了视口
的概念
我们再对比下绝对定位
相信到这里,大家应该又进一步地理解了固定定位与绝对定位的区别
因为固定定位跟绝对定位除了具有上述差别之后,其他的特点跟绝对定位是一样的,所以这里便不再赘述了
4. 粘滞定位
将元素的position
属性设置为sticky
,则开启了元素的固定定位
这次,我们换个方式,直接来看粘滞定位的效果
大家可以看到,右侧边栏部分在一定的情况下是固定的,滚动到上方一定位置开始发生变动
我们先带着这个疑问,打开Zeal
官方手册,找到position
中sticky
的相关描述
The element is positioned according to the normal flow of the document, and then offset relative to its nearest scrolling ancestor and containing block (nearest block-level ancestor), including table-related elements, based on the values of top, right, bottom, and left. The offset does not affect the position of any other elements.
This value always creates a new stacking context. Note that a sticky element “sticks” to its nearest ancestor that has a “scrolling mechanism” (created when overflow is hidden, scroll, auto, or overlay), even if that ancestor isn’t the nearest actually scrolling ancestor. This effectively inhibits any “sticky” behavior (see the GitHub issue on W3C CSSWG).
不要慌,这里大概翻译一下(我这里稍微进行了下省略精简和整理总结)
- 该元素是根据文档流进行定位的,即相对于包含块进行偏移
- 偏移量不会影响任何其他元素的位置
- 粘性元素总是“粘”到其最近的具有“滚动机制”的祖先元素(当
overflow
为hidden
、scroll
、auto
、overlay
时创建),即使该祖先不是最近的实际滚动祖先
这里可能最后一点比较难理解,别着急,我们接着往下看
示例
我们拿之前的w3cschool顶部导航栏
进行下魔改
1 | /* 设置一个高度 */ |
因为在视频中老师并没有对sticky
属性做过多的介绍,只是要求我们了解一下,因为在实际开发中,也是结合 js 去实现的,所以我这里同样也就不再深入带大家一起看了
粘滞定位的特点
- 粘滞定位和相对定位的特点基本一致(视频中说是和相对定位一致,不过我对比了一下,很多特点是不同的,感觉倒是和固定定位更相似,这里存疑)
- 不同的是粘滞定位可以在元素到达某个位置时将其固定
需要注意的是,sticky
属性并不兼容 IE(PS:不过微软官方已经宣布将在 2022 年停止对 IE 的维护,IE 将成为历史。虽然我们经常诟病 IE,但作为当年浏览器的一霸,在废弃多年后,不知道还会不会有所怀念,毕竟它代表着我们不断逝去的青春)
5. 几种定位的对比
我们通过上面的学习,知道position
属性有五个可选值
但static
是默认值,即不开启定位,所以我们只需要对比 4 种定位方式即可
定位方式 | 是否不设置偏移量,元素不会发生改变 | 是否脱离文档流 | 是否改变元素性质 | 是否提升元素层级 | 参考系 |
---|---|---|---|---|---|
relative (相对定位) |
√ | × | × | √ | 参照于元素在文档流中的位置 |
absolute (绝对定位) |
× | √ | √ | √ | 参照于其包含块 |
fixed (固定定位) |
× | √ | √ | √ | 参照于浏览器的视口 |
sticky (粘滞定位) |
× | √ | √ | √ | 参照于浏览器的视口 |
6. 补充:元素层级
对于开启了定位元素,可以通过z-index
属性来指定元素的层级
z-index
需要一个整数作为参数,值越大元素的层级越高,元素的层级越高越优先显示- 如果元素的层级一样,则优先显示靠下的元素
- 祖先的元素的层级再高,也不会盖住后代元素
示例
1 | <style> |
存疑问题
Q:浮动也有层级概念吗?如果有,浮动和定位的层级关系是什么样的?
A:null / none / undefined 调了一下,出现几种现象
- 给
float
设置z-index
多大都没用,还是会被覆盖 - 默认情况,没有设置
z-index
或设置z-index
大小 ≥0 时,浮动层级
没有定位的层级高 - 设置
z-index
<0 时,浮动层级
可以定位的层级高
浮动层级
(不知道有没有这个概念,本身就是存疑问题,现在这种情况看起来应该是没有这个概念了)
7. 总结
一般情况下,
- 页面的整体结构大多采用浮动、块进行布局
- 页面某些模块结构一般采用定位进行微调
8. 练习:京东轮播图
css 代码
1 | /* 整体居中 */ |
html 代码
1 | <div class="box"> |
别忘了,引入reset
样式
效果
等到后面学习了 js,就可以实现自动轮播了,到时候再补充完善
主要运用
- 水平垂直双方向居中(水平垂直方向等式)
absolute
开启绝对定位,使其重叠,达到隐藏效果z-index
设置层级,实现图片轮播border-radius
画圆,transparent
边框透明,background-clip:content-box
隐藏边框
字体
1. 字体相关的样式
我们前面讲过字体的两个属性
-
color
用来设置字体颜色 -
font-size
字体的大小em
相当于当前元素的一个font-size
rem
相对于根元素的一个font-size
当然,字体的属性并不止这些
2. font-family
font-family
字体族(字体的格式)
-
serif
衬线字体 -
sans-serif
非衬线字体 -
monospace
等宽字体 -
cursive
手写体 -
fantasy
梦幻字体
上述字体均不表示具体的某种字体,而是字体的分类
我们经常使用的一些字体,如微软雅黑
、黑体
、楷体
、宋体
、Consolas
等,才是具体的某种字体
也就是说,font-family
指定字体的类别,浏览器会自动使用该类别下的字体
font-family
可以同时指定多个字体,多个字体间使用,
隔开
字体生效时优先使用第一个,第一个无法使用则使用第二个,以此类推
1 | font-family: "Courier New", Courier, monospace; |
3. 几种字体
我是乱分类的,随便看看就好
手写体
Indie Flower
Ink Free
Nanum Pen
MV Boli
Segoe Print
Shadows Into
艺术体
Barrio
Julius Sans One
Lobster
Monoton
Poiret One
乱码字体
MT Extra
Symbol
Webdings
Wingdings
中文字体
方正粗黑宋简体
微软雅黑
黑体
楷体
宋体
仿宋
4. @font-face
我们除了可以使用系统自带的字体样式外,还可以在服务器端自定义字体位置
@font-face
可以将服务器中的字体直接提供给用户去使用
1 | @font-face { |
问题
- 加载速度:受网络速度影响,可能会出现字体闪烁一下变成最终的字体
- 版权:有些字体是商用收费的,需要注意
- 字体格式:字体格式也有很多种(woff、otf、ttf),未必兼容,可能需要指定多个
5. 图标字体(iconfont)
图标字体简介
在网页中经常需要使用一些图标,可以通过图片来引入图标但是图片大小本身比较大,并且非常的不灵活
所以在使用图标时,我们还可以将图标直接设置为字体,然后通过@font-face
的形式来对字体进行引入
这样我们就可以通过使用字体的形式来使用图标
fontawesome
下载解压完毕之后,直接将 css 和 webfonts 移动到项目中即可使用
示例
1 | <link rel="stylesheet" href="/font/fontawesome/css/all.css" /> |
效果
其中fas
/fab
是免费的,其他是收费的
图标字体其他使用方式
通过伪元素设置
- 找到要设置图标的元素通过
::before
或::after
选中 - 在
content
中设置字体的编码 - 设置字体的样式
fab
:font-family: 'Font Awesome 5 Brands';
fas
:font-family: 'Font Awesome 5 Free'; font-weight:900;
示例
1 | <style> |
效果
通过实体设置
通过实体来使用图标字体:&#x图标编码;
示例
1 | <i class="fas"></i> |
效果
iconfont
iconfont 是阿里的一个图标字体库,海量图标库,图标字体非常丰富
但是版权有点模横两可,如果需要商用,最好联系作者
不过一般情况下,公司企业都会有自己的 UI 设计团队,会自己去进行设计
这里使用方式大同小异,不过
- iconfont 需要添加购物车后再添加至项目然后下载,下载包中有 demo.html,详细介绍了使用方式
- iconfont 也提供了一种在线方式,直接在
我的项目
中选择在线链接
可以复制出一份@font-face
的 css 代码
后续步骤与前面介绍的一致
示例
1 | <!-- <link rel="stylesheet" href="/font/iconfont/iconfont.css"> --> |
效果
6. 行高
行高line height
文字占有的实际高度,可以通过line-height
来设置行高
- 可以直接指定一个大小
px
/em
- 也可以直接为行高设置一个小数(字体大小的倍数)
行高经常还用来设置文字的行间距:行间距 = 行高 - 字体大小
字体框
字体框就是字体存在的格子,设置font-size
实际上就是在设置字体框的高度
行高会在字体框的上下平均分配
示例
1 | border: 1px black solid; |
不指定行高时,content
高度131.556px
:说明line-height
默认值大约是1.31
~ 1.32
(倍数)
指定行高时,content
高度99.556px
:少了0.444px
,并且字母p
下面溢出
存疑问题
经测试,line-height
大约比100.444px
略大一点时,content
高度才会大于100px
,暂未知原因
字体的简写属性
font
可以设置字体相关的所有属性:
font: font-style font-variant font-weight font-size/line-height font-family
其中某些值可以不写,会用默认值
默认值
属性 | 默认值 | 其他常用值 |
---|---|---|
font-style |
normal |
italic |
font-variant |
normal |
small-caps |
font-weight |
normal |
bold |
font-size |
medium |
small 、large |
line-height |
normal |
|
font-family |
取决于浏览器 |
示例 1
1 | /* font-size: 50px; |
示例 2
1 | /* small-caps值设置小型大写字母字体,所有小写变大写,同时字体尺寸更小(了解即可) */ |
注意 Pay Attention:简写属性省略的值会使用默认值,所以会覆盖前面的非简写属性(不仅仅对于字体而言)
7. 文本对齐方式
水平对齐
text-align
文本的水平对齐
text-align 属性值 |
对齐方式说明 |
---|---|
left |
左侧对齐 |
right |
右侧对齐 |
center |
居中对齐 |
justify |
两端对齐 |
left
左侧对齐
right
右侧对齐
center
居中对齐
justify
两端对齐
垂直对齐
vertical-align
设置元素垂直对齐的方式
vertical-align 属性值 |
对齐方式说明 |
---|---|
baseline |
基线对齐 |
top |
顶部对齐 |
bottom |
底部对齐 |
middle |
居中对齐 |
baseline
基线对齐
top
顶部对齐
bottom
底部对齐
middle
居中对齐
这里的居中对齐高度 = 基线高度 + x 的高度 / 2
这种居中对齐并非实际上的居中对齐,一般也不会用这种方式对文字进行垂直方向的对齐
vertical-align
还可以设置 px 值设置垂直对齐方式
1 | vertical-align: 10px; |
图片的垂直对齐问题
1 | <style> |
明显默认情况下,图片底部有一定缝隙,我们稍作修改,给 img 元素添加vertical-align
属性值
1 | /* 只要不是基线对齐,就能消除底部缝隙 */ |
Q:为什么图片会有缝隙?
A:图片属于替换元素,特点与文本一致,也有自己的基线,默认也是基线对齐。而基线位置不在最底部,所以会出现缝隙
背景
1. PS 的基本设置
工欲善其事,必先利其器
在介绍背景之前,首先需要做好准备工作:安装 PS 与基本设置
这里就不详细介绍 PS 的安装了,因为网上一抓一大把,主要介绍 PS 的基本设置
左侧工具栏
调成 2 列,更方便使用
右侧工具栏
不需要的视图统统关掉
修改单位为像素
由于一般默认的单位是厘米,所以这里需要修改
在历史记录、颜色或色板附近右键
,打开选项卡,选择界面选项
打开单位与标尺
,修改单位
中的标尺
与文字
为像素
2. 背景
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
1 | .box1 { |
backgound
背景相关的简写属性,所有背景相关的样式都可以通过该样式来设置并且该样式没有顺序要求,也没有哪个属性是必须写的
注意
background-size
必须写在background-position
的后边,并且使用/隔开background-position/background-size
background-origin background-clip
两个样式,orgin
要在clip
的前边
示例 2
1 | .box1 { |
练习 1:线性渐变效果的背景图
如果我们仔细挂那可能,会发现很多网站导航条的背景色并不是单一的某种颜色,而是有一个渐变的效果
不过到目前为止,我们还没有学习线性渐变
的内容,不过凭上面所学的知识同样可以实现
切图
首先,我们需要通过 PS 软件进行切图
- 按住
Alt
同时滚动鼠标滑轮,可以对图片大小进行缩放;调整至合适大小,再选择矩形块
工具,截取一个宽度为 1px 大小的图片
- 然后选择
图像
-裁剪
,就可以得到一个我们需要的一个背景图片
- 最后,选择
文件
-存储为Web所用格式
- 我这里选择的是 PNG 的格式,你可以对比几种格式,看看最终的图片大小折中选择,最好选择存储位置即可
- 得到我们需要的背景图片之后,就可以引入到
css
样式中了
代码
1 | height: 60px; |
效果
练习 2:按钮点击效果
代码
1 | <style> |
效果
雪碧图与渐变
1. 雪碧图
解决图片闪烁的问题:
可以将多个小图片统一保存到一个大图片中,然后通过调整background-position
来显示响应的图片
这样图片会同时加载到网页中就可以有效的避免出现闪烁的问题
这个技术在网页中应用十分广泛,被称为CSS-Sprite
,这种图我们称为雪碧图
雪碧图的使用步骤:
- 先确定要使用的图标
- 测量图标的大小
- 根据测量结果创建一个元素
- 将雪碧图设置为元素的背景图片
- 设置一个偏移量以显示正确的图片
雪碧图的特点:
- 一次性将多个图片加载进页面,降低请求的次数,加快访问速度,提升用户的体验
示例 1
1 | a:link { |
我们对比以下之前练习中的效果,第一次加载进来的时候会有明显的闪烁
示例 2
1 | .box1 { |
2. 线性渐变
通过渐变可以设置一些复杂的背景颜色,可以实现从一个颜色向其他颜色过渡的效果
!!渐变是图片,需要通过background-image
来设置
线性渐变,颜色沿着一条直线发生变化 linear-gradient()
1 | # 红色在开头,黄色在结尾,中间是过渡区域 |
线性渐变的开头,我们可以指定一个渐变的方向
to left
to right
to bottom
to top
deg
deg 表示度数turn
表示圈
1 | background-image: linear-gradient(to left, 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 | background-image: linear-gradient(red, yellow); |
3. 径向渐变
radial-gradient()
径向渐变(放射性的效果)
1 | background-image: radial-gradient(red, yellow); |
默认情况下,径向渐变的形状根据元素的形状来计算的
-
正方形 --> 圆形
-
长方形 --> 椭圆形
默认情况下,circle
和ellipse
是自动适配盒子的,我们也可以手动指定径向渐变的形状
形状
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 | background-image: radial-gradient(100px 60px, red, yellow); |
同时对其形状/大小和位置进行指定
radial-gradient(形状/大小 at 位置, 颜色 位置, 颜色 位置, 颜色 位置)
1 | background-image: radial-gradient(circle at 50px 100px, red 50px, yellow 100px); |
总结一下
形状
circle
圆形ellipse
椭圆
大小
closest-side
近边farthest-side
远边closest-corner
近角farthest-corner
远角
位置
top
right
left
center
bottom
类似于线性渐变,径向渐变也有对应的repeat
属性
1 | background-image: repeating-radial-gradient( |
总结:径向渐变的渐变方向以圆心为起点,往四周扩散的;同一半径上的颜色是渐变的,同一圆周上的颜色是一致的
表格
1、表格
在现实生活中,我们经常需要使用表格来表示一些格式化数据:
- 课程表、人名单、成绩单…
同样在网页中我们也需要使用表格,我们通过table
标签来创建一个表格
在table
中使用tr
表示表格中的一行,有几个tr
就有几行
在tr
中使用td
表示一个单元格,有几个 td就有
几个单元格
rowspan
纵向的合并单元格colspan
横向的合并单元格
1 | <table border="1" width="50%" align=" center"> |
2、长表格
可以将一个表格分成三个部分:
- 头部
thead
- 主体
tbody
- 底部
tfoot
th
表示头部的单元格
1 | <table> |
3、表格的样式
HTML 代码
1 | <table> |
CSS 代码
1 | table { |
其中,
border-spacing
:指定边框之间的距离border-collapse
:设置边框的合并
4、表单
表单
- 在现实生活中表单用于提交数据
- 在网页中也可以使用表单,网页中的表单用于将本地的数据提交给远程的服务器
form 的属性
action
:表单要提交的服务器的地址
文本框
注意:数据要提交到服务器中,必须要为元素指定一个name
属性值
1 | 文本框<input type="text" name="username" /> |
密码框
1 | 密码框<input type="password" name="password" /> |
提交按钮
1 | <input type="submit" value="注册" /> |
单选框
像这种选择框,必须要措定一个value
属性,value
属性最终会作为用户填写的值传递给服务器
1 | 单选框 |
多选框
1 | 多选框 |
下拉列表
1 | 下拉列表 |
5、表单补充
按钮
1 | <!-- 提交按钮 --> |
上面两种写法实际上效果是一致的,区别在于:
input
是自闭合标签,不需要</input>
就能结束;button
不是自闭合标签,跟一般标签一样是成对出现的button
因为不是自闭合标签,所以使用起来更灵活,可以嵌套其他的标签
过渡与动画
1、过渡
过渡(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.comsteps()
分步执行过渡效果,可以设置第二个值:end
,在时间结束时执行过渡(默认值)start
,在时间开始时执行过渡
transition
:可以同时设置过渡相关的所有属性
- 只有一个要求,如果要写延迟,则两个时间中第一个是持续时间,第二个是延迟时间
示例
1 | /* transition: margin-left 2s 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(0.17, 1.79, 0.68, -0.69); |
steps()
分步执行过渡效果
1 | /* transition-timing-function: steps(2, end); */ |
1 | transition-timing-function: steps(2, start); |
2、动画
动画和过渡类似,都是可以实现一些动态的效果,不同的是
- 过渡需要在某个属性发生变化时才会触发
- 动画可以自动触发动态效果
设置动画效果,必须先要设置一个关键帧,关键帧设置了动画执行每一个步骤
1 | @keyframes test { |
animation-name
指定动画的关键帧名称
animation-duration
:指定动画效果的持续时间
animation-delay
:动画效果的延迟,等待一段时间后在执行动画
animation-timing-function
:动画的时序函数
animation-iteration-count
动画执行的次数
infinite
无限执行
animation-direction
指定动画运行的方向
normal
从from
向to
运行,每次都是这样,默认值reverse
从to
向from
运行,每次都是这样alternate
从from
向to
运行,重复执行动画时反向执行alternate-reverse
从to
向from
运行,重复执行动画时反向执行
animation-play-state
设置动画的执行状态
running
动画执行,默认值paused
动画暂停
animation-fill-mode
动画的填充模式
none
动画执行完毕,元素回到原来位置,默认值forwards
动画执行完毕,元素会停止在动画结束的位置backwards
动画延时等待时,元素就会处于开始位置both
结合了forwards
和backwards
示例
1 | /* animation-name: test; |
3、实战
米兔
1 | .box { |
奔跑的少年
1 | .box { |
弹力球
1 | .outer { |
酷炫球
1 | div { |
变形:平移、旋转与缩放
变形就是指通过 css 来改变元素的形状或位置
变形不会影响到页面的布局
transform
用来设置元素的变形效果
1、平移
translateX()
沿着由方向平移translateY()
沿着 y 轴方向平移translateZ()
沿着 z 轴方向平移平移元素
百分比是相对于自身计算的
几种水平垂直双方向居中的方式对比
-
绝对定位的方式
1
2
3
4
5
6
7/* 这种居中方式,只适用于元素的大小确定 */
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto; -
table-cell
的方式1
2
3
4/* table-cell的方式具有一定局限性 */
display: table-cell;
vertical-align: middle;
text-align: center; -
transform
的方式1
2
3
4
5/* transform变形平移的方式 */
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
浮出效果
1 | div { |
2、Z 轴平移
z 轴平移,调整元素在 z 轴的位置,正常情况就是调整元素和人眼之间的距离,距离越大,元素离人越近
z 轴平移属于立体效果(近大远小),默认情况下网页是不支持透视,如果需要看见效果必须要设置网页的视距
透视效果
1 | html { |
3、旋转
通过旋转可以使元素沿着 x、y 或 z 旋转指定的角度
rotateX()
rotateY()
rotateZ()
1 | /* transform: rotateY(0.5turn); */ |
4、缩放
对元素进行缩放的函数
scalex()
水平方向缩放scaleY()
垂直方向缩放scale()
双方向的缩放
1 | .box { |
5、实战
鸭子表
html 代码
1 | <div class="clock"> |
css 代码
1 | .clock { |
复仇者联盟
html 代码
1 | <div class="cube"> |
css 代码
1 | html { |
less 简介
less
是一门css
的预处理语言
less
是一个 css 的增强版,通过less
可以编写更少的代码实现更强大的样式- 在
less
中添加了许多的新特性:像对变量的支持、对mixin
的支持… less
的语法大体上和css
语法一致,但是less
中增添了许多对css
的扩展,所以浏览器无法直接执行less
代码,要执行必须向将less
转换为css
,然后再由浏览器执行
1、安装插件
在vscode
中搜索less
,点击安装
2、编写 less
html 代码
使用快捷方式创建html
代码
回车
生成html
代码
1 | <div class="box1"></div> |
less 代码
创建style.less
文件,编写less
代码
1 | body { |
Easy LESS
插件会帮助我们在style.less
所在目录下面生成一个相同名称的css
文件
查看生成的style.css
代码
1 | body { |
我们直接在 HTML 中引入生成的style.css
1 | <link rel="stylesheet" href="/css/style.css" /> |
运行代码,查看效果
3、less 语法
less 注释
less
中的单行注释,注释中的内容不会被解析到css
中
css
中的注释,内容会被解析到css
文件中
1 | // `less`中的单行注释,注释中的内容不会被解析到`css`中 |
父子关系嵌套
在less
中,父子关系可以直接嵌套
1 | // `less`中的单行注释,注释中的内容不会被解析到`css`中 |
对应的css
1 | /* |
变量
变量,在变量中可以存储一个任意的值
并且我们可以在需要时,任意的修改变量中的值
变量的语法:@变量名
- 直接使用使用变量时,则以
@变量名
的形式使用即可 - 作为类名、属性名或者一部分值使用时,必须以
@{变量名}
的形式使用 - 可以在变量声明前就使用变量(可以但不建议)
1 | @b1:box1; |
生成的css
代码
1 | .box1 { |
注意:在url
中使用less
语法需要用引号包裹
其他
1 | .p1 { |
生成的css
代码
1 | .p1, |
&
拼接- 伪元素
:extend()
对当前选择器扩展指定选择器的样式(选择器分组).p1()
直接对指定的样式进行引用,这里就相当于将p1
的样式在这里进行了复制(mixin
混合)- 使用类选择器时可以在选择器后边添加一个括号,这时我们实际上就创建了一个
mixins
混合函数
4、混合函数
在混合函数中可以直接设置变量,并且可以指定默认值
1 | .test(@w:200px, @h:100px, @bc:red) { |
生成的css
代码
1 | .p6 { |
其他
-
average
混合函数1
2
3.h1 {
color: average(red, yellow);
}生成的
css
代码1
2
3.h1 {
color: #ff8000;
} -
darken
混合函数1
2
3body {
background-color: darken(#bfa, 50%);
}生成的
css
代码1
2
3body {
background-color: #22aa00;
}
5、补充
创建all.less
文件,将我们之前编写的less
文件通过@import
引入进来
可以通过import
来将其他的less
引入到当前的less
中
1 | @import "style.less"; |
查看生成的all.css
代码,会发现其他的内容囊括了两个less
文件的内容
所以,我们可以利用@import
来对less
文件进行整合,然后引入生成的css
文件使用即可
这样,每次修改的时候直接对某个模块的less
文件进行修改,就会非常简单
如果我们观察过之前fontawesome
源码文件,会发现其中也有less
代码文件
不同的less
文件里都有其自己的职责
,如
_animated.less
中专门存放动画的混合函数_variables.less
中专门存放定义的变量- …
但是也有个问题,通过F12
调试时显示的也是css
中对应的行号
如果我们要改,需要找一下,太麻烦了,能不能直接显示less
中行号呢?这样我们直接定位到对应less
中直接进行修改,维护起来也会比较方便
我们需要在Easy LESS
插件中修改settings.json
文件,在其中添加如下配置
1 | "less.compile": { |
修改完毕后,会发现多生成出来一个all.css.map
文件,说明配置生效
再刷新下页面,通过F12
会发现变成了less
文件对应的行号
我们来逐一解释下配置的less.compile
项中每一个属性的含义
compress
生成的css
文件代码会被压缩(作用相当于我们之前安装的JS & CSS Minifier (Minify)
插件的效果)sourceMap
生成.css.map
文件,通过F12
可以查看了less
文件对应行号out
生成对应css
文件(当然是需要了)
弹性盒简介
1、基本概念
弹性盒
flex
(弹性盒、伸缩盒)
- 是
css
中的又一种布局手段,它主要用来代替浮动来完成页面的布局 flex
可以使元素具有弹性,让元素可以跟随页面的大小的改变而改变
弹性容器
要使用弹性盒,必须先将一个元素设置为弹性容器
我们通过display
来设置弹性容器
display:flex
设置为块级弹性容器display:inline-flex
设置为行内的弹性容器
1 | /* 设置弹性容器 */ |
弹性元素
弹性容器的子元素是弹性元素(弹性项)
弹性元素可以同时是弹性容器
2、弹性容器的属性
主轴与侧轴
- 主轴:弹性元素的排列方向称为主轴
- 侧轴:与主轴垂直方向的称为侧轴
主轴属性
排列方式
flex-direction
指定容器中弹性元素的排列方式
row
默认值,弹性元素在容器中水平排列(自左向右)row-reverse
弹性元素在容器中反向水平排列(自右向左)column
弹性元素纵向排列(自上向下)column-reverse
弹性元素反向纵向排列(自下向上)
1 | /* 设置弹性元素排列方式 */ |
自动换行
flex-wrap
设置弹性元素是否在弹性容器中自动换行
nowrap
默认值,元素不会自动换行wrap
元素沿着辅轴方向自动换行
1 | /* 设置弹性元素排列方式 */ |
简写属性
flex-flow
是wrap
和direction
的简写属性
1 | /* 简写属性 */ |
空白空间
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 | justify-content: center; |
3、弹性元素的属性
伸展系数
flex-grow
指定弹性元素的伸展系数,默认值为 0
- 当父元素有多余空间的时,子元素如何伸展
- 父元素的剩余空间,会按照比例进行分配
1 | li:nth-child(1) { |
缩减系数
flex-shrink
指定弹性元素的收缩系数,默认值为 1
- 当父元素中的空间不足以容纳所有的子元素时,如何对子元素进行收缩
- 缩减系数的计算方式比较复杂,缩减多少是根据 缩减系数 和 元素大小 来计算
1 | li:nth-child(1) { |
基础长度
flex-basis
指定的是元素在主轴上的基础长度
- 如果主轴是横向的,则该值指定的就是元素的宽度
- 如果主轴是纵向的,则该值指定的就是元素的高度
- 默认值是
auto
,表示参考元素自身的高度或宽度 - 如果传递了一个具体的数值,则以该值为准
1 | li:nth-child(1) { |
简写属性
flex
可以设置弹性元素所有的三个样式 flex: 增长 缩减 基础
initial
:flex: 0 1 auto
auto
:flex: 1 1 auto
none
:flex: 0 0 auto
弹性元素没有弹性
排列顺序
order
决定弹性元素的排列顺序
1 | li:nth-child(1) { |
覆盖辅轴
align-self
用来覆盖当前弹性元素上的align-items
1 | li:nth-child(1) { |
像素与视口
像素
屏幕是由一个一个发光的小点构成,这一个个的小点就是像素
分辨率:1920x1080
说的就是屏幕中小点的数量
在前端开发中像素要分成两种情况讨论:css像素 和 物理像素
- 物理像素,上述所说的小点点就属于物理像素
- css像素,编写网页时,我们所用像素都是css像素
浏览器在显示网页时,需要将css像素转换为物理像素然后再呈现
一个css像素最终由几个物理像素显示,由浏览器决定:
默认情况下在pc端,一个css像素=一个物理像素
视口(viewport)
视口就是屏幕中用来显示网页的区域
可以通过查看视口的大小,来观察css像素和物理像素的比值
默认情况下的视口宽度
1920px
(css像素)1920px
(物理像素)- 此时,css像素和物理像素的比是
1:2
放大两倍的视口宽度
960px
(CSS像素)1920px
(物理像素)- 此时,css像素和物理像素的比是
1:2
我们可以通过改变视口的大小,来改变css像素和物理像素的比值
手机像素
在不同的屏幕,单位像素的大小是不同的,像素越小屏幕会越清晰
设备 | 尺寸 | 分辨率 |
---|---|---|
PC | 24寸 | 1920×1080 |
iPhone 6 | 4.7寸 | 750×1334 |
智能手机的像素点远远小于计算机的像素点
问题:一个宽度为900px的网页在iPhone6中要如何显示呢?
默认情况下,移动端的网页都会将视口设置为980像素(css像素),以确保pc端网页可以在移动端正常访问
但是如果网页的宽度超过了980像素,移动端的浏览器会自动对网页缩放以完整显示网页
所以基本大部分的pc端网站都可以在移动端中正常浏览,但是往往都不会有一个好的体验
为了解决这个问题,大部分网站都会专门为移动端设计网页
完美视口
移动端默认的视口大小是980px(css像素),默认情况下,移动端的像素比就是980/移动端宽度(980/750)
如果我们直接在网页中编写移动端代码,这样在980的视口下,像素比是非常不好,导致网页中的内容非常非常的小
编写移动页面时,必须要确保有一个比较合理的像素比:
- 1个css像素对应2个物理像素
- 1个css像素对应3个物理像素
可以通过meta
标签来设置视口大小
1 | <meta name="viewport" content="width=375px" /> |
每一款移动设备设计时,都会有一个最佳的像素比,一般我们只需要将像素比设置为该值,即可得到一个最佳效果
将像素比设置为最佳像素比的视口大小我们称其为完美视口
1 | <-- 将网页的视口设置为完美视口 --> |
结论:以后再写移动端的页面,就把上边这个玩意先写上
vw单位
不同的设备完美视口的大小是不一样的
- iphone6 – 375
- iphone6 plus – 414
由于不同设备视口和像素比不同,所以同样的375个像素在不同的设备下意义是不一样
比如在iphone6中375就是全屏,而到了plus中375就会缺一块
所以在移动端开发时,就不能再使用px
来进行布局了
vw
vw
表示的是视口的宽度(viewport width)
100vw = 一个视口的宽度
1vw = 1%视口宽度
vw
这个单位永远相当于视口宽度进行计算
常见的设计图宽度
750px
375px X 2
1125px
375px X 3
设计图
750px
使用vw作为单位
100vw
创建一个48px × 35px
大小的元素
100vw=750px
(设计图的像素)0.1333333333333333vw=1px
6.4vw=48px
4.667VW=35px
vw适配
rem
1rem = 1个html的字体大小
网页中字体大小最小是12px
,不能设置一个比12像素还小的字体
如果我们设置了一个小于12px
的字体,则字体自动设置为12
媒体查询
响应式布局
- 网页可以根据不通的设备或窗口大小呈现出不同的效果
- 使用 响应式布局,可以使一个网页适用于所有设备
- 响应布局的关键就是 媒体查询
- 通过媒体查询,可以为不同的设备,或设备不同状态来分别设置样式
媒体查询
媒体查询语法
@media查询规则{}
媒体类型
all
所有设备print
打印设备screen
带屏幕的设备speech
屏幕阅读器
可以使用,
连接多个媒体类型,这样它们之间就是一个或的关系
可以在媒体类型前添加一个only
,表示只有。only
的使用主要是为了兼容一些老版本浏览器
媒体特性
width
视口的宽度height
视口的高度min-width
视口的最小宽度(视口大于指定宽度时生效)max-width
视口的最大宽度(视口小于指定宽度时生效)
断点
样式切换的分界点,我们称其为断点,也就是网页的样式会在这个点时发生变化一般比较常用的断点
范围(px) | 类型(屏幕) | 写法(媒体特性) |
---|---|---|
小于768 | 超小屏幕 | max-width=768px |
大于768 | 小屏幕 | min-width=768px |
大于992 | 中型屏幕 | min-width=992px |
大于1260 | 大屏幕 | min-width=1200px |
示例
当屏幕宽度为500px和700px之间时,背景色变为#bfa
1 | @media only screen and (min-width:500px) and (max-width:700px) { |