HTML+CSS入到到精通

一、前端简介

1、软件的分类

1.1、 系统软件

  • Windows

  • Linux

  • macOS

1.2、 应用软件

  • Office

  • QQ

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、 浏览器和网页

有了浏览器我们只需要一个网址便可以访问任何的网站。

而浏览器中所显示的内容正是我们所说的网页。

网页原本的样子:

...
<!--无障碍占位-->
<div id="J_accessibility"></div>
<!--顶通占位 -->
<div id="J_promotional-top"></div>
<div id="shortcut">
  <div class="w">
    <ul class="fl" clstag="h|keycount|head|topbar_01">
      <li class="dropdown" id="ttbar-mycity"></li>
    </ul>

    <ul class="fr">
      <li
        class="fore1 dropdown"
        id="ttbar-login"
        clstag="h|keycount|head|topbar_02"
      >
        <a
          href="//passport.jd.com/uc/login?ReturnUrl=https%3A%2F%2Fwww.jd.com%2F"
          class="link-login"
          >你好,请登录</a
        >&nbsp;&nbsp;<a
          href="//reg.jd.com/reg/person?ReturnUrl=https%3A//www.jd.com/"
          class="link-regist style-red"
          >免费注册</a
        >
      </li>
      <li class="spacer"></li>
      <li class="fore2" clstag="h|keycount|head|topbar_03">
        <div class="dt">
          <a target="_blank" href="//order.jd.com/center/list.action"
            >我的订单</a
          >
        </div>
      </li>
      <li class="spacer"></li>
      <li
        class="fore3 dropdown"
        id="ttbar-myjd"
        clstag="h|keycount|head|topbar_04"
      >
        <div class="dt cw-icon">
          <a target="_blank" href="//home.jd.com/">我的京东</a
          ><i class="iconfont">&#xe610;</i><i class="ci-right"><s>◇</s></i>
        </div>
        <div class="dd dropdown-layer"></div>
      </li>
      <li class="spacer"></li>
      <li class="fore4" clstag="h|keycount|head|topbar_05">
        <div class="dt">
          <a target="_blank" href="//vip.jd.com/">京东会员</a>
        </div>
      </li>
      <li class="spacer"></li>
      <li class="fore5" clstag="h|keycount|head|topbar_06">
        <div class="dt"><a target="_blank" href="//b.jd.com/">企业采购</a></div>
      </li>
      <li class="spacer"></li>
      <li
        class="fore8 dropdown"
        id="ttbar-serv"
        clstag="h|keycount|head|topbar_07"
      >
        <div class="dt cw-icon">
          客户服务<i class="iconfont">&#xe610;</i
          ><i class="ci-right"><s>◇</s></i>
        </div>
        <div class="dd dropdown-layer"></div>
      </li>
      <li class="spacer"></li>
      <li
        class="fore9 dropdown"
        id="ttbar-navs"
        clstag="h|keycount|head|topbar_08"
      >
        <div class="dt cw-icon">
          网站导航<i class="iconfont">&#xe610;</i
          ><i class="ci-right"><s>◇</s></i>
        </div>
        <div class="dd dropdown-layer"></div>
      </li>
      <li class="spacer"></li>
      <li
        class="fore10 mobile"
        id="J_mobile"
        clstag="h|keycount|head|topbar_09"
      >
        <div class="dt mobile_txt">手机京东</div>
        <div class="mobile_static">
          <div class="mobile_static_qrcode"></div>
        </div>
        <div id="J_mobile_pop" class="mod_loading mobile_pop"></div>
      </li>
    </ul>
  </div>
</div>
...

浏览器渲染后的样子:

前端工程师负责编写网页的源代码。

浏览器负责将网页渲染成我们想要的样子。

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)

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

<!-- html5的文档声明 -->
<!doctype html>
<!-- 或者 -->
<!DOCTYPE html>

6.3、字符编码

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

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

编码

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

解码

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

字符集(charset)

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

乱码

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

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

<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 的基本结构

<!-- 文档声明,声明当前网页的版本 -->
<!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>

 

二、前端开发准备

1、离线文档的下载

离线文档:Zeal - Offline Documentation Browser

这里需要注意:如果你是Mac系统那么你要下载:Dash文档

如果安装报错,需安装: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 等

官方地址:notepad-plus-plus.org

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

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

Error: connect ECONNREFUSED 127.0.0.1:80
	at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1146:16)

解决方式:取消使用代理,修改 enable 为 false(这里我一直以为是 live-server 服务器本身的代理端口)。live-server 默认使用 5500 端口

实际上,配置端口要在Live Server › Settings: Port选项进行设置

自定义端口号

按照上述说明,点击在settings.json中编辑会打开settings.json文件

这里如果将liveServer.settings.port配置为 0,会随机选择端口号

三、字符实体与语义标签

1、字符实体

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

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

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

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

实体名称 显示结果 描述
&nbsp;   空格
&gt; > 大于号
&lt; < 小于号
&amp; &
&copy; © 版权
&reg; ® 注册商标
&trade; 商标
&times; × 乘号
&divide; ÷ 除号
&iquest; ¿ 倒问号

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

2、meta标签

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

<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:表示网站的描述信息

  • content :指定的数据的内容,会作为搜索结果的超链接上的文字显示

打开 Zeal 手册(前端开发准备中做过介绍)

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

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 头所能提供的信息。

点击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 中

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

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

3、语义标签

在网页中 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>不属于语义标签

举例

<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属性,将日期翻译成机器可读的格式,以便获得更好的搜索引擎结果或自定义功能。如提醒

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

4、块元素与行内元素

块元素(block element)

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

行内元素(inline element)

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

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

    • <p>元素中不能放任何的块元素,如果你放了也不会报错!

5、内容修正

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

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

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

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

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

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

6、布局标签

结构化语义标签

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

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

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

  • nav表示网页中的导航

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

  • article表示一个独立的文章

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

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

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

7、列表

在 html 中可以创建列表,html 列表一共有三种:

  • 有序列表,使用ol标签来创建有序列表,使用li表示列表项

    <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表示列表项

    <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来对内容进行解释说明

<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:下载图片

<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>

效果

内部地址

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

  • ./ 表示当前文件所在目录,可以省略不写

  • ../表示当前文件所在目录的上一级目录

<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在新建页面中打开超链接

<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属性值(唯一不重复)

这里的数据还可以通过:lorem + tab 这个实现随机的生成英文段落!

<p>汉皇重色思倾国,御宇多年求不得。</p>
<p>杨家有女初长成,养在深闺人未识。</p>
<p>天生丽质难自弃,一朝选在君王侧。</p>
<p><a id="Anchor1" href="#Anchor2"> 回眸一笑百媚生,六宫粉黛无颜色。</a></p>
<p>春寒赐浴华清池,温泉水滑洗凝脂。</p>
<p>侍儿扶起娇无力,始是新承恩泽时。</p>
<p>云鬓花颜金步摇,芙蓉帐暖度春宵。</p>
<p>春宵苦短日高起,从此君王不早朝。</p>
<p>承欢侍宴无闲暇,春从春游夜专夜。</p>
<p><a id="Anchor2" href="#Anchor3"> 后宫佳丽三千人,三千宠爱在一身。</a></p>
<p>金屋妆成娇侍夜,玉楼宴罢醉和春。</p>
<p>姊妹弟兄皆列土,可怜光彩生门户。</p>
<p>遂令天下父母心,不重生男重生女。</p>
<p>骊宫高处入青云,仙乐风飘处处闻。</p>
<p>缓歌慢舞凝丝竹,尽日君王看不足。</p>
<p>渔阳鼙鼓动地来,惊破霓裳羽衣曲。</p>
<p>九重城阙烟尘生,千乘万骑西南行。</p>
<p>翠华摇摇行复止,西出都门百余里。</p>
<p>六军不发无奈何,宛转蛾眉马前死。</p>
<p>花钿委地无人收,翠翘金雀玉搔头。</p>
<p>君王掩面救不得,回看血泪相和流。</p>
<p>黄埃散漫风萧索,云栈萦纡登剑阁。</p>
<p>峨嵋山下少人行,旌旗无光日色薄。</p>
<p>蜀江水碧蜀山青,圣主朝朝暮暮情。</p>
<p>行宫见月伤心色,夜雨闻铃肠断声。</p>
<p>天旋地转回龙驭,到此踌躇不能去。</p>
<p>马嵬坡下泥土中,不见玉颜空死处。</p>
<p>君臣相顾尽沾衣,东望都门信马归。</p>
<p>归来池苑皆依旧,太液芙蓉未央柳。</p>
<p>芙蓉如面柳如眉,对此如何不泪垂。</p>
<p>春风桃李花开夜,秋雨梧桐叶落时。</p>
<p>西宫南苑多秋草,落叶满阶红不扫。</p>
<p>梨园弟子白发新,椒房阿监青娥老。</p>
<p>夕殿萤飞思悄然,孤灯挑尽未成眠。</p>
<p><a id="Anchor3" href="#Anchor4"> 迟迟钟鼓初长夜,耿耿星河欲曙天。 </a></p>
<p>鸳鸯瓦冷霜华重,翡翠衾寒谁与共。</p>
<p>悠悠生死别经年,魂魄不曾来入梦。</p>
<p>临邛道士鸿都客,能以精诚致魂魄。</p>
<p>为感君王辗转思,遂教方士殷勤觅。</p>
<p>排空驭气奔如电,升天入地求之遍。</p>
<p>上穷碧落下黄泉,两处茫茫皆不见。</p>
<p>忽闻海上有仙山,山在虚无缥渺间。</p>
<p>楼阁玲珑五云起,其中绰约多仙子。</p>
<p>中有一人字太真,雪肤花貌参差是。</p>
<p>金阙西厢叩玉扃,转教小玉报双成。</p>
<p>闻道汉家天子使,九华帐里梦魂惊。</p>
<p>揽衣推枕起徘徊,珠箔银屏迤逦开。</p>
<p>云鬓半偏新睡觉,花冠不整下堂来。</p>
<p><a id="Anchor4" href="#Anchor5"> 风吹仙袂飘飖举,犹似霓裳羽衣舞。 </a></p>
<p>玉容寂寞泪阑干,梨花一枝春带雨。</p>
<p>含情凝睇谢君王,一别音容两渺茫。</p>
<p>昭阳殿里恩爱绝,蓬莱宫中日月长。</p>
<p>回头下望人寰处,不见长安见尘雾。</p>
<p>惟将旧物表深情,钿合金钗寄将去。</p>
<p>钗留一股合一扇,钗擘黄金合分钿。</p>
<p>但令心似金钿坚,天上人间会相见。</p>
<p>临别殷勤重寄词,词中有誓两心知。</p>
<p>七月七日长生殿,夜半无人私语时。</p>
<p><a id="Anchor5" href="#Anchor6"> 在天愿作比翼鸟,在地愿为连理枝。 </a></p>
<p>天长地久有时尽,此恨绵绵无绝期。</p>

<!-- Heading to link to -->
<a href="#">回到顶部</a>

9、图片

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

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

属性

  • src:属性指定的是外部图片的路径(路径规则和超链接是一样的)

  • alt:图片的描述,这个描述默认情况下不会显示,有些浏览器会在图片无法加载时显示,搜索引擎会根据 alt 中的内容来识别图片

  • width:图片的宽度(单位是像素)

  • height :图片的高度(单位是像素)

  • 宽度和高度中如果只修改了一个,则另一个会等比例缩放

注意

  • 一般情况在 pc 端,不建议修改图片的大小,需要多大的图片就裁多大

  • 但是在移动端,经常需要对图片进行缩放(大图缩小)

举例

<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 编码,这样可以将图片转换为字符,通过字符的形式来引入图片图片格式的选择

<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="
/>
  • 图片效果一样的,选文件小的

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

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

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

设置完美视口,在写移动端页面的时候,优先添加!

查看不同手机、平台像素的网站:https://screensiz.es/

