GDG第一场前端分享

本文参考@李实

前端是什么

相关软件

作者使用的操作系统是 Mac,读者也可以用 Windows,操作使用不会有明显差异,如果有差别会额外注明。
本教程使用的软件主要是 VS Code 用于代码编辑,Chrome 作为浏览器,以及调试工具。另外版本控制软件 (version control software) 例如 Git 是软件开发中必不可少的工具。

VS Code 说明

Visual Studio Code 简称 VS Code 是微软推出的一款代码编辑器,他是开源(源代码公开),免费并且跨平台(Windows/Mac/Linux 都可以安装使用)的。有趣的是他自己也是基于前端技术的,他使用了 Electron 框架,这个框架让你可以使用网页技术和 NodeJS 开发跨平台应用。所以我们会在一个基于前端技术的软件中,写前端代码。

编程语言源代码代码都是纯文本,因为需要从键盘输入。所谓纯文本文件,一般指只有字符原生编码构成的二进制计算机文件。可以理解为除了文字之外,文件不含任何其他数据。一般的 Windows 电脑的 .txt 即是纯文本文件,但是文件的后缀,属于文件名的一部分,和文件的内容没有必然关系,只是暗示操作系统或者使用者文件的内容而已。常见的文档比如 Word 并不是纯文本文件,因为他含有很多额外的信息,比如格式排版等,而这些信息并不是用纯文本表示的,而是文档处理软件比如 Word 生成的,所以如果您用纯文档编辑器,比如 Windows 中的记事本或者 VS Code 打开会 Word 文档会看到乱码。

理解了纯文本文件,那为什么要用 VS Code 而不用记事本呢?你可以选择用记事本,或者其他文本编辑器,比如 Atom, Notepad++, Sublime,但是本教程选择 VS Code。各软件功能都有差异,建议初学者读者使用 VS Code:

  • VS Code 官网:https://code.visualstudio.com
  • 简体中文语言包:https://marketplace.visualstudio.com/items?itemName=MS-CEINTL.vscode-language-pack-zh-hans

Chrome 说明

Chrome 目前是全球最流行的浏览器,并且提供的开发者工具 (developer tools) 非常方便。

如果用其他浏览器可以吗,比如 Firefox, Safari, Edge?当然是可以的,但是本教程选择 Chrome。各浏览器功能都有差异,建议初学者读者使用 Chrome。

网站概述

本章概括性的描述了做网站涉及到的各种概念,运行原理,是整本书的基础。例如:浏览器,网络通信,HTTP,服务器,HTML/CSS/JavaScript。通过本章的介绍,读者可以对 Web 的构成,涉及到的软件和技术有一个概览,知道一个简单的网站是如何工作的。

参考标准W3C

W3C是英文 World Wide Web Consortium 的缩写,中文意思是W3C理事会或万维网联盟。W3C组织是对网络标准制定的一个非赢利组织,像HTML、XHTML、CSS、XML的标准就是由W3C来定制。
到目前为止,W3C已开发了超过50个规范(草案)。这些规范(草案)包括人们早已、耳熟能详的HTML、HTTP、URIs、XML等,也包括针对语义Web的RDF、OWL等。

HTML (超文本标记语言Hypertext Markup Language)

网页的作者,把自己想要展示的内容,以一定的格式表示出来,存放在服务器,由服务器发送给请求访问的用户。这种格式名叫 HTML,最新的版本叫 HTML5。

以下是一段html代码例子:



    
        
        文档名
    
    
        

文章标题

正文

网页中的效果是这样的:

CSS (层叠样式表 Cascading Style Sheets)

HTML 越来越流行,但有一个需求没有很好的被满足:可以让网页有自定义的样式。开发者和网页设计师需要更自由的控制网页的展示效果,比如布局方式,边框,背景色,背景图片,按钮样式等等。HTML 的布局能力非常有限,如果把非常复杂的样式设计到 HTML 中,那么 HTML 会非常复杂,冗长;另外分离内容与样式,也是一个很好的实践方式。因此,在 1994 年,Håkon Wium Lie 发表了自己的样式表提案,这提案成为了后来的 CSS。下面是一个简单的 CSS 例子。

h1 {
    color: red;
}

