这是我参与「第四届青训营 」笔记创作活动的的第1天。梳理了HTML和CSS的相关知识,借此机会考核并鞭策自己不断完善相关知识。
总纲反思篇
在学习听课的过程中,跟随着讲师的讲解对照着自己的知识储备,发现了如下问题。前端在设计和实现过程中遵从功能、安全、性能、美观、兼容性、无障碍和良好的交互体验这七点元素,目前个人(学生)在所做过的项目集中在完成功能,其他方面很少考虑到,也是急需补充和学习的地方。交互体验和美观就不说了,懂得都懂。重点是了解以下内容:
- 安全性:安全性问题无非是被黑客攻击,只是攻击的位置和方式有所不同,针对浏览器和前端应用,破坏正常运转和窃取资料信息。
- XSS攻击:跨站脚本攻击,浏览器只负责执行不去鉴别是否是属于正常程序内的js代码所导致的问题,通常黑客会将恶意代码注入到我们的页面或者浏览器上触发执行盗窃信息。
- CSRF攻击:跨站点请求伪造,即盗用重要信息例如id等参数伪造一份请求,被服务器接收执行从而导致信息泄露。需要满足A站登录且本地生成cookie,又在B站操作(危险)。
- 点击劫持:挂羊头卖狗肉,在原本的页面中覆盖上一层看不见的幕布,你所点击的增加也许实际操作的是删除。 以上三种就是最为简单和常见的攻击方式,也是我们掌握解决对应问题的安全性只是。除此之外肯定还存在很多类型的黑客攻击手段,自然也有对应的手段进行反制,自己可以深入了解。
- 性能:页面加载速度、交互流畅度等与用户体验感直接相关的部分,性能的好前端除了能带给用户良好的体验外,也能让我们的服务和资源利用更加高效,1块钱当5块钱花的感觉。包括网络层面、数据层面、DOM和渲染层面的优化。
- 兼容性:这方面也是在慢慢变好,向着国际化标准进行中,对于一些头铁的浏览器我们一般的做法是兼容性匹配类似与swatch case一样设计方案和操作,提高兼容性,尽量满足不同版本浏览器要求。
- 无障碍:关注不同群体的使用方法,有针对性的在前端做出改变,比如视力残缺的可以通过屏幕阅读器来了解页面内容,老年人字体放大等等,这个对我们在标签书写的时候有严格要求,比如img必须书写alt属性文本内容等等。
HTML篇
HTML(HyperText Markup Language)即超文本标记语言,在这部分学习过程中使用框架的叫多,对于原生的标签了解比较少,个人的学习见解是常用标签知道,大多数标签有印象,具体使用参照文档。在这一部分学习中有三方面的知识收获:一、标签语义化。二、DOM树的生成过程。三、部分标签的练习。
一、标签语义化
一句相同的话在不同的语境下可能会有完全相反的意思,前端想要实现大一统,形成一套大家都公认的语义化标签是至关重要的。由此,我们的标签也逐渐变得有一定的含义在内了,而不是单单的内容类型包裹层。从页面结构上有header,footer,aside表示主体结构,也有具体到一个部分短文含有h1-h6的标题到section段落等。这样的描述,即便没有CSS修饰,也能够让我们的开发人员对于页面内容结构有一个初步的了解。除此之外,为了提升我们网站的排名,做seo优化帮助爬虫更好的了解我们网页内容也是语义化标签使用的一大优势。
二、DOM树生成
浏览器中的渲染引擎负责html|css的解析,并将最终结果显示出来。我们知道html文档转化为了DOM树,CSS转化为了CSSOM,只有DOM+CSSOM才会形成渲染树(render tree)。今天我们主要集中在DOM树的生成过程。
HTML的解析工作包括编码、预解析、标记和构建树四大部分。需要注意的是在解析过程中比如经过网络请求返回的页面信息,可能包括html,css,js以及外部资源引用,而HTML解析器读取到非HTML内容的时候,就会被阻塞打断继而等其执行完后再继续。
编码:
网络传输过程中,我们接受到的是01二进制字符流,在这个阶段就是反转这个过程,将0/1字符流转换成对应内容。服务器应该通过 Content-Type 字段注明标注格式,这样客户端才可以解析,对于无法确定编码格式的内容浏览器会自行匹配。现在大多数都是UTF-8。
预解析:我们都知道页面的解析过程是自上而下逐条语句执行的,小伙伴们肯定不止一次听到说样式写在HTML前面,JS代码写在HTML后面的代码格式,这都是有道理的。但是一条一条的执行,如果遇到外部资源则停下手头工作,取到对应资源后再进行,这样的处理效率显然是很不计算机了,由此产生了多线程并行的方式来提高解析速度,这些额外的线程需要做的事情也很简答,只负责解析外部资源的引用即可,提前请求拿到资源并保存在内存中,这样当用到的时候就不需要再去请求等待了。
标记:这个过程说实话,我看不太懂,客官可以自己下去深入研究。自己的理解是这样的,我们人书写这段代码的时候是有逻辑和理解意义在内,标记的过程即是让计算机读懂这一段代码的含义,哪一串字符是什么标签,对应的前后标签关系,好比 < p >Hello < / p >他的知道这是一对的,里面有什么内容。
构建树:浏览器已经能够看懂我们HTML代码了,但出于后面的访问一个标签(元素节点)的相关操作,后面的样式添加,绘制等等步骤的执行,都需要一份参考!就好比,我们背课文可能会书写一个段落大意来提示自己,因为如果每次搜索或者操作都要去原文中寻找的话太过于繁琐了。所以就引出了DOM树这个数据类型,我们在读懂了文章,只需要做一遍标记构建一份蓝图,就可以轻松掌握正片天空。具体操作就是创建一个document对象作为根节点,根据上一步标记后将节点按照对应关系插入到这个树就形成了DOM树。
三、部分标签练习
//a标签最终的是属性是href:跳转目标地址;target:跳转载入方式
<div id="container">
<a href="https:www.baidu.com" target="_blank" >跳转1</a>
<a href="https:www.baidu.com" target="_parent">跳转1</a>
<a href="https:www.baidu.com" target="_self">跳转1</a>
<a href="https:www.baidu.com" target="_top">跳转1</a>
</div>
_blank:浏览器会创建一个新的空白标签页窗口用来载入目标地址内容。
_parent:目标文档载入位置为当前操作的父窗口或者包含超链接的框架的框架。
_self:这个值属于没有指定target时的默认值,以当前操作的窗口或者框架作为目标地址内容的窗口。
_top:目标文档载入位置直接为最顶层,即当前窗口。
//音频播放的时候一定要携带controls属性,显示相应音频控件,提供如播放、暂停、进度条拖拉等功能操作
<body>
<div id="container">
<video src="/i/movie.ogg" controls="controls">
your browser does not support the video tag
</video>
<audio src="/i/horse.ogg" controls="controls">
Your browser does not support the audio element.
</audio>
</div>
</body>
//与ol(有序列表)、ul(无序列表)齐名,dl为自定义列表包含dt和dd,类似与自定义分点概括一样,自定义项名,项详细信息。
<dl>
<dt>计算机</dt>
<dd>用来计算的仪器 ... ...</dd>
<dd>一个昂贵的物品</dd>
<dd>有很多品牌的产品</dd>
<dt>显示器</dt>
<dd>以视觉方式显示信息的装置 ... ...</dd>
<dd>输入输出设备之一</dd>
</dl>
CSS篇
怎么听过老师讲后感觉头凉凉的,我有真的学过CSS嘛?
CSS选择器补充
除了基本的id、类、元素、通配符选择器外,下面几种组合式的选择器也是我们在开发过程中可能会用到的,有意思的是这玩意有两组是比较容易搞混的,需要额外注意,对比记忆。子选择器和后代选择器,相邻兄弟选择器和兄弟选择器。
- 直接组合选择器:两个选择器写在一起中间没有其他符号连接,表示的式既满足前者又满足后者的一种选择器。
- 分组选择器:多种选择器对应的多个节点设置同一个样式,选择器通过‘,’隔开。偷懒必备!
- 子选择器:一般由两部分组成中间通过‘>’进行连接,前面是父元素,后面是子元素。结果是选中父元素的满足条件的直接后代(孩子)。
- 后代选择器:中间通过空格' '符连接,这个容易和子选择器搞混乱,只需要记住后代选择器的范围更广,孙子也属于父元素的后代。
- 相邻兄弟选择器:可选择紧接在另一元素后的元素,二者由相同的父元素,故而为兄弟元素关系,两个选择器中间使用‘+’连接。
- 兄弟选择器:兄弟选择器的约束性没有相邻兄弟选择器那么强,从名字中我们就能看到。兄弟选择器中间通过'~'连接,只要满足同一个父亲下就可以了。
- 属性选择器:类似于条件筛选一样,我们把关注点放在是否含有某个属性上,而不是元素的位置或者关系。例如 *[title] {color:red;}就是对于文档中所有元素节点中包含title属性的元素字体颜色都设置为红色。这个使用的比较少,但也要知道有这么个选择器。
中英文字体在字体样式CSS设计时遇到的问题。
css选择器读取顺序
只有我是现在才知道CSS选择器在被解析的时候是从右向左的嘛?为此我专门去网上充了充电,那么了解的内容是这样的。css选择器在被解析的时候,其实是将这一条css样式设置内容匹配到对应的元素节点上,拿到一条css选择器然后去对照着DOM树,找的所描述的元素节点。
CSS选择器的书写是从上到下,从里到外,从左到右边符合人类逻辑思维的一种方式,但是解析的时候计算机需要考虑到性能问题采用了从右向左的方式一个步步寻找到目标元素节点的。这种方式能够最大限度的减少回溯。例如 div p a{};从右向左,一定是满足当前a且父元素为p的节点才会继续向上寻找,而不是div 然后深度优先策略下,经过多次回溯找到满足最终结果的节点。
CSS中的颜色
之前对于颜色的使用也就用用rgb(0255,0255,0~255),红绿蓝三原色进行切换,#fff是rgb十六进制的颜色示方法,对于像black,red等英文单词则是对应颜色的文字表示方式,相较于记数值更容易记忆。
RGB: 由红、绿、蓝三个参数租船,范围都是0-255,代表颜色的亮度值,0相当于颜色最暗为黑色,255为颜色最亮,三种颜色按照叠加原则混合后的颜色即为RGB显示的颜色。
HSL: 由三个参数组成,分别是:色相(hua)、饱和度(saturation)、亮度(lightness)。其中色相是颜色的基本属性,在光谱的基础上分成了360°的圆环频率,取不同的值即对应不同的光的频率也就是不同的颜色;饱和度指颜色的鲜艳程度,范围0-100%,越低颜色越暗淡,越趋近于灰色;亮度指颜色的明亮程度,范围0-100%,越高越亮,越趋近于白光。
RGBA: rgba(red, green, blue, alpha)是rgb的扩展,增加了alpha参数,用于规定对象的不同明度。alpha 参数是介于 0.0(完全透明)与 1.0(完全不透明)的数字。
HSLA: hsla与rgba类似的情况类似,是作为hsl的扩展,增加了alpha参数。
opacity与rgba和hsla的区别
我们使用一个例子来展示:opacity属性能够被子元素继承,而rgba和hsla中透明度属性不会被子元素继承。
<style>
.box1,.box2,.box3{
width: 100px;
height: 100px;
background-color: coral;
color: black;
margin-top: 20px;
}
.inerbox1,.inerbox2,.inerbox3{
width: 50px;
height: 50px;
background-color: blue;
}
.box1{
opacity: .5;
}
.box2{
background:rgba(124, 56, 200, .5) ;
}
.box3{
background: hsla(74, 50%, 50%, 0.5);
}
</style>
<body>
<div id="container">
<div class="box1">
<div class="inerbox1">
box1的内容
</div>
</div>
<div class="box2">
<div class="inerbox2">
box2的内容
</div>
</div>
<div class="box3">
<div class="inerbox3">
box3的内容
</div>
</div>
</div>
</body>
执行结果如下:
字体使用
字体属性是 font-family,设置元素字体,可以同时指定多个,按照顺序依次向下使用。如果不设置font-family则使用浏览器默认字体,如果设置的font-family无效,也会fallback到浏览器的默认字体。字体使用是有建议的:
- 字体列表最后写上通用字体族,一般以serif或sans-serif字体族结尾
- 英文字体放在中文字体前面,这是因为英文字体不包含中文,对于中文的字可以由后面的中文字体去设置,但是中文字体包含英文,可以对英文进行字体设置,为了美观性我们才有了这个建议。
- font-family属于可继承属性,全局的font-family一般设置在body元素上。
inherit和initial关键字
我们都知道在CSS的世界里父亲的样子会有部分遗传给孩子的,这些默认的行为我们是可以通过initial关键字作为属性的值,让子类继承到的样式变成初始状态(等同于取消继承),对于那些不能够默认继承的样式,我们通过关键字inherit显式继承,将其用作属性的值即可使得子类在该属性上继承父类样式。
<body>
<div id="container">
<div class="box1">
123
<div class="inerbox1">
box1的内容
</div>
</div>
</div>
</body>
<style>
.box1{
width: 100px;
height: 100px;
background-color: aquamarine;
color: red;
}
.inerbox1{
margin-top: 100px;
color: initial;
background-color: inherit;
}
</style>
盒子模型
什么怪异盒子?什么标准盒子?看到评论区大家一个个的说怪异盒,我就去浅搜了一下,奇怪的知识又增加了!ie,前端程序员的公敌!
W3C标准制定的标准盒子
结合着上图,我们可以知道对于每一个节点元素都可以被看作被一个盒子包裹的东西,它从里到外分别是内容、内边距、边框、外边距。对于标准盒子模型来说,我们设置的width和height指的是盒子最内部的内容的长和宽。如果再增加内外边距和边框,则元素(盒子)整体尺寸会变大,而内容区域大小还是设定的值不变。需要区别的概念是盒子占位和盒子大小! 前者包含外边距,后者不含。以宽度为例,展示计算内容
占位:width=width+2margin+2padding+2border。
大小:width=width+2padding+2border。
标准盒的代码例子
<style>
.box1{
width: 100px;
height: 100px;
background-color: aquamarine;
color: red;
border:1px solid red;
padding:10px;
}
</style>
<body>
<div id="container">
<div class="box1">
123
</div>
</div>
</body>
根据计算可知内容宽度100px,两个内边距210px,两个边框21px,综合刚好等于122px。
IE之怪异盒子
有图有真相,我们将上面标准盒的代码稍作改变,添加box-sizing: border-box;属性,得到的效果如下:
怪异盒子的区别显然就出来了,怪异盒子元素设置的width和height是包含了内边距和边框的,是标准盒的大小。也就是说实际内容区域大小是小于等于设置长和宽的。
CSS做一个三角形玩
1、利用块级元素,长度和宽度设为0,更改border样式,显露出需要的一部分。
来自朋友的指点:为什么要必须设置块级元素属性width:0;height:0;否则会变成长方形? 原因就在于块级元素本身,我们都知道块级元素有一大特点,那就是不能并排一行,即便你设置了width值很小也不能并排在一起,其默认占满页面的长度,所以设置border的时候是长条状的。即我们需要的是没有默认width和height的块级元素。除了设置长宽外,也可以将元素类型设置为行内块级元素,display: inline-block;
<style>
div{
width: 0px;
height: 0px;
}
.container{
display: flex;
}
.box1 {
border:50px solid transparent;
border-bottom: 50px solid mediumspringgreen;
}
.box2{
border:50px solid transparent;
border-top: 50px solid mediumspringgreen;
}
.box3{
border:50px solid transparent;
border-left: 50px solid mediumspringgreen;
}
.box4{
border:50px solid transparent;
border-right: 50px solid mediumspringgreen;
}
</style>
<body>
<div class="container">
<div class="box1">
</div>
<div class="box2">
</div>
<div class="box3">
</div>
<div class="box4">
</div>
</div>
</body>
2、利用linear-gradient线性渐变,以45°角将一个正方形分隔两块,一部分争产显示,渐变区域到最后100%都用透明颜色代替即可。我们在取得一个小三角后,可以通过transform: rotate()进行旋转,以达到不同角朝向。
<body>
<div class="container">
<div class="box1">
</div>
<div class="box2">
</div>
<div class="box3">
</div>
<div class="box4">
</div>
</div>
</body>
<style>
.container {
display: flex;
margin-top: 50px;
}
.box1,
.box2,
.box3,
.box4 {
width: 100px;
height: 100px;
background: linear-gradient(45deg, deeppink, deeppink 50%, transparent 50%, transparent 100%);
margin-left: 50px;
}
.box2 {
transform: rotate(45deg);
}
.box3 {
transform: rotate(135deg);
}
.box4 {
transform: rotate(-45deg);
}
</style>
还有好多种方式,包括利用角度渐变、clip-path切割多边形显示等等。
display
display属性可以设置元素的内部和外部显示类型,对于外部一般是指在常规流布局中是块级元素还是行级元素;对于内部显示一般指该元素内子元素的布局格式(flex|grid|flow)
- none:该元素以及其子元素从可访问树中移除,在屏幕上不再显示。
- block:块级元素
- inline:行级元素
- inline-block:行内块元素
- felx 弹性盒布局
- grid 网格布局
布局相关知识
布局分为常规流和非常规流两类。
常规流:行级、块级、表格布局、FlexBox、Grid
非常规流:浮动、绝对定位
IFC(Inline Formatting Context)行级排版上下文
只包含行级盒子的容器会创建一个IFC,IFC内的排版规则如下:
- 盒子在一行内水平摆放
- 一行放不下时,换行显示
- text-align决定一行内盒子的水平对齐
- vertical-align决定一个盒子在行内的垂直对齐
- 避开浮动元素
BFC(Block Formatting Context)块级元素排版上下文
满足以下任何条件的元素都会创建一个BFC。
- 根元素
- 浮动、绝对定位、inline-block
- flex子项和Grid子项
- overflow值不是visible的块盒
- display:flow-root
BFC内有以下排版规则
- 盒子从上到下摆放
- 垂直margin合并
- BFC内盒子的margin不会与外面的合并 -BFC不会和浮动元素重叠
FlexBox 弹性盒——最常用的一种布局方式
最常见的布局代码莫过于display:flex;了。使用这种方式布局可以通过flex-direction控制盒子摆放的方向和摆放顺序(是否逆序);盒子的宽度和高度;水平和垂直方向的对齐以及是否允许拆分行。
盒子分别由水平方向的主轴和垂直方向的侧轴。在控制子元素(盒子)的对齐时,我们会经常参考这两个轴来进行,通过justify-content和align-items来进行调整。