vw(viewport width):视口的宽度--100vw=1个视口宽度,1vw=1%视口,vw永远相对于视口宽度进行计算,移动端建议使用!

 

10、内联格式

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

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

  • frameborder指定内联框架的边框

举例

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

效果

11、音视频

音频

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

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

属性

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

  • autoplay

    音频文件是否自动播放

    • 如果设置了autoplay,则音乐在打开页面时会自动播放

    • 但是目前来讲大部分浏览器都不会自动对音乐进行播放

  • loop音乐是否循环播放

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

source

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

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

IE11 、Chrome、Edge、firefox下,能够正常播放,但是在IE8下就会报错!

embed

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

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

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

在IE8同样会报错!

视频

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

<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下可以正常使用,在IE8也可以展示!)

其他

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

<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 的支持

<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语法与选择器

1、CSS简介

层叠样式表

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

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

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

内联样式(行内样式)

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

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

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

内部样式表

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

<style>
  p{
      color:green;
      font-size:50px;
  }
</style>

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

外部样式表

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

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

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

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

2、CSS 基本语法

注释

css 中的注释

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

/* css中的单行注释 */

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

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

html 中的注释

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

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

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

JS(JavaScript)和 JQuery 中的注释

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

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

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

基本语法

选择器 声明块

选择器

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

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

声明块

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

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

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

h1 {
  color: green;
}

3、选择器

通配选择器(Universal selector)

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

  • 语法:*

  • 例子:*{}

* {
  color: red;
}

元素选择器(Type selector)

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

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

  • 语法:elementname{}

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

p {
  color: red;
}

h1 {
  color: green;
}

类选择器(Class selector)

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

  • 语法:.classname

  • 例子:.blue{}

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

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

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

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

ID 选择器(ID selector)

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

  • 语法:#idname{}

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

#red {
  color: red;
}

属性选择器(Attribute selector)

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

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

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

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

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

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

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

p[title] {
  color: orange;
}
p[title="e"] {
  color: orange;
}
p[title^="e"] {
  color: orange;
}
p[title$="e"] {
  color: orange;
}
p[title*="e"] {
  color: orange;
}

4、复合选择器

交集选择器

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

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

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

div.red {
  font-size: 30px;
}

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

并集选择器(选择器分组)

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

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

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

h1,
span {
  color: green;
}

5、关系选择器

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

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

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

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

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

子元素选择器(Child combinator)

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

  • 语法:父元素 > 子元素

  • 例子:A > B

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

后代元素选择器(Descendant combinator)

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

  • 语法:祖先 后代

  • 例子:A B

div span {
  color: skyblue;
}

兄弟元素选择器(Sibling combinator)

  • 作用:选择下一个兄弟

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

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

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

p + span {
  color: red;
}

p ~ span {
  color: red;
}

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()否定伪类,将符合条件的元素从选择器中去除

/* 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 鼠标点击的链接

/* 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;
}

7、伪元素选择器

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

伪元素使用::开头

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

  • ::first-line 表示第一行

  • ::selection 表示选中的内容

  • ::before 元素的开始

  • ::after 元素的最后

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

/* 段落首字母设置大小为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;
}

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,则此时该样式会获取到最高的优先级,甚至超过内联样式,注意:在开发中一定要慎用!

<style>
  #box1 {
    background-color: orange;
  }
  div {
    background-color: yellow;
  }
  .red {
    background-color: red;
  }
</style>

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

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,也就说 em 值会根据元素本身的字体大小的改变而改变

rem

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

例:html:100px;  = box=1rem;

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>em/rem练习</title>
        <style>
            * {
                font-size: 30px;
            }

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

            .box2 {
                width: 50%;
                height: 50%;
                background-color: purple;
            }

            .box3 {
                width: 10em;
                height: 10em;
                background-color: lightseagreen;
            }

            /*当时用rem时,不管怎么改本元素的font-size都是不会变的。需要定义root元素的font-size才可以 */
            .box4 {
                font-size: 30px;
                width: 10rem;
                height: 10rem;
                background-color: red;
            }
        </style>
    </head>
    <body>
        <div class="box1">
            <div class="box2"></div>
        </div>

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

        <div class="box4"></div>
    </body>
</html>

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

这里推荐一个mac的取色器Snipaste:https://www.macwk.com/soft/snipaste

HSL

HSL值 HSLA值

  • 色相(0~360)

  • 饱和度,颜色的浓度(0~100%)

  • 亮度,颜色的亮度(0~100%)

  • 不透明度(0~1)

六、盒模型

1、文档流(normalflow)

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

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

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

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

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

  • 在文档流中

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

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

2、块元素

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

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

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

3、行内元素

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

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

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

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

4、盒子模型

盒模型、盒子模型、框模型(box model)

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

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

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

  • 内容区(content)

  • 内边距(padding)

  • 边框(border)

  • 外边距(margin)

内容区(content)

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

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

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

  • width 设置内容区的宽度

  • height 设置内容区的高度

示例

.box1 {
  width: 200px;
  height: 200px;
  border-color: red;
  /*
  			solid 实线
  			dotted 点状虚线
  			dashed 虚线
  			double 双线
  */
  border-style: solid;
  background-color: rgb(73, 184, 139);
}

效果

边框(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 左边框的样式

效果(solid)

效果(dotted)

效果(dashed)

效果(double)

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

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

  • 四个值:上 右 下 左

  • 三个值:上 左右 下

  • 两个值:上下 左右

  • 一个值:上下左右

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

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

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

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

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

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

.box1 {
  border: 10px red solid;
}

内边距(padding)

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

  • padding-top 上内边距

  • padding-right 右内边距

  • padding-bottom下内边距

  • padding-left 左内边距

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

注意:内边距的设置会影响到盒子的大小,背景颜色会延伸到内边距上

示例

<style>
  .outer {
    width: 200px;
    height: 200px;
    border: 10px orange solid;
    background-color: pink;
    padding-right: 100px;
    padding-top: 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

.box1 {
  width: 200px;
  height: 200px;
  background-color: #bfa;
  border: 10px orange solid;

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

效果

示例 2:

.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;
}

效果

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值以使等式成立

    这七个值中有三个值可以设置为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

    3. 如果外边距都为auto,则auto的外边距会自动均分以使等式成立

      auto + 0 + 0 + 200 + 0 + 0 + auto = 600==> 300 + 0 + 0 + 200 + 0 + 0 + 300 = 800

示例

<style>
  .box1 {
    width: 200px;
    height: 200px;
    background-color: #bfa;
    border: 10px orange solid;
    /* 下列条件等价于 margin: 0 auto */
    margin-left: auto;
    margin-right: auto;
  }
</style>
<div class="box1"></div>

效果

6、垂直方向布局

元素溢出

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

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

可选值:visible/hidden/scroll/auto

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

示例

<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 溢出内容会被裁剪,不会显示

示例

<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 生成两个滚动条,通过滚动条来查看完整的内容

示例

<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>

效果

<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>

效果

边距折叠

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

兄弟元素

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

特殊情况:

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

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

示例

.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]

总结

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

父子元素

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

示例

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

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

效果

不加 margin-top

加 margin-top 

父子外边距的折叠会影响到页面的布局,必须要进行处理

处理方式 1

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

.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 属性会影响元素的大小

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

.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属性,但是给父元素加一个上边框

.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。那我们就需要手动调整父元素的高度,同时让边框颜色与父元素盒子颜色保持一致

.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 减去一个像素即可

.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 (子元素远离父元素边框)[3]

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

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

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

应该是 border 让元素脱离了文档流(margin 塌陷)

好吧好吧,至于什么是 margin 塌陷,我也是问了度娘,有兴趣的可以自行百度,这里就不再赘述了

7. 行内元素的盒模型

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

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

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

    .s1 {
      /* 下方的div元素并没有因span设置了padding属性,而受到位置上的影响 */
      padding: 100px;
      background-color: yellow;
    }
    
    .box1 {
      width: 200px;
      height: 200px;
      background-color: #bfa;
    }

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

    .s1 {
      border: 10px orange solid;
      background-color: yellow;
    }
    
    .box1 {
      width: 200px;
      height: 200px;
      background-color: #bfa;
    }

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

    .s1 {
      margin: 100px;
      background-color: yellow;
    }
    
    .box1 {
      width: 200px;
      height: 200px;
      background-color: #bfa;
    }

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

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

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

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

  • block将元素设置为块元素

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

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

    .s1 {
      margin: 100px;
      background-color: yellow;
      /* 将行内元素设置为行内块元素,兼顾行内元素和块元素的特点 */
      display: inline-block;
    }

  • table将元素设置为一个表格

  • none元素不在页面中显示

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

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

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

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

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

    .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 的一些声明和属性。

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

示例

html 代码

<div class="box1"></div>
<p>我是一个段落</p>
<p>我是一个段落</p>
<p>我是一个段落</p>
<ul>
<1i>列表项1</1i>
<1i>列表项2</1i>
<1i>列表项3</1i>
</ul>

css 代码

.box1 {
  width: 100px;
  height: 100px;
  border: 1px solid black;
}

效果

F12 看盒子默认样式

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

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

去除默认样式

  1. 去除与浏览器的边缘间距

    body {
      margin: 0;
    }

  2. 去除段落之间行距

    p {
      margin: 0;
    }

  3. 去除列表的上下外边距和左内边距

    ul {
      margin: 0;
      padding: 0;
    }

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

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

    ul {
      margin: 0;
      padding: 0;
      margin-left: 16px;
    }

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

  4. 去除列表前的黑点

    ul {
      margin: 0;
      padding: 0;
      margin-left: 16px;
      list-style: none;
    }

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

    ul {
      margin: 0;
      padding: 0;
      /* margin-left: 16px; */
      list-style: none;
    }

     

    到这里似乎就大功告成了,但是我们会发现写法似乎 很完美 有点麻烦

    body {
      margin: 0;
    }
    
    p {
      margin: 0;
    }
    
    ul {
      margin: 0;
      padding: 0;
      list-style: none;
    }

    有没有简化空间了呢?

    答案是肯定的,我们前面介绍过通配选择器的概念,可以直接简化成一个

  5. 简化写法

    * {
      margin: 0;
      padding: 0;
      list-style: none;
    }

    效果是一样的

去除浏览器的默认样式的需求是非常普遍的,我们难道每次都需要手动去除浏览器的默认样式?

这样岂不是很麻烦,难道官方就没有想到解决方案吗?

答案也是肯定的,有!

正因为上述冲突和问题依然存在于这个”不完美的世界”,所以一些设计师想到了一种避免浏览器兼容性问题的方法,那就是 CSS Reset

什么是 CSS Reset?

我们可以把它叫做 CSS 重设,也有人叫做 CSS 复位、默认 CSS、CSS 重置等。

CSS 重设就是先定义好一些 CSS 样式,来让所有浏览器都按照同样的规则解释 CSS,这样就能避免发生这种问题。

下方两种 css 样式,我们引入其中一个即可

reset 样式

官方地址:reset.css

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

效果

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

/* 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

<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 出来,直接在地址栏进行访问

//img14.360buyimg.com/babel/s380x300_jfs/t1/168591/2/9328/64891/603ddb1aE93567699/3e4e717eeac051b2.jpg.webp
//img12.360buyimg.com/babel/s380x300_jfs/t1/152314/13/19839/57522/603e118dE941f0ce9/fdff58457adbef3e.jpg.webp
//img10.360buyimg.com/babel/s380x300_jfs/t1/154848/7/7426/82296/5fc072eeE20809200/34dca267e049d035.jpg.webp

这里就可以进行图片另存为了,当然你也可以直接在src上填写这些地址

不过,细心的同学会发现,这张图片的格式是jpg.webp .avif后缀结尾的

因为我是在谷歌浏览器中访问的,而谷歌浏览器有自己的特有的一种图片格式 webp(这个我们在第三节-字符实体与语义标签中介绍过)

当然这个格式不是谷歌自己进行转换的,而应该是京东做了不同浏览器之间的适配,即不同的浏览器传递不同格式的图片

Q:怎么验证这种说法呢?

A:我们可以打开非 Chrome 内核的浏览器,使用 F12 查看imgsrc地址就会发现不一样的地方了

这里我用微软自带的 IE 浏览器(温馨提示:微软官宣定于 2022 年 6 月 15 日完全停止对 IE 的支持)

扩展:对于AVIF格式,参考:https://zhuanlan.zhihu.com/p/444624167

对比就可以发现,无非就是在 Chrome 浏览器里后缀名多了一个.webp而已

对比就可以发现,无非就是在 Chrome 浏览器里后缀名多了一个.webp而已

<!-- IE中的src地址 -->
//img14.360buyimg.com/babel/s380x300_jfs/t1/168591/2/9328/64891/603ddb1aE93567699/3e4e717eeac051b2.jpg
<!-- Chrome中的src地址 -->
//img14.360buyimg.com/babel/s380x300_jfs/t1/168591/2/9328/64891/603ddb1aE93567699/3e4e717eeac051b2.jpg.webp

知道这个原理,我们除了可以直接在图片另存为保存为jpg格式,其实还可以直接修改 url 地址

最后,我们将下载的图片放入assets(自定义目录)工程目录下即可

布局剖析

我们使用 F12 进行调试,可以看到京东图片列表的具体元素及属性

  • 整体使用一个li元素包裹,里面又套了一层 div`元素,宽高比:190:470

  • 每张图片使用一个img元素,同时分别用a元素包裹,宽高比:190:150

  • 三张图片高度和为 1503=450 < 470,注意到图片之间存在 210px 的外边距

这样,整个京东的图片列表的整体布局就非常清晰了

但是,我们不会那么去实现代码。因为li元素应该包裹在ul元素或者ol元素中,而这里并没有遵循 css 中的语义标签使用规范

我们先看一下这么写会有什么问题

<link rel="stylesheet" href="../assets/reset.css" />
<!-- ul包裹li -->
<ul>
  <li>ul li</li>
  <li>ul li</li>
  <li>ul li</li>
</ul>
<!-- div包裹li -->
<div>
  <li>div li</li>
  <li>div li</li>
  <li>div li</li>
</div>

效果

由于使用了 reset 样式,浏览器的默认样式被我们去除了。但是使用ul包裹的li元素和使用div包裹的li元素存在明显的区别:

  • 使用ul包裹的li元素是没有默认样式的

  • 使用div包裹的li元素前仍然存在黑点

我想是因为京东在这里实现了自己的样式替换,所以为了避免重复 reset 默认样式,我们采用正常的列表标签

<ul>
  <li>
    <a href="javascript:;"><img src="assets/1.jpg" /></a>
  </li>
  <li>
    <a href="javascript:;"><img src="assets/2.jpg" /></a>
  </li>
  <li>
    <a href="javascript:;"><img src="assets/3.jpg" /></a>
  </li>
</ul>

到这里我们基本骨架已经有了,不过因为没有写 css 样式,图片几乎占据了整个浏览器页面

样式添加

方式 1

还记得上面分析对布局结构的分析吗?

我们首先调整整体的宽高比和单个图片的宽高比

ul {
  width: 190px;
  height: 470px;
}

ul > li img {
  /* 
		这里其实只调整高度即可,因为我们下载的图片宽高比跟F12中调试的是一致的
		而且一般情况下,不会固定或修改图片在网页中显示的宽高比
		因为如果我们随意调整css中的宽高比,会导致图片变形 
    	这里任意只调整高度或宽度,图片可以保持原比例大小
    */
  /* width: 190px; */
  height: 150px;
}