上面的 CSS 规定了 h1 元素的文字颜色是红色。如果把上面的 CSS 应用到之前 HTML 的例子,用浏览器打开效果如下:

HTML 语法

在上面的例子中可以看到 HTML 文件是由浏览器处理的,浏览器的工作就是根据 HTML 文件展示效果,这个过程称为渲染。HTML 该怎么写呢?

定义文档类型

在上面的例子中,第一行是:


这一行的作用是定义文档类型,意义是告诉浏览器,以 HTML5 的方式识别内容。历史上有过其他种文档类型,基本已经过时了。因此大家只要记住这个就好。想了解更多请查看链接:https://www.w3.org/QA/2002/04/valid-dtd-list.html

元素 (Element)

HTML 文档由元素组成,在上面的例子中,出现的元素有:html, head, body, meta, title, h1, p。用 p 元素举例子

正文

P 代表 paragraph 即段落,段落是有开始和结束的,可以看到,这个元素由

开始,由

结束。但并不是所有的元素都有开始和结束之分的,比如例子中的 meta 元素,meta 代表 metadata 是文档的元数据,因此不需要结束标签。再比如 BR 元素用作换行 (break line),写法是
,也不需要结束标签。如何知道一个元素是否需要结束标签呢?推荐的地方是 MDN web docs,这里的文档齐全并且权威,是开发者的好朋友。比如 br 元素的文档:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/br 这里明确说名了不需要结束标签。

另外有的元素还有自己的属性,例子中的 meta:


charset 是属性名属性的值为 UTF-8,值需要用双引号包含,属性名和属性的值用等号相连。不同的元素有着不同的属性以及值,可以从 MDN 文档中找到答案。

树形结构

上文中我们提到了内容有自己的逻辑结构。在 HTML 中,基本的结构是树形结构,树由元素组成。在上面的例子中 HTML 的树形结构是:

  • 只有1个根元素,元素名为 html
  • 根元素有两个子元素(Child Element)分别是 head 和 body
  • head 和 body 分别有自己的子元素
  • 其中 body 的子节点 h1 包含的是文字,文字就不是元素了,它属于 h1

树形结构也是有限制的:是否能包含子元素,能包含什么样的子元素都各有区别。例如 html 就只能有 2 个子元素,分别是 head 和 body,而 P 元素可以包含很多种元素。读者可以查看 MDN 文档说明 中的 Permitted content (允许的内容,即允许包含的内容)。

总结

本节介绍了 HTML 文档的基本写法,包括标签的写法,以及树形结构,介绍了查文档的地方。但是 HTML 文档很长,需要全看一遍吗?当然不,有经验的程序员通常也不会知道所有元素。下一节我们会介绍一些常用的元素,让大家快速上手。

HTML 常用元素与属性

常用的元素

标题元素

-

标题元素用来表示标题,HTML 一共定义了6个级别的标题,即

-

,例如

Petter Parker

效果:

Petter Parker

P 元素

P 元素表示段落(paragraph),P 可以包含文字,或者很多元素,比如A元素,IMG 元素,H1-H6 元素等

我是蜘蛛侠,我做一些很酷的事情,比如拯救世界

效果:

  

我是蜘蛛侠,我做一些很酷的事情,比如拯救世界

IMG 元素

IMG 元素表示图片(image),img 元素不需要结束标签。需要 src 属性指定图片的 url。alt 属性的作用是给图片一个描述文字,屏幕阅读器会使用到这个描述,另外在图片无法再入的时候,浏览器也会显示这个文字,alt 属性不是必须的。

spider man

效果:

spider man

A 元素

A 元素(anchor element)表示超链接(hyperlink)。href 属性指定了超链接的 URL,也可以是 URL 片段或相对路径。关于相对路径,在下一章介绍。URL 片段是以井号开头的文字,例如顶部,其中 top 是页面中某个元素的 ID,ID 在以后的章节会介绍。另外 A 元素还有 target 属性,表示链接打开的目标。属性值默认是 _self 指定在当前页面打开链接,还可以设置为 _blank 指定浏览器在新窗口打开链接。

漫威蜘蛛侠

效果:


UL, OL 以及 LI 元素

