作者:我没有三颗心脏
本文已收录至我的GitHub
前言
现在我们来学习一些基础的 HTML/ CSS 知识。希望阅读完这篇文章能达到编写简单页面的程度。
目录:
HTML/ CSS 的发明;HTML 基础;CSS 基础;页面是如何渲染的;Part 1. HTML/ CSS 的发明
1989 年 3 月,互联网还只属于少数人。
《图解 HTTP》同年,蒂姆·伯纳斯·李(Tim Berners-Lee)提出了一种能让远隔两地的研究者们共享知识的设想。
这一想法的实践促使了万维网的诞生。它基于现有的 TCP/IP 协议构建,包括 4 个部分:
一种表示超文本文档的文本格式,即超文本标记语言(HTML);一种用于交换这些文档的简单协议,即 HyperText 传输协议(HTTP);一个客户端可以显示这些文档,第一个 Web 浏览器称为 WorldWideWeb。一个可以访问文档的服务器;这四部分在 1990 年底完成。虽然此时 Web 页面只能显示单纯的文本内容,浏览器也只能显示呆板的文字信息,不过这已经基本满足了建立 Web 站点的初衷,实现了信息资源共享。
1991 年创建的第一个网页从 HTML 被发明开始,样式就以各种形式存在。不同的浏览器结合它们各自的样式语言为用户提供页面效果的控制。
随着 HTML 的成长,为了满足页面设计者的要求,HTML 添加了很多显示功能。但是随着这些功能的增加,HTML 变的越来越杂乱,而且 HTML 页面也越来越臃肿。于是 CSS 便诞生了。
1995 年 www 网络会议上 CSS 被提出。同年,W3C 组织成立,层叠样式表的开发就此走上正轨。
HTML 负责网页内容,CSS 负责内容的基本样式。
Part 2. HTML 基础
什么是 HTML
HTML 是 Hper Text Markup Language 的简称,即超文本标记语言。它就像我们熟知的 Word 一样,只不过它适用于 Web。
HTML 同 Word 一样提供了标题、段落、列表、表格、图像、粗体、斜体等文本来构建文档。关键区别在于 Word 中的格式文本是可视的,而HTML 代码纯粹是语义的。
HTML 基础
像任何语言一样,HTML 带有一组规则。这些规则相对简单,就是要界定界限——知道从哪里开始,从哪里结束。
例如,HTML 表示的段落将被写为:
说明:
一对尖括号 (</ >)中间的就是 HTML 标签。不同的标签有不同的含义。这里的 p 代表了一个段落的意思;HTML 标签通常成对出现,开始标签(opening tag)<p>定义了段落的开始,结束标签(closing tag)</p>定义了结束;开始和结束标签之间唯一的区别就是标签名称前的斜杠 /;当您把开始标签和结束标签以及两者之间所有内容组合在一起时,就获得了一个 HTML 元素;标签(尖括号内的内容都)不会被显示,仅仅用于区分内容的语义并提供一些默认的样式;在哪里写 HTML?
就像我们熟知的 .txt 文本文件一样, HTML 文档(后缀为 .html)也可以使用任意文本编辑器打开。
打开您的任一文本编辑器,然后复制并粘贴以下内容:
<p>这是我的第一个网页</p>将文件另存为 my-first-webpage.html ,然后使用浏览器将其打开,您就会看到:
用预览来简单展示啦但实际上,我们一般会选择更加专业的软件:
推荐 WebStorm属性
属性就像绑定到 HTML 元素的额外信息一样。它们写在 HTML 标签内,所以,浏览器也不会显示它们。
例如,href 属性就是用来定义 a 标签跳转目标链接的属性:
<a href=“https://www.wmyskxz.com/”>点击会跳转到我的主页</a>有 16 个 HTML 属性可用于任何 HTML 元素,所有这些都是可选的。
我们最常用的就是 class 属性(用于 CSS)。
一些 HTML 元素具有强制属性。例如,插入图片时,必须使用 src (source)属性来提供图像的位置:
<img src=“#” alt=“Description of the image”>考虑到 <img> 标签的意义,强制性的要求设置显示图像的路径,是有意义的。
注释
如果你有一些不想显示但是又想提醒代码阅读者的一些事情,通常可以添加注释。
HTML 注释以 <!– 开始,以 –> 结束。如下所示:
<!– This is an HTML comment –> that spans across more than one line –><p>This is a normal piece of text.</p>您还可以注释掉部分 HTML 代码来进行调试,如下所示:
–>自封闭元素
一些 HTML 元素只有一个开始标签:
<br> <!– 换行标签 –><img src=“#” alt=“Description”> <!– 图像标签 –><input type=“text”> <!– 文字输入标签 –>因为它们没有结束标签,因此内部不能包含任何内容。所以自封闭元素通常带有一些属性,以便为它们提供附加信息。
HTML 块和内联
在 HTML 中,您主要会遇到两种类型的 HTML 元素:
块元素用于通过将内容划分为连贯的块来构造页面的主要部分。
<p>这是第一段内容</p><p>这是第二段内容</p>内联元素旨在区分文本的一部分,以赋予其特定的功能或含义。内联元素通常包含一个或几个单词。
<p>如果感兴趣,可以点击<a href=“https://www.wmyskxz.com”>这里</a>来访问我的主页</p>开始和结束标签
所有块级元素都有一个开始和结束标签。
所以,自封闭元素都是内联元素,仅仅是因为它们的语法不允许它们包含任何其他 HTML 元素。
HTML 层次结构
HTML 文档就像一棵大的家族树,上面有父母、兄弟姐妹、孩子、祖先和后代等。
这源于 HTML 元素具有相互嵌套的功能。
嵌套
让我们编写一个简单的段落,并通过插入两个内联元素来区分文本各个部分来对其进行增强:
<p> <strong>培根</strong>曾经说过:<q>合理安排时间,就等于节约时间</q>。
</p>结果:
其中:
<strong> 对「培根」这一个词语进行了强调;<q> 对「合理安排时间,就等于节约时间」这句话加上了引号;使用 <strong> 会加粗标签内的内容,这只是浏览器的默认行为。请注意:您必须根据 HTML 元素的含义而非其外观来选择 HTML 元素。
这种情况下:
<p> 是 <strong> 和 <q> 标签的父元素;<strong> 和 <q> 同为 <p> 元素的子元素;<strong> 和 <q> 是同级元素;顺序
如何嵌套HTML 文档取决于打开和关闭标签的位置。
由于 HTML 元素包含打开和关闭标签,以及介于两个标签之间的内容,一个子元素的关闭必须结束于父元素之前。
<!– This is INVALID code! 🙁 –><p> This HTML code wont work because I the “strong” tag is opened here <strong>but is only closed after the paragraph.
</p></strong>上述代码是不合法的,因为 <strong> 标签打开在 <p> 标签之后(因此 <strong> 被认为是 <p> 的子元素),所以 <strong> 必须在 <p> 元素关闭之前关闭。
<!– This is valid code. 🙂 –><p>This HTML code will work because I the “strong” tag is opened<strong>and closed</strong>properly.
</p>深度
由于子元素本身可以包含其他子元素,所以可以在 HTML 文档中编写更深的层次结构。
例如,我们可以编写一段:
<article> <h1>题图故事:光努力是没有用的</h1> <p> 漫画家蔡志忠有一个演讲,题目叫做<a href=“https://www.yuque.com/book-academy/share/shp7tu”>《努力是没有用的》</a>。读完这份演讲稿,我觉得他说的有道理。
</p> <p>有些人非常勤奋,别人休息和娱乐的时候,都在工作学习。但是努力了一辈子,人生也没有显著的提升,就像报道里经常说的:<q>某某在平凡的岗位上,勤勤恳恳工作了一辈子</q>。
</p> <p>另一方面,很多成功者似乎也没有特别努力,就取得了许多成就,过上了好日子。蔡志忠以自己为例,他从小就喜欢画画,然后一直画,不知不觉就成了大漫画家,名利双收,从没有觉得过得很辛苦。
</p></article>结果:
在这种情况下,该 HTML 文档的家族树看起来会是这样:
<h1> 和三个 <p> 是兄弟姐妹;每个 <p> 的父亲都是 <article>;每个元素(除开 <article>)都是 <article> 的后代;
块元素和内联元素嵌套
块元素可以包含块元素或内联元素。
但是,内联元素只能包含其他内联元素。(<a> 标签除外)
<!– This is INVALID code! 🙁 –><strong> <p>You cant put a paragraph inside a “strong” tag.
</strong>但是要记住元素的家族树。这种层次结构在 CSS 中很有用。
HTML 是语义的
HTML 标记的目的是向文档传递含义。所以不必担心网页的外观,应该关心每个标签的含义。
选择合适匹配的元素
根据要编写的内容,可以选择与文本含义相匹配的适当元素。
不要过分考虑语义
大约有 100 个语义 HTML 元素可供选择。遍历该列表并为您的内容选择适当的元素可能会让人不知所措。
但是不要花太多时间担心这一点。基本上能用好上面的标签就足够好了。
一个有效的 HTML 文档
HTML 文档需要特定的结构才能生效。
文档类型
提供的第一个信息就是我们正在编写的 HTML 文档的类型:Doctype。
曾经有很多 HTML 版本共存。如今,HTML 5 已经成为规范。
所以,我们要告诉浏览器这个 HTML 文档是 HTML 5 的版本,只需要在最开始写上:
<!DOCTYPE html>注意:HTML 是大小写不敏感的。这意味着你只需要单词拼写对就可以了——但仍需要保持规范。
“HTML 5 文档类型没有提到数字 “5” 的原因是:W3C 认为以前的文档类型定义太混乱了,借机吧任何 HTML 版本的信息都给简化掉了。
<html> 元素
除了 doctype 外,所有 HTML 文档都必须包装在一个 <html> 元素内:
<!DOCTYPE html><html> <!– The rest of your HTML code is here –></html><head>
<head> 标签相当于整个页面(<html> 包裹的内容)的属性。为整个页面提供了附加的额外信息,并且不会显示。
例如,文档的标题就包含在 <head> 标签内:
<!DOCTYPE html><html> <head> <title>网页标题</title> </head></html><body>
<body> 使我们编写所有网页内容的地方。里面的所有内容都会显示在浏览器窗口中。
完整的有效 HTML 文档
综合所有这些要求,我们可以编写一个简单有效的 HTML 文档:
<!DOCTYPE html><html> <head> <title>Java3y</title> </head> <body> <p>欢迎关注公众号:Java3y</p> </body></html>浏览器视角:
Part 3. CSS 基础
为什么存在 CSS?
随着 90 年代网络的普及,将特定设计应用于网站的意图也随之增强。Web 开发人员依靠特定的 HTML 标签来增强网页显示:
<basefont> 为整个 HTML 文档定义了一种字体<font> 为它包含的文本定义字体,颜色和大小<center> 将所有内容水平居中<big> 增加文字大小<strike> 带有删除线的渲染文本也可以使用几个 HTML 属性:
bgcolor 在元素上定义背景色text 定义文字颜色几个margin属性可用于在元素的任何一侧添加间隔的空间但最重要的是,为了创建视觉上对齐(通常是彼此定位)的元素,Web 开发人员通常会使用 <table> 来设计网页,因为它自然地提供了视觉网格:
但这种方法很麻烦,原因如下:
HTML <table> 定义是冗长的:它们需要很多样板代码标签在语义上是错误的:<table> 应该用于多维数据更改布局需要更改标签:如果我们想将左列移动到右侧,则必须修改 HTML 结构容易出现语法错误:行和单元格需要按特定顺序进行排序和嵌套才能有效标签不可读:表格之间相互嵌套这就是为什么逐渐放弃使用表进行布局的原因,而改用 CSS 的原因。
什么是 CSS?
CSS 是 CascadingStyle Sheets 的缩写,即层叠样式表。其目的是为标记语言(如 HTML 或 XML)设置样式。因此,CSS 本身一文不值,除非与 HTML 文档相关联。
CSS 通过设置字体、颜色,定义边距、定位元素、动画交互等等,使 HTML 文档栩栩如生。
CSS 是如何工作的?
CSS 的工作方式是选择一个 HTML 元素(如一个段落),选择一个要更改的属性(如颜色),并应用一个特定的值(如红色):
p {color: red;}
““样式” 一词可能具有欺骗性。CSS 不仅仅可以用于修改文本的颜色、大小、字体等,还可以用来定义高度、宽度、内部和外部的边距、位置等。
我在哪里写 CSS?
CSS 作为标签属性
您可以使用 style 属性直接在 HTML 元素上编写 CSS:
<p style=“color: red;”>This paragraph will be red.</p>结果:
<head> 中的 CSS
您也可以在 <head> 中使用 <style> 标签来使用 CSS:
<html> <head> <title>Hello World</title> <style type=“text/css”> p{ color: red;}
</style> </head> <body> <p>This paragraph will be red.</p> </body></html>结果:
CSS 在单独的文件中
您也可以把 CSS 编写为带有 .css 扩展名的单独文件,然后使用 <link> 标签来将其链接到 HTML 中:
p{ color: red;}
<html> <head> <title>Hello World</title> <link rel=“stylesheet” type=“text/css” href=“style.css”> </head> <body> <p>This paragraph will be red.</p> </body></html>目录结构:
Desktop
├── style.css
├── my-first-webpage.html
结果:
这种单独使用一个 CSS 文件的方法是优选的。
为什么不直接在 HTML 中设置样式?
因为我们要把内容和其表示形式分开。这样做的好处显而易见。
首先是可阅读性变高了,有哪些元素,以及元素哪些属性一目了然,也利于分别维护和修改。(类似于书的目录和对应内容一样)
另外是你可以提炼一些通用的属性来减少描述:
简而言之:更易维护、更灵活。不过应该怎么描述是相当看经验的。
CSS 基础语法
CSS 的目的是定义 HTML 元素的布局和样式。语法非常简单:
/* A CSS rule */selector{ property: value;}
您也可以将其看作是:
who{ what: how;}
CSS 选择器
因为我们不想一次为所有 HTML 元素设置样式,所以我们需要能够定位这些 HTML 元素的子集。
CSS 选择器定义了我们希望样式应用到哪些元素。
通用标签选择器
定位通用 HTML 标签很容易:只需使用标签名称即可。
a{ /* Links */}
p{ /* Paragraphs */}
ul{ /* Unordered lists */}
li{ /* List items */}
HTML 标签的名称和所使用的 CSS 选择器之间存在直接联系。
class
考虑到我们可能不希望所有段落或所有标题的样式都相同,因此需要区分它们。
在所有 HTML 属性中,该 class 属性对于 CSS 来说是最重要的。它允许我们定义一组专门设计的 HTML 元素。只需在要使用的类名前面加一个点 . :
.date{
color: red;
}
这样,所有具有 class=”redColor” 的 HTML 元素都会被设置为红色:
<p class=“date”>Saturday Feb 21
</p><p> The event will be on <em class=“date”>Saturday</em>.
</p>结果:
IDs
你也可以使用 id 属性来作用于 HTML,只需要在 CSS 选择器前面加上 # :
#tagline{ color: orange;}
<h1 id=“tagline”>This heading will be orange.</h1>id 属性有点类似于 class 属性,但 id 只能作用于唯一一个 HTML 元素,而 class 可以作用于一类。
一些例子
组合选择器
我们重用之前的示例,该实例中,我们希望日期显示为红色:
.date{
color: red;
}
<p class=“date”>Saturday Feb 21
</p><p> The event will be on <em class=“date”>Saturday</em>.
</p>但如果我们希望 em 元素中的日期改为蓝色应该怎么办?我们可以添加以下 CSS:
em.date{
color: blue;
}
结果:
该 em.date 选择器仅适用于 <em class=”date”></em> 的 HTML 元素。它不会影响 .date 或 em。
层级选择器
选择器中的空格定义祖先/后代关系。假设我们希望标题中的链接为红色:
header a{
color: red;
}
可以读作:”选择 header 标签内所有的 a 元素”。这样可以防止所有其他链接(不在标题中)受到影响。
伪类选择器
HTML 元素可以具有不同的状态。最常见的情况是当您将鼠标悬停在链接上时。当此类事件发生时,CSS 中可能会应用不同的样式。
伪类选择器附加到常规选择器上,并以冒号开头::
/* 正常情况下的样式 */a{
color: blue;
}
/* 鼠标悬停时的样式 */a:hover{
color: red;
}
CSS 继承
假设我们要更改网页的文本颜色,为每个 HTML 元素指定颜色将很麻烦:
p,
ul,
ol,
li,
h1,
h2,
h3,
h4,
h5,
h6{ color: grey;}
值传递
但其实 color 值是可以从祖先继承的。考虑到我们要更改整个页面,我们可以选择所有 HTML 元素的祖先 body 标签:
body{ color: grey;}
所有子元素和后代元素都将从其共同祖先继承该值。
“当然我们也可以使用 html 标签。
继承的属性
只能从祖先那里继承少数 CSS 属性。它们主要是文本属性:
文字颜色字体(大小/ 字体 Family/ 样式/ 粗细)行高“一些 HTML 元素不会从其祖先那里继承。例如,链接(<a> 标签)不继承该color属性。
CSS 优先级
一个 HTML 元素可以被多个 CSS 规则作为目标。让我们以一个简单的段落为例:
<p class=“message” id=“introduction”>欢迎关注公众号:wmyskxz
</p>我们有三种方式使用 CSS 来对其设置样式:
/* 标签名 */p{ color: blue;}
/* 类名 */.message{ color: green;}
/* id */#introduction{ color: red;}
由于浏览器只能选择一种颜色应用于该段落,因此必须决定哪种 CSS 规则优先于其他规则。这就是 CSS 优先级。
在我们的示例中,该段落将为**红色,**因为#id选择器比其他选择器具有更高优先级。
CSS 规则的顺序
如果您的 CSS 中有类似的选择器,则最后定义的选择器将具有优先权。
p{ color: green;}
p{ color: red;}
/* Paragraphs will be red */快速判断的方法
判断 CSS 优先级的一种快速方法是给选择器的打分:
#id 选择器价值 100.class 选择器价值 10tag 选择器价值 1无论 CSS 出现的顺序如何, “得分”最高的选择器都将优先。
#introduction{ color: red;}
.message{ color: green;}
p{ color: blue;}
<p class=“message” id=“introduction”>欢迎关注公众号:wmyskxz
</p>结果这一段将是红色的。因为 #introduction{ color: red;} ID 选择器具有更高的优先级。
如何避免冲突
在编写CSS时,很容易编写有冲突的规则,比如多次应用同一属性。
为了避免这种情况:
仅使用类:使用.introduction代替#introduction,即使该元素仅在您的网页中出现一次避免在单个 HTML 元素上应用多个类:不要编写<p class=”big red important”>,而是<p class=”title”>在语义上更具描述性;不要使用像这样的内联样式<div style=”background: blue;”>CSS 常用属性一览表
body{
width:100px;/*宽度*/ min-width:1000px;/*最小宽度*/ height :100px;/*高度*/ line-height:100px;/*行高*/ font-family:SimSun,“Microsoft YaHei”;/*字体*/ font-size :16px;/*字体大小*/ font-style :italic;/*字体风格*/ font:16px/26px “微软雅黑”;/*字号/行高 字体*/ color:#ccc;/*字体颜色*/ border-width:10px;/*四边边框粗细*/ border-style:solid;/*四边边框的风格*/ border-color:red;/*四边边框的颜色*/ border:10px solid red;/*border-width,border-style,border-color的简写*/ border-top-width:10px;/*上边框的粗细*/ border-top-style:dashed;/*上边框的风格*/ border-top-color:red;/*上边框的颜色*/ border-top:10px solid red;/*上面三个简写*/ border-radius:2px;/*边框圆角*/ text-align:center;/*left,center,right,justify 水平方向居中*/ letter-spacing:10px;/*字间距*/ word-spacing:10px;/*单词之间的间距*/ text-indent:10px;/*首行缩进*/ margin-top:10px;/*上外边距*/ margin:10px;/*四边外边距*/ padding-top:10px;/*上内边距*/ padding :10px;/*可以设置一,二,三,四种值.内边距*/ float:left;/*right 左浮动,右浮动*/ clear :both;/*清除浮动,,清除左浮动或者右浮动*/ position:relative;/*相对定位*/ position:absolute;/*绝对定位*/ position:fixed;/*固定定位*/ z-index:1;/*设置层叠元素的上下位置*/ background-color:#ddd;/*背景颜色*/ background-image:url(“”);/*背景图片*/ overflow:hidden;/*溢出部分隐藏*/ visibility:hidden;/*隐藏,占位置*/ display:block;/*设为块状元素 块级元素自带的属性*/ display:inline;/*设为行内元素*/ display:inline-block;/*非块状元素的块状盒子*/ display:none;/*隐藏,不占位置*/ opacity:0.5;/*透明度 兼容ie9以上的浏览器*/ filter:alpha(opacity=50)/*设置透明度 兼容i6~ie8*/}
Part 4. 页面是如何渲染的
浏览器具有运行在操作系统之上的”操作系统”的”美称”。这意味着这是一个相当复杂的过程。
对于浏览器如果感兴趣的话,可以参考之前的文章。这里简单回顾一下。
首先,渲染进程内部包含主线程、工作线程、合成线程和光栅线程。
请先想象一个这样的场景:您站在一副简单绘画的面前,如何通过打电话来让您的朋友知道这幅画究竟长什么样子呢?
浏览器实际上要知道绘制些什么元素,每个元素属性如何是要分成三步的:1)通过 HTML 绘制元素树(俗称 DOM 树);2)通过 CSS 文件绘制样式树(俗称 CSSOM 树);3)综合两颗树绘制渲染树(俗称 Render Tree);
现在浏览器知道文档的结构、每个元素的样式、页面的几何形状和绘制顺序,它是如何绘制页面的?把这些信息转换为屏幕上的像素,我们称为光栅化
。
处理这种情况的一种简单的方法是,先在光栅化视窗内的画面,如果用户滚动页面,则移动光栅框,并光栅化填充缺少的部分。这就是 Chrome 首次发布时处理光栅化的方式。
但是,现代浏览器会运行一个更复杂的过程,我们称为合成。
合成是一种将页面的各个部分分层,分别光栅化,并在称为合成线程的单独线程中合成为页面的技术。如果发生滚动,由于图层已经光栅化,因此它所要做的只是合成一个新帧。动画也可以以相同的方式(移动图层和合成新帧)实现。
后记
如今我们纷繁复杂的网页几乎都靠 HTML 和 CSS 来实现。至此,我们已经对它们有了最基础的了解。
– End –
《对线面试官》系列目前已经连载19篇啦!进度是一周更新两篇
,欢迎持续关注
【对线面试官】Java注解【对线面试官】Java泛型【对线面试官】 Java NIO【对线面试官】Java反射 && 动态代理【对线面试官】多线程基础【对线面试官】 CAS【对线面试官】synchronized【对线面试官】AQS&&ReentrantLock【对线面试官】线程池【对线面试官】ThreadLocal【对线面试官】CountDownLatch和CyclicBarrier【对线面试官】List【对线面试官】Map【对线面试官】SpringMVC【对线面试官】Spring基础【对线面试官】SpringBean生命周期【对线面试官】Redis基础【对线面试官】Redis持久化怎样偷偷努力 惊艳所有人?点击小卡片关注【面试造火箭】888