当然这只是其中写法,我们还可以换个思路,退一步来思考

方式 2

我们呢不去限制图片的宽或高,而是对超出ul元素部分(溢出部分)进行隐藏

ul {
  width: 190px;
  height: 470px;
  overflow: hidden;
}

但是因为图片本身的大小还没有做限制,所以图片保持了原来的图片比例和大小

小剧场:

我们发现下载下来的图片分辨率大小为 380*300,宽和高都刚好是浏览器中图片宽高的 2 倍

这只是巧合么?

不!这是京东为了高分辨率设备而做的适配,保证在一些高清屏下也能够保持清晰

那我们再对图片添加固定的宽或高不就行了?

不!我们直接指定宽或高的话,overflow属性不就显得多此一举嘛

我们给 img 元素设定一个100%width属性

ul > li img {
  /* height: 150px; */
  width: 100%;
}

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父元素是lili的父元素是ul

也就是说,由于我们没有给ali单独设置样式,因此img最终会根据ul的宽度计算

而如果只调整图片的宽或高,图片是会保持原比例进行缩放的

所以这个时候就相当于给img设置了一个width=190px的属性值

细节完善

背景色

通过颜色拾取器,识别背景色(我这里使用的是FastStone Capture中自带的Screen Color Picker

ul{
    ...
    /* 添加背景色 */
    background-color: #F4F4F4;
}

外边距

根据布局剖析结果,我们给每个li元素添加一个 10px 的下边距

ul > li {
  margin-bottom: 10px;
}
/* 
	但是上述写法有些问题,最后一张图片也有10px的外边距,有可能会影响到页面布局 
	所以我们可以指定最后一个没有外边距,可以使用之前讲到的伪类选择器
*/
ul > li:not(:last-child) {
  margin-bottom: 10px;
}

Q:为什么是给li元素添加呢?

A:我们在调整布局结构的时候,特别是设置外边距,一般是设置块元素的,而不建议去调整行内元素或行内块元素

最终效果

核心代码

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>图片列表</title>
        <link rel="stylesheet" href="../assets/style/reset.css" />
        <style>
            /* 设置body的背景颜色 */
            body {
                background-color: antiquewhite;
            }

            /* 设置外部ul的样式 */
            .img-list {
                width: 190px;
                height: 470px;
                overflow: hidden;
                /* 在实际开发中不需要写,ul居中! */
                margin: 50px auto;
                background-color: #f4f4f4;
            }

            /* 设置li的位置 */
            .img-list li:not(:last-child) {
                margin-bottom: 10px;
            }

            /* 设置图片的大小 */
            .img-list img {
                width: 100%;
            }
        </style>
    </head>
    <body>
        <ul class="img-list">
            <li>
                <a href="javascript:;"><img src="../assets/images/1.webp" /></a>
            </li>
            <li>
                <a href="javascript:;"><img src="../assets/images/2.webp" /></a>
            </li>
            <li>
                <a href="javascript:;"><img src="../assets/images/3.webp" /></a>
            </li>
        </ul>
    </body>
</html>

2、京东左侧导航条

开发准备

我们需要的就是这些文字,事先复制下来

家用电器 手机 / 运营商 / 数码 电脑 / 办公 家居 / 家具 / 家装 / 厨具 男装 / 女装
/ 童装 / 内衣 美妆 / 个护清洁 / 宠物 女鞋 / 箱包 / 钟表 / 珠宝 男鞋 / 运动 /
户外 房产 / 汽车 / 汽车用品 母婴 / 玩具乐器 食品 / 酒类 / 生鲜 / 特产 艺术 /
礼品鲜花 / 农资绿植 医药保健 / 计生情趣 图书 / 文娱 / 教育 / 电子书 机票 / 酒店
/ 旅游 / 生活 理财 / 众筹 / 白条 / 保险 安装 / 维修 / 清洗 / 二手 工业品

布局剖析

  • 整体使用ulli元素,宽高比=190px:470px,其中上下存在 10px 的内边距(影响盒子大小)和 10px 的外边距(影响盒子布局)

  • li中每个元素也比较简单,用a包裹文字,用span包裹斜杠

  • 每个li元素的宽高比=190px:25px,其中左边存在 18px 的内边距(注意右边是不存在的)

  • a 元素没有什么大的布局,span元素左右存在 2px 的内边距

结构搭建

<ul>
  <li>
    <a href="javascript:;">家用电器</a>
  </li>
  <li>
    <a href="javascript:;">手机</a>
    <span>/</span>
    <a href="javascript:;">运营商</a>
    <span>/</span>
    <a href="javascript:;">数码</a>
  </li>
  <li>
    <a href="javascript:;">电脑</a>
    <span>/</span>
    <a href="javascript:;">办公</a>
  </li>
  <li>
    <a href="javascript:;">家居</a>
    <span>/</span>
    <a href="javascript:;">家具</a>
    <span>/</span>
    <a href="javascript:;">家装</a>
    <span>/</span>
    <a href="javascript:;">厨具</a>
  </li>
  <li>
    <a href="javascript:;">男装</a>
    <span>/</span>
    <a href="javascript:;">女装</a>
    <span>/</span>
    <a href="javascript:;">童装</a>
    <span>/</span>
    <a href="javascript:;">内衣</a>
  </li>
  <li>
    <a href="javascript:;">美妆</a>
    <span>/</span>
    <a href="javascript:;">个护清洁</a>
    <span>/</span>
    <a href="javascript:;">宠物</a>
  </li>
  <li>
    <a href="javascript:;">女鞋</a>
    <span>/</span>
    <a href="javascript:;">箱包</a>
    <span>/</span>
    <a href="javascript:;">钟表</a>
    <span>/</span>
    <a href="javascript:;">珠宝</a>
  </li>
  <li>
    <a href="javascript:;">男鞋</a>
    <span>/</span>
    <a href="javascript:;">运动</a>
    <span>/</span>
    <a href="javascript:;">户外</a>
  </li>
  <li>
    <a href="javascript:;">房产</a>
    <span>/</span>
    <a href="javascript:;">汽车</a>
    <span>/</span>
    <a href="javascript:;">汽车用品</a>
  </li>
  <li>
    <a href="javascript:;">母婴</a>
    <span>/</span>
    <a href="javascript:;">玩具乐器</a>
  </li>
  <li>
    <a href="javascript:;">食品</a>
    <span>/</span>
    <a href="javascript:;">酒类</a>
    <span>/</span>
    <a href="javascript:;">生鲜</a>
    <span>/</span>
    <a href="javascript:;">特产</a>
  </li>
  <li>
    <a href="javascript:;">艺术</a>
    <span>/</span>
    <a href="javascript:;">礼品鲜花</a>
    <span>/</span>
    <a href="javascript:;">农资绿植</a>
  </li>
  <li>
    <a href="javascript:;">医药保健</a>
    <span>/</span>
    <a href="javascript:;">计生情趣</a>
  </li>
  <li>
    <a href="javascript:;">图书</a>
    <span>/</span>
    <a href="javascript:;">文娱</a>
    <span>/</span>
    <a href="javascript:;">教育</a>
    <span>/</span>
    <a href="javascript:;">电子书</a>
  </li>
  <li>
    <a href="javascript:;">机票</a>
    <span>/</span>
    <a href="javascript:;">酒店</a>
    <span>/</span>
    <a href="javascript:;">旅游</a>
    <span>/</span>
    <a href="javascript:;">生活</a>
  </li>
  <li>
    <a href="javascript:;">理财</a>
    <span>/</span>
    <a href="javascript:;">众筹</a>
    <span>/</span>
    <a href="javascript:;">白条</a>
    <span>/</span>
    <a href="javascript:;">保险</a>
  </li>
  <li>
    <a href="javascript:;">安装</a>
    <span>/</span>
    <a href="javascript:;">维修</a>
    <span>/</span>
    <a href="javascript:;">清洗</a>
    <span>/</span>
    <a href="javascript:;">二手</a>
  </li>
  <li>
    <a href="javascript:;">工业品</a>
  </li>
</ul>

我们引入reset.css样式来去除浏览器的默认样式

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

到这里,基本的骨架就有了

Q:那有些人会问了,我们不是引入了reset.css重置了浏览器的默认样式吗?为什么超链接还有样式?

A:其实,如果仔细看 reset.css 的源代码,会发现a元素只是重置了一些基本的内外边距、边框和字体大小,并没有做完全把a元素的样式去除。这个下面会具体介绍

样式添加

根据布局剖析,我们可以直接设置整体的样式

body {
  /* 这里顺便添加下背景色,通过颜色拾取器识别 */
  background-color: #f4f4f4;
}

ul {
  /* 宽高 */
  width: 190px;
  height: 450px;
  /* 内外边距 */
  padding: 10px 0;
  margin: 10px auto;
  /* 处理溢出部分 */
  overflow: hidden;
  /* 这里顺便添加下背景色,通过颜色拾取器识别 */
  background-color: #fefefe;
}

ul > li {
  /* 宽高,根据继承关系可以不写宽度 */
  height: 25px;
  /* 内外边距,这里只有一个内边距 */
  padding-left: 18px;
  /* 设置背景色:不是必须的,这里只是为了发现一些问题 */
  background-color: #bfa;
}

ul > li span {
  /* 内外边距*/
  padding: 0 2px;
}

到这里整体样式就添加完毕,但我们发现有点问题

别急!我们继续进行细节上的样式调整和优化

细节完善

要求效果

目前的效果

两个主要问题

  1. 要求效果文字居中显示,而我们的文字偏左上角,底部有一定间距

  2. 文字存在换行和重叠现象

我们一个一个处理

文字调整

只需要给li元素添加一行属性

line-height: 25px;

文字虽然在一行上了,但是依然有重叠问题啊,需要怎么处理呢?

要知道文字有几个属性:

  • 文字大小

  • 文字颜色

  • 文字样式

我们通过 F12 看下这些属性

废话少说,直接写代码

font-size: 14px;
color: #333;

我们这里先不写text-decoration属性,看下效果

写上text-decoration属性,再看下效果

text-decoration: none;

这里可以看到文字下划线消失了,因为我们使用的a标签包裹文字,而超链接具有一定的文字样式(就是蓝色字体带下划线),所以text-decoration属性就是调整文字样式的

到这里,我们的重叠问题还是没有解决

稳住,我们能赢! 我们再对比下要求的效果和我们现在的效果

看出来区别了吗?(当然重点不是我们的背景色,这无关紧要)

我们是把/符号用span包裹起来的,但是我们的/符号似乎又大又粗

符号调整

废话少说,上代码

ul > li span {
  padding: 0 2px;
  /* 调整符号字体大小 */
  font-size: 12px;
}

不过到这里,还是存在问题,我把span元素的内边距去除才可以 (这里我没搞清楚为什么,知道的小伙伴可以评论或私信我哦;不过对比各个元素的盒子模型没什么区别,而且字体样式我也调整了;而且总感觉/符号之间间隙大了一点,这里存疑先不管了,我们继续往下)

悬浮样式

我们注意到,当鼠标悬浮在某一行时,其背景颜色会有变化;同时,悬浮在某一个超链接上时,字体颜色变红

这里要用到一个伪类选择器:hover,我们还是直接上代码

ul > li {
  height: 25px;
  padding-left: 18px;
  /* background-color: #bfa; 同时注释掉之前的一个辅助我们查看问题的背景色 */
  line-height: 25px;
}
/* 悬浮在某一行时,其背景颜色会有变化 */
ul > li:hover {
  background-color: #d9d9d9;
}
/* 悬浮在某一个超链接上时,字体颜色变红 */
ul > li a:hover {
  color: #c81724;
}

至此,我们的京东左侧导航栏的前端样式就基本完成了

最终效果

核心代码

<link rel="stylesheet" href="css/reset.css" />
<style>
  body {
    /* body背景色,通过颜色拾取器识别 */
    background-color: #f4f4f4;
  }

  ul {
    /* 整体宽高 */
    width: 190px;
    height: 450px;
    /* 整体内外边距 */
    padding: 10px 0;
    margin: 10px auto;
    /* 处理溢出部分 */
    overflow: hidden;
    /* 整体背景色,通过颜色拾取器识别 */
    background-color: #fefefe;
  }

  ul > li {
    /* 每行宽高 */
    height: 25px;
    padding-left: 18px;
    /* 每行行高 */
    line-height: 25px;
  }

  ul > li:hover {
    /* 悬浮背景色 */
    background-color: #d9d9d9;
  }

  ul > li a {
    /* 字体大小、颜色、样式 */
    font-size: 14px;
    color: #333;
    text-decoration: none;
  }

  ul > li a:hover {
    /* 悬浮字体颜色 */
    color: #c81724;
  }

  ul > li span {
    /* 内边距,应该是有的,但是有点问题 */
    /* padding: 0 2px; */
    font-size: 12px;
  }
</style>

存疑问题

通过一番折腾和研究,终于发现问题的关键所在

因为在编写 HTML 代码时,每个li元素中的aspan标签都是换行的

而 HTML 中会将多个空格合并成一个,所以aspan之间都多了一个空格

有几种解决这个问题的方式

  • 一是调整 HTML 中每个li元素中的代码,使之在一行上

  • 二是给 ul 元素或 li 元素设置一个font-size: 0的属性值

  • 三是通过 js 去除多余的换行字符(目前还没有学习到,所以不用这种方式,而且较麻烦)

我这里采用第二种方式

ul > li {
  height: 25px;
  padding-left: 18px;
  line-height: 25px;
  /* 设置font-size */
  font-size: 0;
}

ul > li span {
  /* 设置内边距 */
  padding: 0 2px;
  font-size: 12px;
}

到这里,我们往往会忍不住赞叹一下自己:Nice !

3、网易新闻列表

有了上面的实战步骤,对于网易新闻列表,我们就不进行那么详细的剖析了,直接上代码

结构搭建

/* ====================整体==================== */
.news_money {
  /* 整体布局 */
  width: 300px;
  height: 324px;
  margin: 35px auto;
}

a {
  /* 去除超链接样式 */
  text-decoration: none;
}

/* ====================标题==================== */
.news_title {
  height: 40px;
  border-top: 1px #ddeedd solid;
}

.news_title .title {
  /* 标题整体布局 */
  width: 32px;
  height: 24px;
  line-height: 24px;
  padding-top: 6px;
  border-top: 1px #f34540 solid;
  margin-top: -1px;
}

.news_title a {
  /* 标题字体样式 */
  font-size: 16px;
  font-weight: bold;
  color: #404040;
}

.news_title a:hover {
  /* 标题悬浮样式 */
  color: red;
}

/* ====================图片==================== */
.new_img {
  height: 150px;
}

.news_img:hover {
  /* 
    	图片悬浮样式
    	这部分知识还没有学习到,所以只是做了一个简单的放大效果
    	但现在的效果其实是不对的,标题文字也被放大了
    */
  transform: scale(2);
}

/* 图片标题 */
.news_img .img_title {
  /* 图片标题整体布局 */
  height: 40px;
  line-height: 40px;
  margin-top: -40px;
  padding-left: 30px;
}

.news_img a {
  /* 图片标题字体样式 */
  color: #fff;
  font-weight: bold;
}

/* ====================新闻列表==================== */
.news_list {
  height: 120px;
  margin-top: 12px;
}

.news_list li {
  /* 新闻列表整体布局 */
  width: 285px;
  height: 30px;
  line-height: 30px;
  padding-left: 15px;
}

.news_list a {
  /* 新闻列表字体样式 */
  font-size: 14px;
  color: #666;
}

.news_list a:hover {
  /* 新闻列表悬浮样式 */
  color: red;
}

效果:

七、盒模型补充

1、盒子大小

默认情况下,盒子可见框的大小由内容区、内边距和边框共同决定

box-sizing用来设置盒子尺寸的计算方式(设置 width 和 height 的作用)

.box1 {
    width: 100px;
    height: 100px;
    padding: 10px;
    background-color: orange;
    border: 10px solid red;
    /* box-sizing: content-box; */
    box-sizing: border-box;
}

可选值:

  • content-box默认值,宽度和高度用来设置内容区的大小

  • border-box 宽度和高度用来设置整个盒子可见框的大小

widthheight指的是内容区、内边距和边框的总大小

2、轮廓

outline用来设置元素的轮廓线,用法和border一模一样

轮廓和边框不同点是,轮廓不会影响到可见框的大小

边框

.box {
  width: 200px;
  height: 200px;
  background-color: orange;
  border: 10px red solid;
}

 

轮廓

.box {
  width: 200px;
  height: 200px;
  background-color: orange;
  outline: 10px red solid;
}

可以很明显看到outlineborder的区别

我们一般不会直接这么设置轮廓,而是下面这种场景

.box:hover {
  outline: 10px red solid;
}

从上面的动态图也可以很清晰地看出,outline属性并没有改变盒子的布局

3、阴影

box-shadow属性用于在一个元素的框架周围添加阴影效果

你可以设置多个由逗号分隔的效果

一个盒状阴影由相对于元素的 X 和 Y 的偏移量、模糊和扩散半径以及颜色来描述

box-shadow用来设置元素的阴影效果,阴影不会影响页面布局

.box {
  width: 200px;
  height: 200px;
  background-color: yellow;
  box-shadow: 10px 10px orange;
}

box-shadow: 10px 10px 5px orange;

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

border-radius: 20px;

border-top-right-radius: 50px 100px;

border-radius 可以分别指定四个角的圆角

  • 四个值:左上 右上 右下 左下

  • 三个值:左上 右上/左下 右下

  • 两个值:左上/右下 右上/左下

  • 一个值:左上/右上/右下/左下

这里同样不需要死记硬背,只要记住遵循顺时针方向和矩形中心点对称原则

border不同的是,border是从开始顺时针设置,而圆角是从左上开始

原理很简单,就是绘制正方形,并将四个圆角半径设置为正方形的一半

.box {
  width: 200px;
  height: 200px;
  background-color: yellow;
  border-radius: 50%;
}

椭圆

只需要对上述样式对一点点的改动,设置widthheight属性不相等即可

.box {
  width: 300px;
  height: 200px;
  background-color: yellow;
  border-radius: 50%;
}

 

八、浮动

1、浮动的简介

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

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

  • none 默认值,元素不浮动

  • left 元素向左浮动

  • right 元素向右浮动

注意

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

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

也可以参考:https://www.cnblogs.com/zhaostudy/p/16558751.html

2、浮动的特点

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

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

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

<style>
  .box1 {
    width: 100px;
    height: 100px;
    background-color: orange;
    float: left;
	}

  .box2 {
    width: 200px;
    height: 200px;
    background-color: yellowgreen;
  }
</style>
<body>
    <div class="box1"></div>
    <div class="box2"></div>
</body>

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

<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. 浮动元素不会超过上边的浮动的兄弟元素,最多就是和它一样高

<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. 如果浮动元素的上边是一个没有浮动的块元素,则浮动元素无法上移

<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. 浮动元素不会盖住文字,文字会自动环绕在浮动元素的周围,所以我们可以利用浮动来设置文字环绕图片的效果

简单总结:

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

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

3、脱离文档流的特点

块元素:

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

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

<style>
  .box1 {
    background-color: orange;
    /* float: left; */
  }
</style>

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

行内元素:

  • 行内元素脱离文档流以后会,特点和块元素一样

<style>
  span {
    width: 200px;
    height: 200px;
    background-color: orange;
    float: left;
  }
</style>

<span>I am a Span</span>

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

<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>

4、简单布局

整体样式

目的

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

  2. 公共 css 部分复用

  3. 复习语义标签

代码

html 代码

<!-- 页眉 -->
<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代码

/* 公共部分 */
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;
}