UL 元素表示无序列表 (Unordered List),无序指没有先后顺序。OL 元素表示有序列表(Ordered List)。列表中的内容 (List Item),用 LI 元素表示,例如:

组织:
  • 复仇者联盟
  • 号角日报
  • 未来基金会
  • 新复仇者
  • 帕克工业
敌人:
  1. 绿恶魔
  2. 章鱼博士
  3. 灭霸

效果:

组织:
  • 复仇者联盟
  • 号角日报
  • 未来基金会
  • 新复仇者
  • 帕克工业
敌人:
  1. 绿恶魔
  2. 章鱼博士
  3. 灭霸

HEADER, MAIN, SECTION, ARTICLE, FOOTER, DIV元素

HEADER, MAIN, SECTION, ARTICLE, FOOTER 属于内容分区元素(Content sectioning elements),用来把整个文档分为多个逻辑分区,比如 HEADER 元素可以用来表示介绍性内容,MAIN 元素可以用来表示文档的主要内容,SECTION 元素可以用来表示单独的一节内容,ARTICLE 可以用来表示帖子,文章,博客,评论等,FOOTER 表示页脚,经常用来放作者,版权,联系方式等信息。这几个元素都是 HTML5 标准新加入的,可以更准确的表达文档的逻辑结构,也属于语义元素(semantic element) 在 HTML5 之前,通常是用 DIV 元素来分隔。

DIV 元素,即文档分区元素(Content Division element),是一个通用的容器,可以包含各种子元素,比如 UL, H1, P, IMG, DIV 等。在 HTML5 之前,只能用 DIV 来组织文档的逻辑结构,在 HTML5 之后,建议在不同的场景下使用不同的更加准确的语义元素,比如 HEADER, FOOTER, ARTICLE 等,虽然浏览器展示没有分别。

语义元素的好处,请参考 https://developer.mozilla.org/en-US/docs/Glossary/Semantics#Semantics_in_HTML

this website is made by Simon1987

效果:

this website is made by Simon1987

STRONG, SPAN 元素

STRONG 元素 ()表示文本十分重要,浏览器通常会用粗体显示。元素是一个文字容器,没有任何特殊语义,经常用来配合 CSS 显示不同的样式。与 DIV 同样是通用的容器,区别是 DIV 是块级元素的容器,可以包含块级元素和行内元素,而 SPAN 只能包含行内元素。

蜘蛛侠(英语:Spider-Man)是漫威漫画的超级英雄。本名为彼得·班杰明·帕克(Peter Benjamin Parker)他是由作家/编辑史丹·李及作家/画家史蒂夫·迪特科所创造。

效果:

蜘蛛侠(英语:Spider-Man)是漫威漫画的超级英雄。本名为彼得·班杰明·帕克(Peter Benjamin Parker)他是由作家/编辑史丹·李及作家/画家史蒂夫·迪特科所创造。

FORM, INPUT, BUTTON 等表单交互性元素

块级元素(Block-level elements)和行内元素(Inline elements)

有些元素属于块级元素,有些属于行内元素。上文中的

-
,