效果

5、练习:w3school 导航条

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

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

css 样式

/* 去除默认样式 */
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 代码

<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

1、高度塌陷

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

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

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

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

别急,我们接着往下看

2、BFC

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

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

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

元素开启 BFC 后的特点:

  • 不会被浮动元素覆盖

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

  • 可以包含浮动的元素

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

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

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

    动画2021-39

  • 设置overflow为非visible值:既没有覆盖元素,也保持了独占一方的特性(保持了宽度),与下方元素也保持了最初的间隙

    常用的方式为元素设置overflow:hiddenoverflow:auto也是 ok 的) 开启其 BFC, 以使其可以包含浮动元素

    overflow:scroll 会有滚动条,可能并不需要的,所以不太推荐

    动画2021-38

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

总结

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

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

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

我们可以打开Zeal/Dash手册(《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不为visibleclip的块元素
display: flow-root  
contain: layout contain: content contain: paint  
display: flex display: inline-flex的直接子元素 Flex 项,如果它们本身既不是flex,也不是gridtable容器
display: grid display: inline-grid的直接子元素 Grid 项,如果它们本身既不是flex,也不是gridtable容器
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 中的两大难题

.clearfix::before,
.clearfix::after {
  content: "";
  display: table;
  clear: both;
}

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

.clearfix::before {
  content: "";
  display: table;
}

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

.clearfix::after {
  content: "";
  display: table;
  clear: both;
}

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

十、定位的简介

也可以参考我的另一篇博客:https://www.cnblogs.com/zhaostudy/p/16558751.html

需求分析

按照我们之前所学知识,可以怎么实现呢?

应该来说不难,很容易实现

.box2 {
  width: 200px;
  height: 200px;
  background-color: yellow;
  /* 左外边距、上外边距 */
  margin-left: 200px;
  margin-top: -200px;
}

.box3 {
  width: 200px;
  height: 200px;
  background-color: orange;
  /* 上外边距 */
  margin-top: 200px;
}

我们分别给 box2 和 box3 添加了外边距之后,就可以达到需求效果

当然也可以使用浮动来解决上述问题,但稍微麻烦一点

不管怎样,问题也是显而易见。我们实际开发中,页面上的元素可能很多,这样改必然是 牵一发而动全身

那么仅仅靠我们之前学习的布局知识,不足以轻松应对这种场景

那么就势必需要一个方便我们处理这种场景的办法,它就是定位

呸!不是!糟老头子

定位(position)

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

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

使用position属性来设置定位

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

1、相对定位

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

偏移量(offset)

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

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

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

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

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

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

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

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

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

.box2 {
  width: 200px;
  height: 200px;
  background-color: yellow;
  /* 开启相对定位 */
  position: relative;
  top: -200px;
  left: 200px;
}

我们给 box2 设置相对定位,就得到了我们想要的页面效果

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

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

相对定位的特点

  1. 当元素开启相对定位以后,如果不设置偏移量元素,则元素不会发生任何变化(这里注意,不仅仅是位置)

  2. 相对定位是参照于元素在文档流中的位置进行定位的(可以理解为相对于自身原始位置)

  3. 相对定位会提升元素的层级(表现为可以覆盖其他元素)

  4. 相对定位不会改变元素的性质:块还是块,行内还是行内

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2、绝对定位

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

绝对定位的特点

  1. 开启绝对定位后,如果不设置偏移量,元素的位置不会发生变化

  2. 开启绝对定位后,元素会从文档流中脱离

  3. 绝对定位会改变元素的性质:行内变成块,块的宽高被内容撑开(与相对定位相反)

  4. 绝对定位会使元素提升一个层级

  5. 绝对定位元素是相对于其包含块进行定位的(与相对定位不同)

包含块(containing block)

正常情况下:

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

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

<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>

示例

<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(默认值),那么就满足了其成为包含块的必要条件

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

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

水平方向的布局

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

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

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

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,当等式不满足时,则会自动调整这两个值

水平居中

<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>

垂直方向的布局

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

top + margin-top + border-top + padding-top + height + padding-bottom + border-bottom + margin-bottom + top = 其父元素的高度

垂直居中

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

水平垂直居中

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

.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

3、固定定位

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

固定定位的特点

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

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

示例

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

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

我们再对比下绝对定位

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

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

4、粘滞定位

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

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

大家可以看到,右侧边栏部分在一定的情况下是固定的,滚动到上方一定位置开始发生变动

我们先带着这个疑问,打开Zeal官方手册,找到positionsticky的相关描述

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).

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

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

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

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

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

示例

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

/* 设置一个高度 */
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,但作为当年浏览器的一霸,在废弃多年后,不知道还会不会有所怀念,毕竟它代表着我们不断逝去的青春)

5、几种定位的对比

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

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

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

6、补充:元素层级

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

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

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

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

示例

<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 时,浮动层级可以定位的层级高

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

7、总结

一般情况下,

  • 页面的整体结构大多采用浮动、块进行布局

  • 页面某些模块结构一般采用定位进行微调

8、练习:京东轮播图

css代码:

/* 整体居中 */
.box {
  width: 590px;
  height: 470px;
  /* 水平垂直双方向居中 */
  margin: auto;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

/* ======轮播图Start====== */

.img_list li {
  /* 每个轮播图绝对定位,让其重叠 */
  position: absolute;
}

.img_list li:nth-child(1) {
  /* 目前还没有学习js,暂时做成静态切换层级 */
  z-index: 1;
}

/* 全局图像大小 */
.img_list img {
  /* 我这里之所以要设置宽高,是因为下载的图片大小不全是一样大的 */
  /* 但是一般情况下,这些图片都会裁剪成统一大小,所以可以不用设置 */
  width: 590px;
  height: 470px;
}

/* ======轮播图End====== */

/* ======轮播圆Start====== */

.circle_list {
  height: 20px;
  /* 开启绝对定位 */
  position: absolute;
  bottom: 20px;
  left: 30px;
  z-index: 2;
  /* 参考京东原网页,整体字体设置样式,这种设置方式还不太懂 */
  /* 其实也可以不设置,不过每个轮播圆之间的间距跟原来就不太一样了 */
  font-size: 0;
  text-align: center;
}

/* 轮播圆细节 */
.circle_list .circle {
  /* 这里设置display: inline-block; 也是一样的 */
  float: left;
  height: 8px;
  width: 8px;
  background-color: rgba(255, 255, 255, 0.4);
  margin-right: 4px;
  /* 画圆,这个按照课程中的画法,按照网页源代码调出来的有点问题 */
  background-clip: content-box;
  border: 3px transparent solid;
  border-radius: 50%;
}

/* 轮播圆悬浮效果 */
.circle_list .circle:hover,
.circle_list .circle:nth-child(1) {
  background-color: #fff;
  border: 3px rgba(0, 0, 0, 0.1) solid;
}

/* ======轮播圆End====== */

html代码:

<div class="box">
  <ul class="img_list">
    <li>
      <a href="#"><img src="assets/lbt/1.jpg" alt="" /></a>
    </li>
    <li>
      <a href="#"><img src="assets/lbt/2.jpg" alt="" /></a>
    </li>
    <li>
      <a href="#"><img src="assets/lbt/3.jpg" alt="" /></a>
    </li>
    <li>
      <a href="#"><img src="assets/lbt/4.jpg" alt="" /></a>
    </li>
    <li>
      <a href="#"><img src="assets/lbt/5.jpg" alt="" /></a>
    </li>
    <li>
      <a href="#"><img src="assets/lbt/6.jpg" alt="" /></a>
    </li>
    <li>
      <a href="#"><img src="assets/lbt/7.jpg" alt="" /></a>
    </li>
    <li>
      <a href="#"><img src="assets/lbt/8.jpg" alt="" /></a>
    </li>
  </ul>
  <!-- 我这里结构并没有完全按照课程中的结构来,但实现效果是一样的 -->
  <ul class="circle_list">
    <li class="circle"></li>
    <li class="circle"></li>
    <li class="circle"></li>
    <li class="circle"></li>
    <li class="circle"></li>
    <li class="circle"></li>
    <li class="circle"></li>
    <li class="circle"></li>
  </ul>
</div>

别忘了,引入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可以同时指定多个字体,多个字体间使用隔开

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

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可以将服务器中的字体直接提供给用户去使用

@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),未必兼容,可能需要指定多个

5、图标字体(iconfont)

图标字体简介

在网页中经常需要使用一些图标,可以通过图片来引入图标但是图片大小本身比较大,并且非常的不灵活

所以在使用图标时,我们还可以将图标直接设置为字体,然后通过@font-face的形式来对字体进行引入

这样我们就可以通过使用字体的形式来使用图标

fontawesome

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

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

示例

<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>

效果

其中fas/fab是免费的,其他是收费的

图标字体其他使用方式

通过伪元素设置

  1. 找到要设置图标的元素通过::before::after选中

  2. content中设置字体的编码

  3. 设置字体的样式

    • fabfont-family: 'Font Awesome 5 Brands';

    • fasfont-family: 'Font Awesome 5 Free'; font-weight:900;

示例

<style>
  .poem {
    width: 200px;
    height: 300px;
    margin: auto;
  }

  li {
    list-style: none;
    margin-left: -40px;
  }

  li::before {
    content: "\f130";
    /* font-family: 'Font Awesome 5 Brands'; */
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    margin-right: 10px;
    color: gray;
  }
</style>

<div class="poem">
  <h1>武陵春·春晚</h1>
  <p>[宋] 李清照</p>
  <ul>
    <li>风住尘香花已尽,</li>
    <li>日晚倦梳头。</li>
    <li>物是人非事事休,</li>
    <li>欲语泪先流。</li>
    <li>闻说双溪春尚好,</li>
    <li>也拟泛轻舟。</li>
    <li>只恐双溪舴艋舟,</li>
    <li>载不动、许多愁。</li>
  </ul>
</div>

效果

通过实体设置

通过实体来使用图标字体:&#x图标编码;

示例

<i class="fas">&#xf025;</i>

效果

iconfont

官方网站:https://www.iconfont.cn/

iconfont 是阿里的一个图标字体库,海量图标库,图标字体非常丰富

但是版权有点模横两可,如果需要商用,最好联系作者

不过一般情况下,公司企业都会有自己的 UI 设计团队,会自己去进行设计

这里使用方式大同小异,不过

  • iconfont 需要添加购物车后再添加至项目然后下载,下载包中有 demo.html,详细介绍了使用方式

  • iconfont 也提供了一种在线方式,直接在我的项目中选择在线链接可以复制出一份@font-face的 css 代码

后续步骤与前面介绍的一致

示例

<!-- <link rel="stylesheet" href="/font/iconfont/iconfont.css"> -->
<style>
  i.iconfont {
    font-size: 100px;
  }

  p::before {
    content: "\e811";
    font-family: "iconfont";
    font-size: 50px;
  }

  /* 3、通过在线连接:这里link和@font-face择其一即可  */
  @font-face {
    font-family: "iconfont";
    /* Project id 2580407 */
    src: url("//at.alicdn.com/t/font_2580407_c0kpuhebb7r.woff2?t=1622373966454")
        format("woff2"), url("//at.alicdn.com/t/font_2580407_c0kpuhebb7r.woff?t=1622373966454")
        format("woff"),
      url("//at.alicdn.com/t/font_2580407_c0kpuhebb7r.ttf?t=1622373966454")
        format("truetype");
  }
</style>

<!-- 1、通过字符实体设置 -->
<i class="iconfont">&#xe810;</i>
<i class="iconfont">&#xe811;</i>
<i class="iconfont">&#xe812;</i>
<i class="iconfont">&#xe813;</i>

<!-- 2、通过伪元素设置 -->
<p>
  Lorem ipsum, dolor sit amet consectetur adipisicing elit. Totam deserunt
  tempore fugit quos eaque, ipsa rerum suscipit iure cumque aspernatur esse
  cupiditate nihil quas nulla odit? Sequi accusantium labore maiores.
</p>

效果

6、行高

行高line height

文字占有的实际高度,可以通过line-height来设置行高

  • 可以直接指定一个大小 px/em

  • 也可以直接为行高设置一个小数(字体大小的倍数)

行高经常还用来设置文字的行间距:行间距 = 行高 - 字体大小

字体框

字体框就是字体存在的格子,设置font-size实际上就是在设置字体框的高度

行高会在字体框的上下平均分配

示例

border: 1px black solid;
font-size: 100px;
/* line-height: 100px; */