,

    ,
      ,
      ,
      ,
      ,
      ,

      ,

      属于块级元素,, , , 属于行内元素。

      块级元素默认会占满父元素的宽度,前后各新起一行,隔断(Block)其之前与之后的元素。而行内元素默认不会新起一行,大小取决于自己的内容。看下面2个例子:

      行内元素,代码如下:

      下面的元素是行内元素,行内元素,行内元素不会换行,大小取决于自身的内容。

      效果:

      下面的元素是行内元素,行内元素,行内元素不会换行,大小取决于自身的内容。

      块级元素,代码如下:

      下面的元素是块级元素,

      块级元素,

      块级元素默认会占满父元素的宽度,前后各新起一行,隔断(Block)其之前与之后的元素。

      效果:

      下面的元素是块级元素,

      块级元素,

      块级元素默认会占满父元素的宽度,前后各新起一行,隔断(Block)其之前与之后的元素。

      其中 style 属性在 CSS 章节会详细解释,在这里只要知道它让背景变色就好了。在 CSS 章节中我们会看到可以通过 CSS 改变元素是否块级元素或者行内元素。

      一些全局属性(Global attributes)

      全局属性是所有 HTML 元素共有的属性; 它们可以用于所有元素,即使属性可能对某些元素不起作用。

      id 属性

      id 属性给标签定义唯一标识,例如

      一篇文章
      ,这时候这个 DIV 元素就有了自己的唯一标识 id 为 container。页面中不允许出现另外的 id 为 container 的元素了。如果当前页面有个超链接
      一篇文章,点击这个超链接浏览器便会跳转到上文的 DIV 标签处。另外 id 还可以配合 CSS 选择器,作用于 CSS 和 JavaScript。分别在 CSS 章节和 JavaScript 章节会介绍。

      class 属性

      一个以空格分隔的元素的类名(classes )列表,例如

      ,这里我们给 DIV 元素设置了 2 个不同的类,分别是 container 和 important。有了这个类,我们就可以在 CSS 或者 JavaScript 中通过这个类名,找到这个元素。分别在 CSS 章节和 JavaScript 章节会介绍。

      style 属性

      style 属性可以给元素设置 CSS 样式,例如行内元素,这里 span 中的内容会显示黄色。在 CSS 章节会详细介绍。

      onclick,oncontextmenu,onfocus,onscroll,onblur 等事件相关的属性

      这些属性表示在当前元素发生某种事件时应该作出的反应。标签的值是一段 JavaScript 脚本。例如hello表示这个 A 元素在点击时会执行alert('hello')这个脚本。关于这个脚本的含义在 JavaScript 章节会介绍。

      如果 HTML 文档不符合规则了?

      规则有很多,例如上文中介绍的:

      1. 很多 HTML 的元素只可以包含一部分 HTML 元素,不是任何内容都可以成为元素的内容。比如
          元素只可以包含
        • 元素作为子元素, 元素只可以包含 等。
        • 属性有限制。例如 id 属性必须是唯一的。
        • 是否可以省略结束标签。例如
          , 元素没有结束标签。

      这些都是在编码时需要注意的规则。如果不符合规则,会发生未定义的行为,所谓未定义意思是 W3C 标准中没有规定发生这种情况浏览器应该如何处理,于是浏览器会自行处理。很多情况的小错误,浏览器会自动纠正,比如
      写成了
      浏览器通常不会显示错误,能够正常显示。再比如给多个元素设置同样的 id 属性,浏览器仍然可以正常显示内容,但是这个可能引起相关 CSS 样式和 JavaScript 的错误。

      语义类标签是什么,使用它有什么好处?

      语义类标签也是大家工作中经常会用到的一类标签,它们的特点是视觉表现上互相都差不多,主要的区别在于它们表示了不同的语义,比如大家会经常见到的 section、nav、p,这些都是语义类的标签。

      语义是我们说话表达的意思,多数的语义实际上都是由文字来承载的。语义类标签则是纯文字的补充,比如标题、自然段、章节、列表,这些内容都是纯文字无法表达的,我们需要依靠语义标签代为表达。

      在讲语义之前,我们来说说为什么要用语义。

      现在我们很多的前端工程师写起代码来,多数都不用复杂的语义标签, 只靠 div 和 span 就能走天下了。

      这样做行不行呢?毫无疑问答案是行。那这样做好不好呢?按照正确的套路,我应该说不好,但是在很多情况下,答案其实是好。

      这是因为在现代互联网产品里,HTML 用于描述“软件界面”多过于“富文本”,而软件界面里的东西,实际上几乎是没有语义的。比如说,我们做了一个购物车功能,我们一定要给每个购物车里的商品套上 ul 吗?比如说,加入购物车这个按钮,我们一定要用 Button 吗?

      实际上我觉得没必要,因为这个场景里面,跟文本中的列表,以及表单中的 Button,其实已经相差很远了,所以,我支持在任何“软件界面”的场景中,直接使用 div 和 span。

      不过,在很多工作场景里,语义类标签也有它们自己无可替代的优点。正确地使用语义标签可以带来很多好处

      1、语义类标签对开发者更为友好,使用语义类标签增强了可读性,即便是在没有 CSS 的时候,开发者也能够清晰地看出网页的结构,也更为便于团队的开发和维护。
      2、除了对人类友好之外,语义类标签也十分适宜机器阅读。它的文字表现力丰富,更适合搜索引擎检索(SEO),也可以让搜索引擎爬虫更好地获取到更多有效信息,有效提升网页的搜索量,并且语义类还可以支持读屏软件,根据文章可以自动生成目录等等。

      不过,不恰当地使用语义标签,反而会造成负面作用。这里我们举一个常见的误区作为例子。我们都知道 ul 是无序列表,ol 是有序列表,所以很多接触过语义这个概念,半懂不懂的前端工程师,特别喜欢给所有并列关系的元素都套上 ul。
      实际上, ul 是长成下面的这种样子的 (以下来自 HTML 标准)。

      I have lived in the following countries:

      Switzerland
      Norway
      United Kingdom
      United States
      ul 多数出现正在行文中间,它的上文多数在提示:要列举某些项。但是,如果所有并列关系都用 ul,会造成大量冗余标签。

      错误地使用语义标签,会给机器阅读造成混淆、增加嵌套,给 CSS 编写加重负担。

      所以,对于语义标签,我的态度是:“用对”比“不用”好,“不用”比“用错”好。当然了,我觉得有理想的前端工程师还是应该去追求“用对”它们。

      总结

      本章介绍了一些常用的 HTML 元素,有了这些元素,就已经可以做出基本的网页了。到这个时候,HTML 的任务已经完成了:定义内容和定义内容的逻辑结构。但是这个网页视觉效果十分基础,可以说是极简主义设计了,下一步就是进入 CSS 的学习,给网页添加样式。

      当然 HTML 元素比本章介绍的这些多很多,大家可以自行查阅文档学习剩下的部分,也可以在实际使用中根据场景再进行针对性学习。

      参考文档

      • 完整的元素列表及文档:https://developer.mozilla.org/en-US/docs/Web/HTML/Element
      • HTML中的语义元素:https://developer.mozilla.org/en-US/docs/Glossary/Semantics#Semantics_in_HTML

      CSS (层叠样式表 Cascading Style Sheets) 概述

      怎样允许为一个固定的 HTML 设置无限种可能的样式?所谓样式,即视觉效果。肉眼能分辨的事物基本包含3种:大小,距离,色彩,形状:

      • 大小:可以设置元素的长度,宽度,文字的字号,行高等。
      • 距离:元素之间的距离,文字之间的距离
      • 色彩:可以设置元素的背景色,背景图片,边框颜色,文字颜色
      • 形状:可以设置矩形边框,圆角边框,文字的字体

      上面的几点可能能够满足平面设计的需求,但是无法满足网页设计的需求,原因是:

      • 浏览器的大小不一。例如分辨率是 1920x1080 和分辨率 1024x768,对于前者,我们让宽度为 20 的元素的左边距为 950 即可达到居中的效果,而同样的设置,显然无法在后者的分辨率下显示居中。例如,在较宽的屏幕我们希望一行显示4列,而在较窄的屏幕,比如手机等移动设备,我们希望一行显示1列。
      • 网页有交互。例如多数网页都可以向下滚动,而我们希望导航栏在滚动时依然保持在最上面的位置。例如当鼠标在某个链接上方时,我们希望改变链接的样式。(复杂的交互可以通过 JavaScript 实现,本章不讨论)
      • 需要动画特效。比如我们希望元素有淡入淡出等效果。

      而 CSS 可以满足以上绝大部分的需求。如果能配合 JavaScript (在下一章介绍)更有无限种可能。

      CSS 基本语法

      CSS 语法的思路是:

      1. 选中元素
      2. 设置属性和值

      内联样式 (inline style)

      使用 style 属性设置 CSS 的方式叫内联样式 (inline style)

      一个例子,代码和效果如下:

      内联样式

      内联样式

      在上面的例子中,我们通过给元素添加style属性选中元素,设置了属性(property)colortext-align值(value)分别为yellowcenter。属性和值连起来叫声明(declaration),多个声明用分号;隔开,格式为:

      <属性>:<值>;<属性2>:<值2>;...
      

      在需要设置很多元素为相同的样式时,内联样式这样做显然比较冗长,混合了内容与样式的代码,在修改时也不方便,还不支持所有 css 功能,比如不支持伪类(pseudo-class)媒体查询(media query)。所以一般不推荐这种做法。

      内部样式

      所谓内部样式是指通过

      内部样式

      内联样式

      通过内部样式,将样式与 HTML 分离开来了,这样 html 就看起来更加清晰,特别是在复杂的网页的情况下。但是这样需要选中元素,选中元素使用CSS 选择器(CSS Selector),上看的例子中 鼠标悬停效果

      
      

      包括:hover,一共有几十种 css 伪类,常用的有以下:

      更多的伪类可以查看 MDN 文档:CSS 伪类。

      伪元素选择器

      伪元素的写法与伪类相似,区别是伪元素用“::”分隔(旧的标准也是用“:”)。伪元素可以选择本身不是 HTML 标签定义的元素。

      • ::first-letter代表第一个字母,中文则是第一个汉字
      • ::first-line代表第一行
      • ::before会在当前元素内增加一个内部伪元素,并置于所有子元素之前。定义的样式将作用于增加的元素
      • ::after会在当前元素内增加一个内部伪元素,并置于所有子元素之后。定义的样式将作用于增加的元素
      • ::selection代表鼠标选中的文字的

      新的 CSS 标准 css-pseudo-4 定义了更多的伪元素,浏览器实现程度不一,可以自行查阅。

      下面是两个例子,说明请看注释:

      
      

      这是一个::first-letter的例子,这是一个::first-letter的例子,这是一个::first-letter的例子,这是一个::first-letter的例子,这是一个::first-letter的例子,这是一个::first-letter的例子

      https://www.w3.org/

      选中后样式变化

      这是一个::first-letter的例子,这是一个::first-letter的例子,这是一个::first-letter的例子,这是一个::first-letter的例子,这是一个::first-letter的例子,这是一个::first-letter的例子

      https://www.w3.org

      选中后样式变化

      参考文档

      • CSS 选择器:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors
      • 伪类:https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes
      
      

      CSS 长度单位

      CSS 中设置大小是基本操作,本节介绍常用的长度单位。width, height, margin, padding, border-width, font-size, 和 text-shadow 等等 CSS 属性都需要使用长度单位。

      像素 px

      浏览器的像素与设备像素(device pixel)不一样。我们在 CSS 中设置的像素实际为逻辑像素。为了了解清楚其区别和缘由,必须先解释下设备像素,DPI,DPPX 和逻辑分辨率。

      一般的显示器是由一个一个微小的可发光的灯一排一排组成,每个灯叫“像素 (pixel)”。如果一个显示器的分辨率是 1920×1080,代表每一排有 1920 个像素,一共有 1080 排。所以,同样面积分辨率越大,画面就越细腻,因为有更密集的像素点,甚至肉眼无法看到屏幕的像素点,即所谓“视网膜屏幕”。这个属性是生产好显示器就确定了的,称作:设备分辨率设备像素。有时候也称为物理分辨率。

      分辨率 1280×720px 经常被称作 720p。分辨率 1920×1080px 经常被称作 1080p,如果水平像素点达到 2000 左右,可以被称为 2k 分辨率,例如 2560×1600px,如果水平像素点达到 4000 左右,可以被称作 4k 分辨率,例如 3840×2160px。

      DPI(Dots per inch), PPI(Pixels per inch)

      分辨率和像素的密集程度没有关系,因为分辨率不反映面积,而反应像素密集程度的单位是 DPI(Dots per inch) 或者严格说来对于显示器是 PPI(Pixels per inch), 不过很多场合这两者不作区分,这里为了方便直接称作 DPI。

      显示器的物理大小通常不会相差很大,特别是笔记本,家用台式机。因此 2k/4k 分辨率的显示器,通常会有更高的 DPI。也能够显示更细致的画面。

      逻辑分辨率(Logic Resolution)

      试想一下,如果我们有一个 100px 的图,我们的显示器是 1080p 的,现在我们升级显示器到 4k 分辨率的(屏幕尺寸不变,即 4 倍 DPI),这张图就会变成之前的 1/4 大小,文字也是同样的现象。这当然不是我们希望的,因为我们的眼睛没有跟屏幕一起升级,无法轻松辨认原先 1/4 大小的文字或图像。

      于是操作系统设计了逻辑分辨率(Logic Resolution),可以让 4k 的显示器的逻辑分辨率为 1920×1080, 让 4 个设备像素显示原来的 1 个设备像素,这样我们的 100px 的图片就不会过分缩小了。

      DPPX(Dots per px unit) & Device Pixel Ratio

      在上面的例子中,我们将 4K 的显示器设置了 1920×1080 的逻辑分辨率。因此现在的 1 个逻辑像素,其实是有 4 个设备像素显示的,即 4 DPPX(Dots per px unit),设备像素比(Device Pixel Ratio)为 4。其中 DPPX 是的 w3c 标准化的名称,Device Pixel Ratio 会在一些旧的浏览器及文档中使用。

      Windows 和 Mac 都可以设置显示的逻辑分辨率,以这台 Mac 为例:

      设备分辨率(物理分辨率)为 2560×1600:


      image.png

      当前设置的逻辑分辨率为 1280×800:


      image.png

      设置好逻辑分辨率,我们的图片,文字就不会在不同 DPI 显示器显示的大小差异很大了。

      但是这里有个问题:上文的例子中,原本 100×100px 的图片在高 DPI 的显示器上,用 400×400 个物理像素显示,那多余的像素怎么来呢?操作系统或者软件会进行缩放计算,得出应该填充的像素颜色。如果 dpi 是原先的两倍,那么 3/4 的像素都是计算得出的,因此图片会变的模糊。这种情况可以在高 DPI 的情况下使用同样图片的高分辨率版本,同时设置逻辑像素不变。例如将 400×400px 的图片,在 4 DPPX 的显示器上设置为 100×100px 的大小显示。通过 CSS 媒体查询(Media query) 技术可以实现。另外如果图片是“矢量图”的话,则可以自动适应不同的 DPPX,例如 SVG 图片。

      在 HTML/CSS 中,设置的像素 px 实际是设置的和逻辑分辨率对应的逻辑像素,例如:

      p {
        width: 500px;
        font-size: 20px;
      }
      

      rem & em

      px 是绝对单位(absolute units),CSS 中还有相对单位,例如 rem 和 em。这两者都是相对于字体大小(font-size)的单位,1 rem 就是 1 倍字体大小,2 rem 就是 2倍字体大小。区别是相对于的字体来源,rem 是相对于根元素(即 html 元素)的字体(font-size)大小,而 em 是相对于当前继承的font-size大小。由于 em 受font-size的继承关系影响,因此推荐使用 rem 作单位。

      vh && vw

      vh(viewport height) 代表 viewport 高度的 1% 大小,vw(viewport width) 代表 viewport 高度的 1% 大小。

      viewport 即浏览器的可见区域。不一定和网页一样大,例如:调节浏览器放大网页,这时候网页可能变的比浏览器更大,浏览器就好像一个窗口一样,通过他来看到整个网页的一部分,所以叫做 viewport。如果希望一个元素能正好和浏览器显示区域一样大,那么可以设置:

      #fullsize {
        height: 100vh;
        width: 100vw;
      }
      

      百分比单位

      百分比单位可以设置一个元素的大小为其父元素的一个百分比,父元素放大/缩小,子元素也会随之改变。例如:

      
      
      
      

      百分比使用在font-size时相对的不是父元素,而是继承到的font-size大小,和 em 效果相同。例如 font-size: 200%font-size: 2em 效果一样。

      0

      在使用 0 时不需要加单位。例如 margin: 0

      其他长度单位

      上文介绍了常用的长度单位,可以满足常见需求。
      其他长度单位可以查看MDN 文档:values & units

      参考

      • https://www.wikiwand.com/en/2K_resolution
      • 查询各设备的 DPI: http://dpi.lv/
      • pixels physical vs logical https://blog.specctr.com/pixels-physical-vs-logical-c84710199d62
      • DPPX https://www.w3.org/TR/css-values-4/#dppx

      CSS 盒模型 (Box Model)

      CSS 能控制大小和距离,有哪些地方的大小和距离可以控制呢?CSS 是通过一个叫做“盒模型 (Box Model)”的模型来描述页面上所有的元素,通过设置这个“盒子”的各种属性,就可以调整任意元素的大小,距离了。

      这个盒模型如下

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

      可以看到,在盒模型中,每个元素都有 外边距 (margin)边框 (border)内边距 (padding)内容(content) 属性。这几个属性很常用,在 CSS 中是 margin, border, padding 属性,下文将直接使用英文。

      设想一下,我们用一个盒子装东西。不同盒子之间有个距离,为 margin,盒子本身有个边框,为 border,盒子与里面的东西之间还有一定的距离,为 padding。最里面才是盒子里面装的东西。

      Margin

      margin 定义了元素和其他元素之间的距离。即如果希望两个元素靠近,则设置较小 margin,如果希望距离大,设置较大 margin。margin 可以为负,这样两个元素可能会重叠。

      margin 有个特殊的属性是他可以重叠(margin collapse):相邻的元素的距离,以他们的 margin 比较大的那个决定,而不是他们的和。例如 a, b 两个元素,margin 分别是 10px, 20px 那么他们的距离是 20px。

      margin 有4个方向,上右下左分别为 margin-top, margin-right, margin-bottom 和 margin-bottom。可以分别设置。

      margin 的写法如下:

      • 分别设置 4 个方向: margin: 10px 20px 10px 20px。顺序是“上右下左”的顺时针顺序。
      • 缩写 margin: 10px 20px 效果是 maring-top 和 mrgin-bottom 为 10px,margin-right 和 margin-left 为 20px。缩写 margin: 10px 效果是 4 个方向的外边距都为 10px。
      • 可以单独设置 1 个方向:margin-top: 10px 上外边距为 10px。
      • 可以设置margin: auto 这时候浏览器会给一个适当的值,经常用来让块级元素水平居中。

      Border

      Border 定义了元素的边框,除了可以设置边框的大小粗细,还可以设置边框的样式,颜色以及圆角。大部分元素默认没有边框。

      border 写法如下:

      • 设置粗细:border-width: 2px
      • 设置样式:border-style: dashedborder-style 的值还可以为 soliddotted 等。可以查看完整文档。
      • 设置颜色:border-color: red
      • 设置圆角:border-radius: 5px
      • border-width, border-style, border-color 可以缩写为:border: 2px dashed red
      • 可以单独设置某一边的 border: border-right: 2px dashed red

      Padding

      Padding 定义了元素的内边距,即边框与内容间的距离。padding 的值也可以为负。

      写法与 margin 类似,只是属性值没有auto

      • 分别设置 4 个方向: padding: 10px 20px 10px 20px。顺序是“上右下左”的顺时针顺序。
      • 缩写 padding: 10px 20px 效果是 padding-top 和 padding-bottom 为 10px,padding-right 和 padding-left 为 20px。缩写 padding: 10px 效果是 4 个方向的内边距都为 10px。
      • 可以单独设置 1 个方向:padding-top: 10px 上内边距为 10px。

      内容大小

      width, height 来设置内容大小,例如 width: 100px 设置了内容大小为 100px,如果与个元素有 20px 的 padding 以及 5px 的border,不算 margin, 元素的占用宽度为 100px + 20px × 2 + 5px × 2 即 150px。

      在这个例子里,计算元素的宽度实在麻烦。例如我们希望设置 200px 宽的元素,需要计算 border 和 padding。而 border 和 padding 在调试外观样式的时候需要频繁修改,这样让布局变的困难。于是在 CSS3 中引入了 box-sizing 属性,让大小设置更为直观简单。

      box-sizing 属性

      box-sizing 有 2 值可以设置:content-box 和 border-box。

      • content-box: 默认设置,元素占用空间的大小需要 width 加上 border 和 padding。
      • border-box: 元素占用空间的大小为 width 的值。如果设置了 border 和 padding,则会挤占内容的大小,而不会撑大元素的占用空间。

      一个建议的做法是设置所有元素的 box-sizing 属性都为 border-box,例如:

      html {
        box-sizing: border-box;
      }
      
      *, *:before, *:after {
        box-sizing: inherit; /* box-sizing 默认不继承父元素的值 */
      }
      

      标准盒子模型与IE盒子模型

      标准盒子模型.jpg

      IE盒子模型.jpg

      参考文档

      • inheriting box sizing probably slightly better best practice: https://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/

你可能感兴趣的:(GDG第一场前端分享)