不指定行高时,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 smalllarge
line-height normal  
font-family 取决于浏览器  

示例 1

/* font-size: 50px;
font-family: 'Courier New', Courier, monospace; */
font: 50px "Courier New", Courier, monospace;

示例 2

/* small-caps值设置小型大写字母字体,所有小写变大写,同时字体尺寸更小(了解即可) */
font: bold small-caps italic 50px "Courier New", Courier, monospace;

注意 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 值设置垂直对齐方式

vertical-align: 10px;

图片的垂直对齐问题

<style>
  .imgDiv {
    border: 5px seagreen solid;
  }

  .imgDiv img {
    width: 400px;
    height: 300px;
  }
</style>

<div class="imgDiv">
  <img src="/assets/news.png" alt="" />
</div>

明显默认情况下,图片底部有一定缝隙,我们稍作修改,给 img 元素添加vertical-align属性值

/* 只要不是基线对齐,就能消除底部缝隙 */
vertical-align: top;
vertical-align: bottom;
vertical-align: middle;

Q:为什么图片会有缝隙?

A:图片属于替换元素,特点与文本一致,也有自己的基线,默认也是基线对齐。而基线位置不在最底部,所以会出现缝隙

其他样式

white-space 设置网页如何处理空白

可选值:

  • normal 正常

  • nowrap 不换行

  • pre 保留空白

案例:实现网页省略符号

white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;

效果:

十二、背景

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

.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的前边

示例二:

.box1 {
  height: 500px;
  width: 500px;
  border: 10px red double;
  padding: 10px;
  background: #bfa url("assets/dlam.png") no-repeat 100px 100px/200px
    padding-box content-box;
}

练习一:线性渐变效果的背景图

如果我们仔细挂那可能,会发现很多网站导航条的背景色并不是单一的某种颜色,而是有一个渐变的效果

不过到目前为止,我们还没有学习线性渐变的内容,不过凭上面所学的知识同样可以实现

切图

首先,我们需要通过 PS 软件进行切图

  1. 按住Alt同时滚动鼠标滑轮,可以对图片大小进行缩放;调整至合适大小,再选择矩形块工具,截取一个宽度为 1px 大小的图片

  1. 然后选择图像-裁剪,就可以得到一个我们需要的一个背景图片

  1. 最后,选择文件-存储为Web所用格式

  1. 我这里选择的是 PNG 的格式,你可以对比几种格式,看看最终的图片大小折中选择,最好选择存储位置即可

  1. 得到我们需要的背景图片之后,就可以引入到css样式中了

代码

height: 60px;
width: 1500px;
background: url("assets/背景3.png") repeat-x;

效果

练习二:按钮点击效果

代码

<style>
  a:link {
    /* 因为本身是行内元素,变成块元素更方便设置宽高 */
    display: block;
    width: 93px;
    height: 29px;
    background: url("assets/背景/练习2-背景/link.png");
  }

  a:hover {
    background: url("assets/背景/练习2-背景/hover.png");
  }

  a:active {
    background: url("assets/背景/练习2-背景/active.png");
  }
</style>

<a href="javascript:;"></a>

效果

十三、雪碧图与渐变

1、雪碧图

解决图片闪烁的问题:

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

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

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

雪碧图的使用步骤:

  1. 先确定要使用的图标

  2. 测量图标的大小

  3. 根据测量结果创建一个元素

  4. 将雪碧图设置为元素的背景图片

  5. 设置一个偏移量以显示正确的图片

雪碧图的特点:

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

示例 1

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

.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;
}

2、线性渐变

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

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

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

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

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

  • to left

  • to right

  • to bottom

  • to top

  • deg deg 表示度数

  • turn 表示圈

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 个方向的渐变很好理解,我们就不再做过多的一一解释了

我们来看度数的渐变效果

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

会发现它是从左下角往右上角去进行渐变的,为什么呢?

我们小时候肯定都用过量角器

是不是恍然大悟,我们以原点作为起始点,有角度的那条边去做渐变,再把四象限的概念和矩形内部的四个角对应起来

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

然后看下圈数的表示方法

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

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

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

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

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

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

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

由于我们设置的div宽高为200px,所以会有 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]);

3、径向渐变

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

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

默认情况下,径向渐变的形状根据元素的形状来计算的

  • 正方形 --> 圆形

  • 长方形 --> 椭圆形

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

形状

  • circle 圆形

  • ellipse椭圆

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

也可以指定渐变的位置

位置

  • top

  • right

  • left

  • center

  • bottom

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

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

大小

  • closest-side 近边

  • farthest-side 远边

  • closest-corner 近角

  • farthest-corner 远角

background-image: radial-gradient(100px 60px, red, yellow);

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

radial-gradient(形状/大小 at 位置, 颜色 位置, 颜色 位置, 颜色 位置)
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属性

background-image: repeating-radial-gradient(
  circle at 50px 100px,
  red 50px,
  yellow 100px
);

总结:径向渐变的渐变方向以圆心为起点,往四周扩散的;同一半径上的颜色是渐变的,同一圆周上的颜色是一致的

十四、表格

1、表格

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

  • 课程表、人名单、成绩单...

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

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

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

  • rowspan 纵向的合并单元格

  • colspan 横向的合并单元格

<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>

2、长表格

可以将一个表格分成三个部分:

  • 头部 thead

  • 主体 tbody

  • 底部 tfoot

th 表示头部的单元格

<table border="1" width="50%" align="center">
  <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>

3、表格的样式

HTML 代码

<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>

CSS 代码

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:设置边框的合并

4、表单

表单

  • 在现实生活中表单用于提交数据

  • 在网页中也可以使用表单,网页中的表单用于将本地的数据提交给远程的服务器

form 的属性

  • action:表单要提交的服务器的地址

文本框

注意:数据要提交到服务器中,必须要为元素指定一个name属性值

文本框<input type="text" name="username" />

密码框

密码框<input type="password" name="password" />

提交按钮

<input type="submit" value="注册" />

单选框

像这种选择框,必须要措定一个value属性,value属性最终会作为用户填写的值传递给服务器

单选框
<input type="radio" name="hello" value="a" />
<input type="radio" name="hello" value="b" checked />

多选框

多选框
<input type="checkbox" name="test" value="1" />
<input type="checkbox" name="test" value="2" />
<input type="checkbox" name="test" value="3" checked />

下拉列表

下拉列表
<select name="haha">
  <option value="i">选项一</option>
  <option value="ii" selected>选项二</option>
  <option value="iii">选项三</option>
</select>

5、表单补充

按钮

<!-- 提交按钮 -->
<input type="submit" />
<!-- 重置按钮 -->
<input type="reset" />
<!-- 普通按钮 -->
<input type="button" value="按钮" />
<br /><br />
<button type="submit">提交</button>
<button type="reset">重置</button>
<button type="button">按钮</button>

上面两种写法实际上效果是一致的,区别在于:

  • input是自闭合标签,不需要</input>就能结束;button不是自闭合标签,跟一般标签一样是成对出现的

  • button因为不是自闭合标签,所以使用起来更灵活,可以嵌套其他的标签

十五、小米官网-练习

1、首先css样式重置

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;
}

2、公共样式的抽取

/* 公共样式 */
.clearfix::before,
.clearfix::after {
    content: '';
    display: table;
    clear: both;
}

/* 去除a的下划线 */
a {
    text-decoration: none;
    color: #333;
}

body {
    font: 14px/1.5 Helvetica Neue, Helvetica, Arial, Microsoft Yahei, Hiragino Sans GB, Heiti SC, WenQuanYi Micro Hei, sans-serif;
    color: #333;
    min-height: 1226px;
}

/* 设置一个类,用来表示中间容器的宽度! */
.w {
    width: 1226px;
    /* 容器居中 */
    margin: 0 auto;
}

3、 HTML 代码

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>小米商城 - Xiaomi 12、Redmi K50、MIX FOLD,小米电视官方网站</title>
        <!-- 引入css重置样式 -->
        <link rel="stylesheet" href="./css/reset.css" />
        <!-- 引入公共样式表 -->
        <link rel="stylesheet" href="./css/base.css" />
        <!-- 引入图标字体库 -->
        <link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.2.0/css/all.css" rel="stylesheet" />
        <!-- 引入当前页面的样式表 -->
        <link rel="stylesheet" href="./css/index.css" />
        <!-- 设置网站的图标:
            网站的图标:favicon.ico可以直接打开!   
        -->
        <link rel="icon" href="./img/favicon.ico">
    </head>
    <body>
        <!-- 顶部导航条 -->
        <!-- 顶部导航条外部容器 -->
        <div class="topbar-wrapper">
            <!-- 创建内部容器 -->
            <div class="topbar w clearfix">
                <!-- 左侧的导航 -->
                <ul class="service">
                    <li><a href="javascript:;">小米商城</a></li>
                    <li class="line">|</li>
                    <li><a href="javascript:;">loT</a></a></li>
                    <li class="line">|</li>
                    <li><a href="javascript:;">MIUI</a></li>
                    <li class="line">|</li>
                    <li><a href="javascript:;">云服务</a></li>
                    <li class="line">|</li>
                    <li><a href="javascript:;">金融</a></li>
                    <li class="line">|</li>
                    <li><a href="javascript:;">有品</a></li>
                    <li class="line">|</li>
                    <li><a href="javascript:;">小爱开放平台</a></li>
                    <li class="line">|</li>
                    <li><a href="javascript:;">企业团购</a></li>
                    <li class="line">|</li>
                    <li><a href="javascript:;">资质证照</a></li>
                    <li class="line">|</li>
                    <li><a href="javascript:;">协议规则</a></li>
                    <li class="line">|</li>
                    <li class="app-wrapper">
                        <a class="app" href="javascript:;">
                            下载app
                            <!-- 添加一个弹出层 -->
                            <div class="qrcode">
                                <img src="./img/miapp.png" alt="">
                                <span>小米商城app</span>
                            </div>
                        </a>
                    </li>
                    <li class="line">|</li>
                    <li><a href="javascript:;">Select Location</a></li>
                </ul>

                <!-- 购物车 -->
                <ul class="shop-cart">
                    <li>
                        <a href="#">
                        <i class="fas fa-cart-arrow-down"></i>
                        购物车(0)
                    </a>
                    </li>
                </ul>

                <!-- 用户登录注册 -->
                <ul class="user-info">
                    <li><a href="javascript:;">登录</a></li>
                    <li class="line">|</li>
                    <li><a href="javascript:;">注册</a></li>
                    <li class="line">|</li>
                    <li><a href="javascript:;">消息通知</a></li>
                </ul>

            </div>
        </div>

        <!-- 创建一个头部的外部容器 -->
        <div class="header-wrapper">
            <div class="header w clearfix">
                <h1 class="logo" title="小米">
                    小米官网
                    <a class="home" href="/"></a>
                    <a class="mi" href="/"></a>
                </h1>

                <!-- 创建一个中间导航条的容器 -->
                <div class="nav-wrapper">
                    <!-- 创建导航条 -->
                    <ul class="nav clearfix">
                        <li class="all-goods-wrapper">
                            <a class="all-goods" href="#">全部商品分类</a>

                            <!-- 创建一个左侧导航菜单 -->
                            <ul class="left-menu">
                                <li>
                                    <a href="#">
                                        手机 电话卡
                                        <i class="fas fa-angle-right"></i>
                                    </a>
                                </li>
                                <li>
                                    <a href="#">
                                        电视 盒子
                                        <i class="fas fa-angle-right"></i>
                                    </a>
                                </li>
                                <li>
                                    <a href="#">
                                        笔记本 平板
                                        <i class="fas fa-angle-right"></i>
                                    </a>
                                </li>
                                <li>
                                    <a href="#">
                                        家电 插线板
                                        <i class="fas fa-angle-right"></i>
                                    </a>
                                </li>
                                <li>
                                    <a href="#">
                                        出行 穿戴
                                        <i class="fas fa-angle-right"></i>
                                    </a>
                                </li>
                                <li>
                                    <a href="#">
                                        智能 路由器
                                        <i class="fas fa-angle-right"></i>
                                    </a>
                                </li>
                                <li>
                                    <a href="#">
                                        电源 配件
                                        <i class="fas fa-angle-right"></i>
                                    </a>
                                </li>
                                <li>
                                    <a href="#">
                                        健康 儿童
                                        <i class="fas fa-angle-right"></i>
                                    </a>
                                </li>
                                <li>
                                    <a href="#">
                                        耳机 音箱
                                        <i class="fas fa-angle-right"></i>
                                    </a>
                                </li>
                                <li>
                                    <a href="#">
                                        生活 箱包
                                        <i class="fas fa-angle-right"></i>
                                    </a>
                                </li>
                            </ul>
                        </li>
                        <li><a href="#">小米手机</a></li>
                        <li><a href="#">Redmi红米</a></li>
                        <li><a href="#">电视</a></li>
                        <li><a href="#">笔记本</a></li>
                        <li><a href="#">家电</a></li>
                        <li><a href="#">路由器</a></li>
                        <li><a href="#">只能硬件</a></li>
                        <li><a href="#">服务</a></li>
                        <li><a href="#">社区</a></li>

                        <!-- 创建一个弹出层 -->
                        <div class="goods-info">

                        </div>

                        <!-- 创建搜索框的容器 -->
                        <div class="search-wrapper">
                            <form class="search" action="#">
                                <input class="search-inp" type="text">
                                <button class="search-btn">
                                    <i class="fas fa-search"></i>
                                </button>
                            </form>
                        </div>
                    </ul>
                </div>
            </div>
        </div>

        <!-- 创建banner的容器 -->
        <div class="banner-wrapper">
            <div class="banner w">
                <ul class="img-list">
                    <li>
                        <a href="#">
                            <img src="./img/banner1.jpg" alt="">
                        </a>
                    </li>
                    <li>
                        <a href="#">
                            <img src="./img/banner2.webp" alt="">
                        </a>
                    </li>
                    <li>
                        <a href="#">
                            <img src="./img/banner3.webpg" alt="">
                        </a>
                    </li>
                    <li>
                        <a href="#">
                            <img src="./img/banner4.webp" alt="">
                        </a>
                    </li>
                    <li>
                        <a href="#">
                            <img src="./img/banner5.webp" alt="">
                        </a>
                    </li>
                </ul>

                <div class="pointer">
                    <a class="active" href="javascript:;"></a>
                    <a href="javascript:;"></a>
                    <a href="javascript:;"></a>
                    <a href="javascript:;"></a>
                    <a href="javascript:;"></a>
                </div>

                <div class="prev-next">
                    <a class="prev" href="javascript:;"></a>
                    <a class="next" href="javascript:;"></a>
                </div>
            </div>

            <!-- 固定定位的工具条 -->
            <div class="back-top"></div>

            <!-- 创建广告容器 -->
            <div class="ad w">
                <ul class="shortcut">
                    <li>
                        <a href="#">
                            <i class="fas fa-clock"></i>
                            小米秒杀
                        </a>
                    </li>
                    <li>
                        <a href="#">
                            <i class="fas fa-building"></i>
                            企业团购
                        </a>
                    </li>
                    <li>
                        <a href="#">
                            <i class="fas fa-frog"></i>
                            F码通道
                        </a>
                    </li>
                    <li>
                        <a href="#">
                            <i class="fas fa-address-card"></i>
                            米粉卡
                        </a>
                    </li>
                    <li>
                        <a href="#">
                            <i class="fas fa-gift"></i>
                            以旧换新
                        </a>
                    </li>
                    <li>
                        <a href="#">
                            <i class="fas fa-mobile-alt"></i>
                            话费充值
                        </a>
                    </li>
                </ul>

                <ul class="ad-img">
                    <li>
                        <a href="#">
                            <img src="./img/01.jpg" alt="">
                        </a>
                    </li>
                    <li>
                        <a href="#">
                            <img src="./img/02.jpg" alt="">
                        </a>
                    </li>
                    <li>
                        <a href="#">
                            <img src="./img/03.jpg" alt="">
                        </a>
                    </li>
                </ul>
            </div>
        </div>
    </body>
</html>

4、CSS 代码

/* 主页index.html的样式表 */

/* 设置顶部导航条的容器 */
.topbar-wrapper {
    width: 100%;
    height: 40px;
    line-height: 40px;
    background-color: #333;
}

/* 设置超链接的颜色 */
.topbar a {
    font-size: 12px;
    color: #b0b0b0;
    display: block;
}

/* 设置超链接移入的效果 */
.topbar a:hover {
    color: #fff;
}

/* 设置中间的分割线效果 */
.topbar .line {
    color: #424242;
    font-size: 12px;
    margin: 0 8px;
    margin-top: -1px;
}

/* 设置左侧导航条 */
.service,
.topbar li {
    float: left;
}

.app {
    position: relative;
}

/* 设置app下的小三角 */
.app-wrapper:hover .app::after {
    display: none;
    content: '';
    /* 设置绝对定位 */
    position: absolute;
    display: block;
    width: 0;
    height: 0;
    /* 设置四个方向的边框 */
    border: 6px solid transparent;
    /* 去除上边框 */
    border-top: none;
    /* 单独设置下边框的颜色 */
    border-bottom-color: #fff;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}

/* 设置下载app的下拉 */
.app .qrcode {
    /* 如果设置过渡先关闭display */
    /* display: none; */
    position: absolute;
    /* left: -38px; */
    left: 22px;
    width: 124px;
    /* height: 135px; */ /* 这个是通过display设置的方式,不好加动画效果! */
    /* 通过height、overflow方便设置动画 */
    height: 0;
    overflow: hidden;
    margin-left: -62px;
    line-height: 1;
    text-align: center;
    background-color: #fff;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
    z-index: 9999;

    /* transition设置过度效果 */
    transition: height 0.3s;
}

/* 与下方的效果是一样的,另一种写法! */
/* .app:hover .qrcode,
.app:hover::after {
    display: block;
} */

.app-wrapper:hover > .app .qrcode {
    display: block;
    height: 148px;
}

.app .qrcode img {
    width: 90px;
    margin: 17px;
    margin-bottom: 12px;
}

.app .qrcode span {
    color: #000;
    font-size: 13px;
}

/* 设置右侧导航条 */
.shop-cart,
.user-info {
    float: right;
}

.shop-cart {
    margin-left: 26px;
}

/* 设置购物车的样式 */
.shop-cart a {
    width: 120px;
    background-color: #424242;
    text-align: center;
}

.shop-cart:hover a {
    background-color: #fff;
    color: #ff6700;
}

.shop-cart i {
    margin-right: 2px;
}

/* 设置中间的header */
.header {
    height: 100px;
    /* background-color: pink; */
}

.header-wrapper {
    /* background-color: red; */
    position: relative;
}

/* 设置logo的h1 */
.header .logo {
    /* 隐藏logo中的文字 */
    text-indent: -999px;
    float: left;
    margin-top: 22px;
    width: 55px;
    height: 55px;
    position: relative;
    overflow: hidden;
}

/* 统一设置logo的超链接 */
.header .logo a {
    /* display: block; */
    position: absolute;
    width: 55px;
    height: 55px;
    left: 0;
    background-color: #ff6700;
    background-image: url('../img/mi-logo.png');
    background-size: cover;
    background-position: center;
    transition: left 0.3s;
}

/* 设置home的图标 */
.header .logo .home {
    left: -55px;
    background-image: url('../img/mi-home.jpeg');
}

/* 设置鼠标移入以后两个图标的位置 */
.header .logo:hover .mi {
    left: 55px;
}

.header .logo:hover .home {
    left: 0px;
}

.header .nav-wrapper {
    float: left;
    margin-left: 7px;
}

/* 设置导航条 */
.header .nav {
    /* width: 792px; */
    height: 100px;
    line-height: 100px;
    padding-left: 58px;
}

/* 设置导航条的li */
.nav > li {
    float: left;
}

.all-goods-wrapper {
    position: relative;
}

/* 设置左侧导航条的样式 */
.left-menu {
    width: 234px;
    height: 420px;
    background-color: rgba(0, 0, 0, 0.6);
    position: absolute;
    z-index: 998;
    left: -120px;
    line-height: 1;
    padding: 20px 0;
}

ul .left-menu li a {
    display: block;
    height: 42px;
    line-height: 42px;
    color: white;
    margin-right: 0;
    padding: 0 30px;
    font-size: 14px;
}

ul .left-menu li a:hover {
    color: white;
    background-color: #ff6700;
}

.left-menu a i {
    float: right;
    line-height: 42px;
}

.nav-wrapper li a {
    font-size: 16px;
    display: block;
    margin-right: 20px;
}

.nav-wrapper li a:hover {
    color: #ff6700;
}

/* 隐藏全部商品 */
.all-goods {
    visibility: hidden;
}

.nav .goods-info {
    /* height: 228px; */
    height: 0;
    overflow: hidden;
    width: 100%;
    position: absolute;
    background-color: white;
    top: 100px;
    left: 0;
    transition: height 0.3s;
    /* background-color: #bfa; */
    z-index: 999;
}

.nav li:not(:first-of-type):not(:nth-child(10)):not(:nth-child(9)):hover ~ .goods-info,
.goods-info:hover {
    border-top: 1px solid rgb(224, 224, 224);
    box-shadow: 0 5px 3px rgba(0, 0, 0, 0.2);
    height: 228px;
}

/* 设置搜索框的容器 */
.search-wrapper {
    width: 296px;
    height: 50px;
    float: right;
    margin-top: 25px;
}

.search-wrapper .search-inp {
    box-sizing: border-box;
    float: left;
    padding: 0;
    height: 50px;
    border: none;
    padding: 0 10px;
    width: 244px;
    font-size: 16px;
    border: 1px solid rgb(224, 224, 224);
    outline: none;
}

/* 设置input获取焦点后的样式 */
.search-wrapper .search-inp:focus,
.search-wrapper .search-inp:focus + button {
    /* outline: 1px solid #ff6700; */
    border-color: #ff6700;
}

.search-wrapper .search-btn {
    float: left;
    height: 50px;
    width: 52px;
    padding: 0;
    border: none;
    background-color: #fff;
    color: #616161;
    font-size: 16px;
    border: 1px solid rgb(224, 224, 224);
    border-left: none;
}

.search-wrapper .search-btn:hover {
    background-color: #ff6700;
    color: white;
    border: none;
}

/* 设置banner */
.banner {
    position: relative;
    height: 460px;
}

.banner .img-list li {
    position: absolute;
}

.banner img {
    width: 100%;
}

/* 设置5个导航点 */
.pointer {
    position: absolute;
    bottom: 22px;
    right: 35px;
}

.pointer a {
    float: left;
    width: 6px;
    height: 6px;
    border: 2px rgba(0, 0, 0, 0.4) solid;
    border-radius: 50%;
    background-color: rgba(0, 0, 0, 0.4);
    margin-left: 6px;
}

.pointer a:hover,
.pointer a.active {
    border-color: rgba(0, 0, 0, 0.4);
    background-color: rgba(225, 225, 225, 0.4);
}

/* 设置两个箭头 */
.prev-next a {
    width: 41px;
    height: 69px;
    position: absolute;
    background-image: url('../img/icon-slides.png');
    top: 0;
    bottom: 0;
    margin: auto 0;
}

.prev-next .prev {
    left: 234px;
    background-position: -84px 0;
}

.prev-next .prev:hover {
    background-position: 0 0;
}

.prev-next .next {
    right: 0;
    background-position: -125px 0;
}

.prev-next .next:hover {
    background-position: -42px 0;
}

/* 设置回到顶部的元素 */
.back-top {
    width: 26px;
    height: 206px;
    background-color: #ff6700;
    position: fixed;
    bottom: 60px;
    right: 50%;
    margin-right: -639px;
}

/* 设置下部的广告区域 */
.ad {
    /* background-color: orange; */
    height: 170px;
    margin-top: 14px;
}

.ad .shortcut,
.ad .ad-img,
.ad li {
    float: left;
}

/* 设置左侧快捷方式 */
.ad .shortcut {
    width: 228px;
    height: 168px;
    background-color: #5f5750;
    margin-right: 14px;
    padding-left: 6px;
    padding-top: 2px;
}

.ad .shortcut li {
    position: relative;
}

/* 设置上边框 */
.ad .shortcut li::before {
    content: '';
    position: absolute;
    width: 64px;
    height: 1px;
    background-color: #665e57;
    left: 0;
    right: 0;
    top: 0;
    margin: 0 auto;
}

/* 设置左边框 */
.ad .shortcut li::after {
    content: '';
    position: absolute;
    height: 70px;
    width: 1px;
    background-color: #665e57;
    top: 0;
    left: 0;
    margin: auto 0;
}

/* 设置快捷方式的超链接 */
.ad .shortcut a {
    color: #cfccca;
    display: block;
    height: 84px;
    width: 76px;
    text-align: center;
    font-size: 12px;
    overflow: hidden;
}

.ad .shortcut a:hover {
    color: #fff;
}

/* 设置图标字体 */
.ad .shortcut i {
    display: block;
    margin-top: 20px;
    font-size: 20px;
    margin-bottom: 6px;
}

/* 设置自左侧的图片 */
.ad .ad-img li {
    width: 316px;
    margin-right: 15px;
}

.ad .ad-img li:last-child {
    margin: 0;
}

.ad .ad-img img {
    width: 100%;
    vertical-align: top;
}

5、效果展示

对于小米官网的一些静态资源可以在mi.com的开发者工具进行获取,这里省略!

十六、过渡与动画

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.com

  • steps() 分步执行过渡效果,可以设置第二个值:

    • end,在时间结束时执行过渡(默认值)

    • start,在时间开始时执行过渡

transition:可以同时设置过渡相关的所有属性

  • 只有一个要求,如果要写延迟,则两个时间中第一个是持续时间,第二个是延迟时间

/* transition: margin-left 2s 1s; */
transition-property: margin-left;
transition-duration: 2s;
transition-delay: 1s;

示例

/* transition: margin-left 2s 1s; */
transition-property: margin-left;
transition-duration: 2s;
transition-delay: 1s;

几种过渡效果对比

linear匀速运动

transition-timing-function: linear;

ease 默认值,慢速开始,先加速后减速

transition-timing-function: ease;

ease-in 加速运动

transition-timing-function: ease-in;

ease-out 减速运动

transition-timing-function: ease-out;

ease-in-out 先加速后减速

transition-timing-function: ease-in-out;

cubic-bezier()来指定时序函数

transition-timing-function: cubic-bezier(0.17, 1.79, 0.68, -0.69);

steps()分步执行过渡效果

/* transition-timing-function: steps(2, end); */
transition-timing-function: steps(2);

transition-timing-function: steps(2, start);

2、动画

动画和过渡类似,都是可以实现一些动态的效果,不同的是

  • 过渡需要在某个属性发生变化时才会触发

  • 动画可以自动触发动态效果

设置动画效果,必须先要设置一个关键帧,关键帧设置了动画执行每一个步骤

@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

示例

/* 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;

3、实战

米兔

.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;
}

奔跑的少年

.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;
  }
}

弹力球

.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;
  }
}

酷炫球

div {
  float: left;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  animation: bounce 0.5s infinite ease-in alternate;
}

.ball1 {
  background-color: red;
  animation-delay: 0.1s;
}

.ball2 {
  background-color: yellow;
  animation-delay: 0.2s;
}

.ball3 {
  background-color: green;
  animation-delay: 0.3s;
}

.ball4 {
  background-color: blue;
  animation-delay: 0.4s;
}

.ball5 {
  background-color: pink;
  animation-delay: 0.5s;
}

.ball6 {
  background-color: orange;
  animation-delay: 0.6s;
}

.ball7 {
  background-color: fuchsia;
  animation-delay: 0.7s;
}

.ball8 {
  background-color: gray;
  animation-delay: 0.8s;
}

.ball9 {
  background-color: darkcyan;
  animation-delay: 0.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用来设置元素的变形效果

1、平移

  • translateX() 沿着由方向平移

  • translateY() 沿着 y 轴方向平移

  • translateZ() 沿着 z 轴方向平移平移元素

百分比是相对于自身计算的

几种水平垂直双方向居中的方式对比

  1. 绝对定位的方式

    /* 这种居中方式,只适用于元素的大小确定 */
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    margin: auto;
  2. table-cell的方式

    /* table-cell的方式具有一定局限性 */
    display: table-cell;
    vertical-align: middle;
    text-align: center;
  3. transform的方式

    /* transform变形平移的方式 */
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translateX(-50%) translateY(-50%);

浮出效果

div {
  float: left;
  width: 200px;
  height: 300px;
  background-color: silver;
  margin: 100px 50px auto 50px;
  transition: all 0.3s;
}

div:hover {
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  transform: translateY(-5px);
}

2、Z 轴平移

z 轴平移,调整元素在 z 轴的位置,正常情况就是调整元素和人眼之间的距离,距离越大,元素离人越近

z 轴平移属于立体效果(近大远小),默认情况下网页是不支持透视,如果需要看见效果必须要设置网页的视距

透视效果

html {
  background-color: rgb(71, 44, 32);
  /* 设置当前网页的视距为800px,人眼距离网页的距离 */
  perspective: 800px;
}

.box {
  width: 200px;
  height: 300px;
  background-color: silver;
  margin: 100px auto;
  transition: all 0.3s;
}

.box:hover {
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  transform: translateZ(200px);
}

3、旋转

通过旋转可以使元素沿着 x、y 或 z 旋转指定的角度

  • rotateX()

  • rotateY()

  • rotateZ()

/* transform: rotateY(0.5turn); */
transform: rotateY(180deg);
/* backface-visibility设置元素的背面:可选值:hidden、visible:默认值! */

4、缩放

对元素进行缩放的函数

  • scalex() 水平方向缩放

  • scaleY() 垂直方向缩放

  • scale() 双方向的缩放

.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;
}

5、实战

鸭子表

HTML 代码

<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>

CSS 代码

.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);
  }
}

复仇者联盟

HTML 代码

<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>

CSS 代码

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: 0.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官网地址:https://less.bootcss.com/

less是一门css的预处理语言

  • less是一个 css 的增强版,通过less可以编写更少的代码实现更强大的样式

  • less中添加了许多的新特性:像对变量的支持、对mixin的支持...

  • less的语法大体上和css语法一致,但是less中增添了许多对css的扩展,所以浏览器无法直接执行less代码,要执行必须向将less转换为css,然后再由浏览器执行

1、安装插件

vscode中搜索less,点击安装

2、编写 Less

HTML 代码

使用快捷方式创建 HTML 代码

回车生成html代码

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

less 代码

创建style.less文件,编写less代码

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;
  }
}

Easy LESS插件会帮助我们在style.less所在目录下面生成一个相同名称的css文件

查看生成的style.css代码

body {
  --height: calc(200px / 2);
  --width: 100px;
}
body div {
  height: var(--height);
  width: var(--width);
}
body .box1 {
  background-color: #bfa;
}
body .box2 {
  background-color: red;
}
body .box3 {
  background-color: yellow;
}

我们直接在 HTML 中引入生成的style.css

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

运行代码,查看效果

2、Less 语法

less 注释

less中的单行注释,注释中的内容不会被解析到css

css中的注释,内容会被解析到css文件中

// `less`中的单行注释,注释中的内容不会被解析到`css`中

/*
`css`中的注释,内容会被解析到`css`文件中
*/

父子关系嵌套

less中,父子关系可以直接嵌套

// `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

/*
`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;
}

变量

变量,在变量中可以存储一个任意的值

并且我们可以在需要时,任意的修改变量中的值

变量的语法:@变量名

  • 直接使用使用变量时,则以@变量名的形式使用即可

  • 作为类名、属性名或者一部分值使用时,必须以@{变量名}的形式使用

  • 可以在变量声明前就使用变量(可以但不建议)

@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代码

.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语法需要用引号包裹

其他

.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代码

.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混合函数

4、混合函数

在混合函数中可以直接设置变量,并且可以指定默认值

.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代码

.p6 {
  width: 300px;
  height: 100px;
  background-color: red;
}

其他

  • average混合函数

    .h1 {
      color: average(red, yellow);
    }

    生成的css代码

    .h1 {
      color: #ff8000;
    }
  • darken混合函数

    body {
      background-color: darken(#bfa, 50%);
    }

    生成的css代码

    body {
      background-color: #22aa00;
    }

5、补充

创建all.less文件,将我们之前编写的less文件通过@import引入进来

可以通过import来将其他的less引入到当前的less

@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文件,在其中添加如下配置

"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文件(当然是需要了)

十九、弹性盒简介

可以参考:https://www.cnblogs.com/zhaostudy/p/16558810.html

1、基本概念

弹性盒

flex(弹性盒、伸缩盒)

  • css中的又一种布局手段,它主要用来代替浮动来完成页面的布局

  • flex可以使元素具有弹性,让元素可以跟随页面的大小的改变而改变

弹性容器

要使用弹性盒,必须先将一个元素设置为弹性容器

我们通过display 来设置弹性容器

  • display:flex 设置为块级弹性容器

  • display:inline-flex 设置为行内的弹性容器

/* 设置弹性容器 */
display: flex;

弹性元素

弹性容器的子元素是弹性元素(弹性项)

弹性元素可以同时是弹性容器

2、弹性容器的属性

主轴与侧轴

  • 主轴:弹性元素的排列方向称为主轴

  • 侧轴:与主轴垂直方向的称为侧轴

主轴属性

排列方式

flex-direction 指定容器中弹性元素的排列方式

  • row默认值,弹性元素在容器中水平排列(自左向右)

  • row-reverse 弹性元素在容器中反向水平排列(自右向左)

  • column 弹性元素纵向排列(自上向下)

  • column-reverse 弹性元素反向纵向排列(自下向上)

/* 设置弹性元素排列方式 */
flex-direction: column;

自动换行

flex-wrap 设置弹性元素是否在弹性容器中自动换行

  • nowrap 默认值,元素不会自动换行

  • wrap 元素沿着辅轴方向自动换行

/* 设置弹性元素排列方式 */
flex-direction: row;
/* 设置自动换行 */
flex-wrap: wrap;

简写属性

flex-flowwrapdirection的简写属性

/* 简写属性 */
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 空白分布到元素的单侧

弹性居中

利用弹性盒对元素进行水平垂直双方向居中

justify-content: center;
align-items: center;

3、弹性元素的属性

伸展系数

flex-grow 指定弹性元素的伸展系数,默认值为 0

  • 当父元素有多余空间的时,子元素如何伸展

  • 父元素的剩余空间,会按照比例进行分配

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

  • 当父元素中的空间不足以容纳所有的子元素时,如何对子元素进行收缩

  • 缩减系数的计算方式比较复杂,缩减多少是根据 缩减系数元素大小 来计算

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,表示参考元素自身的高度或宽度

  • 如果传递了一个具体的数值,则以该值为准

li:nth-child(1) {
  background-color: #bfa;
  flex-basis: 200px;
}

简写属性

flex可以设置弹性元素所有的三个样式flex: 增长 缩减 基础

  • initialflex: 0 1 auto

  • autoflex: 1 1 auto

  • noneflex: 0 0 auto 弹性元素没有弹性

排列顺序

order 决定弹性元素的排列顺序

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;
}

覆盖辅轴

align-self用来覆盖当前弹性元素上的align-items

li:nth-child(1) {
  background-color: #bfa;
  align-self: flex-end;
}

 

 

posted @ 2022-09-12 17:08  nakano_may  阅读(178)  评论(0编辑  收藏  举报