CSS 和 HTML 知识总结

1,140 阅读26分钟

一、HTML

很认真的总结了一些基础知识,虽然不能全部覆盖,但还是有一定的内容的。精神食粮,欢迎食用!

1. HTML文档各个标签的作用HTML

你肯定知道在编辑器输入英文感叹号,再按个 Tab 键就能够得到下面的内容,那你清楚下面标签的作用嘛?

<!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>Document</title>
</head>
<body>
    
</body>
</html>

1.1 DOCTYPE

DOCTYPE 就是 Document Type 的简写,它不是 HTML 标签,通过它浏览器就能了解预期的文档类型,而且必须写在文档的第一行

怪异(兼容)模式:你的页面如果不写上边这条指令的话,就是怪异模式,浏览器会向后兼容自己的低版本的方式来渲染

标准模式:加上指令,就是标准模式,浏览器会按照 W3c 的标准,以浏览器支持的最该标准渲染,另外 <!DOCTYPE html> 是指 HTML5,HTMLL5 以下的有所不同的。见到过,没有去了解。

1.2 lang

<html> 标签就是文档的根元素了,lang 是 语言 language 的简写 ,en 表示英文,zh 表示中文,主要是给浏览器的搜索引擎看的,看这个页面定义为中文还是英文的,其实你写 en 中文啥的也都是照常显示,因为编码还是按照 UTF-8 啥的嘛

1.3 meta

<meta> 标签提供一些元数据,虽然对于用户来说是不可见的,但是可供我们的机器解读,可以用来描述页面,作者等。

可以稍稍的解读上面默认产生的三个 <meta> 标签

1.3.1 charset

charset 属性是设置文档的字符编码。UTF_8 俗称万国码,现在见的比较多,但是我对 MDN 上边的描述感到疑惑,上边说:

如果使用了这个属性,其值必须是与ASCII大小写无关(ASCII case-insensitive)的"utf-8"。

我记得 Eclipse 生成 jsp 文件上边默认就写的是 <meta charset="ISO_8859-1">,当时 JAVA 老师还让我们改用 GBK.

1.3.2 name

naame 是和 content 一起用的,name 的值作为元数据的名称,content 的值作为元数据的值。

viewport 是 HTML5 新增的,在写移动端页面的时候很常见,width=device-width 意思是页面所有内容的宽度等于设备宽度,initial-scale 表示页面的初始缩放值。其实还有其他,例如 minimum-scale 允许用户的最小缩放值等

name 的值还可以是 keywords,description,author

1.3.3 http-equiv

http-equiv 也是和 content 一起使用的 X-UA-Compatible 是定义浏览器的渲染方式的,IE=edge 就是告诉浏览器按照 IE 的最高标准来渲染,默认就光强制 IE 了,其他浏览器的渲染方式不强制和,可见业界对 IE 浏览器的那啥,哈哈哈!

当然也还有其他值像 content-type 定义文件类型,refresh 设置网页自动刷新的时间间隔等

2.HTML 的语义化

语义化就是赋予了一些标签意义,不是全部都是 <div> ,而是多了像 <img>,<table>,<form>这些标签,这些标签本身就带有一定的样式。

值得一提的是 HTML5 新增的语义化标签 <header>,<nav>,<section>,<article>,<aside>,<figcaption>,<figure>,<footer>

这些标签倒好像没有什么样式,感觉就是一种规范,以后写代码,什么内容应该放在上面地方,上面的除了 <figcaption> 都是块元素哦!

语义化的好处:

  • 方便阅读了,让你的代码“肉眼可见”,自己看着舒服,别人维护起来也舒服
  • 有利于 SEO,就是能够更好的被爬虫爬到,用户搜索目标和爬到的更加匹配,不至于牛头不对马嘴

3.块级,行内,行内块元素

3.1 对比

块级元素能够使用 css 定义其宽高,会独占一行,也就是自动换行,且对 margin padding 的上下左右设置均有效,例如:<div>,<p>,<h1>,<ul>,<form>

行内元素设置不能设置宽高,元素宽高由内容撑大,相邻的行内元素都会在一行,即不会自动换行,margin 仅左右方向有效,上下无效,padding 上下左右均有效,例如:<a><span><u><em><i>

行内块元素,不会换行,但是能够设置宽高,例如:<img><input><textarea><select><option>

当我给四个元素下面相同的样式,效果显示如下

    margin-bottom:40px;
    margin-right:40px;
    background-color: blue;

image-20210916121642845.png

3.2 转换

  • 转块级元素:display:block
  • 转行内元素:display:inline
  • 转行内块元素:display:inline-block

3.3 IE 盒模型与 W3c 盒模型

截一下菜鸟教程上边的图(狗头)

image-20210916193913801.png

W3c/标准 盒子模型

刚刚提到过,我们的块级元素和行内块元素是可以设置宽高的,而默认的都是盒子模型,给元素设置的 width 就等于 content 的宽度。这个时候元素的总宽度=width+左内边距+右内边距+左边框+右边框+左外边距+右外边距

IE 盒子模型

我们可以通过 CSS 设置 box-sizing:border-box 来使用这个模式, 这个时候设置的 width 就是 content,padding,border 加起来的宽度。

写到这里,我还记得一个有意思的 CSS 属性 background-origin ,我给下面的 div 设置如下样式

<div class="box">盒子盒子盒子盒子盒子盒子盒子盒子盒子盒子盒子盒子</div>
.box{
    margin-left: 100px;
    margin-right: 100px;
    padding-left: 100px;
    padding-right: 100px;
    border: black solid 5px;
    background-color: chartreuse;
}

在浏览器显示如下:

image-20210916195112311.png

可以看到背景颜色是会显示在 coontentpadding 区域的。这是因为 background-origin 的默认值就是 padding-box,它还能取另外两个值,分别表示从边框区域开始显示背景(border-box),仅在内容区显示背景( content-box)

4 DOM

可以给大家伙推荐一本书,像我这样的小菜鸡阅读起来也是觉得很舒服。书名《JavaScript DOM编程艺术》

DOM 就是文档对象模型(Document Object Model)。可以理解为用一个逻辑树来表示一个文档,浏览器在解析 HTML 时,会把每个标签抽象成对象,并且根据嵌套关系,构成层次分明的树结构,这就是 DOM 树。

4.1 结点

4.1.1 结点类型

  • 元素结点:像 <p>,<div> 这种标签
  • 文本结点:<div>文本结点<div>,标签里面的内容
  • 属性结点:<p class="desc"><p> ,标签属性

这样我们也能够知道文本结点和属性结点总是被包含在元素结点内的

4.1.2 获取结点

document 对象身上有几个函数供我们获取元素结点

  • document.getElementById(id),根据元素 id 获取
  • document.getElementsByTagName(tag),根据标签名获取
  • document.getElementsByTagName(class),根据元素类名获取
  • document.querySelector(),根据 css 选择器获取,就是上边三个的整合

属性结点有两种方式获取,但前提都是获取到了元素结点

let p = document.getElementById("pic")

  • p.getAttribute("src"),当然也可以设置属性 p.setAttribute("src", str)
  • p.style.width,通过对象属性的形式获取,也能够加个等号来赋值

至于一些博客里面说的,前者的修改会体现到 HTML 中,后者不会,还有说 DOM 的工作模式是 “先加载静态内容,再动态刷新,动态刷新不影响文档的静态内容”,所以 id 属性不会变,我做了一个小实验

    <span class="inline" id="inline1">行内元素1</span>
    <span class="inline" id="inline1">行内元素1</span>
    <script>
        let s = document.getElementsByClassName("inline")
        s[0].setAttribute("id","outline1")
        s[1].id = "outline1"
    </script>

浏览器控制台的 DOM 结构显示如下

image-20210919221324807.png

给按钮绑定函数来修改结果同样如上,所以暂时持保留意见。

4.1.3 操纵结点

前边也说到了,元素之间可能会存在一些包含嵌套关系,然后一起构成层次分明的树结构。

image-20210920205647329.png

结点之间的获取有很多 API 下面记录一些常用的查询插入等操纵结点的方法

  • 新建元素:document.createElement
  • 获取子元素:childNodes
  • 获取父元素:parentNode
  • 获取哦结点类型:nodeType
  • 获取/修改文本:nodeType,innerHTML
  • 获取当前元素的下一个同级元素:nextSibling
  • 获取当前元素的上一个同级元素:previousSibling
  • 删除结点:removeChild
  • 插入结点:appendChild,insertBefore (在已有元素前插入一个新元素)

4.2 事件

HTML 有能力使 HTML 事件触发浏览器中的行为,比如触发一段 JavaScript 代码。

4.2.1 事件类型

事件有很多像鼠标事件:onclick 鼠标点击,onmouseup 鼠标松开

键盘事件:onkeydown 某个键盘被按下,onkeyup 某个键盘被松开,onkeypress 某个键盘被按下并松开

对象事件:onload页面或者图像加载完成,onscroll 文档被滚动,onresize 窗口被重新调整大小

表单事件:onblur 元素失去焦点,onfocus 元素获取焦点,onsubmit 表单提交

剪切板事件:oncopy 用户在拷贝内容时,onpaste 用户在粘贴元素时

等等等等

4.2.2 事件模型

事件冒泡:事件根据元素嵌套关系从触发结点一直冒泡到 document 。自下而上

事件捕获:事件根据元素嵌套关系从 document 一直传递到触发事件的元素。自上而下

浏览器中事件机制默认为事件冒泡

4.2.3 事件绑定

事件触发后,基本都是由函数来处理

有三种写法,W3c 推荐的是第三种,可以看下面的伪代码

    <button id="button" onclick="show()" >按钮</button>
    <!-- 1.直接在HTML元素上边绑定 -->
    <script>
        function show(){
            alert("你点了我一下")
        }
        const but = document.getElementById("button")
        but.onclick = show//获取元素后通过属性监听
        but.addEventListener("click",show,false)//通过addEventListener监听,第三个参数默认false,事件冒泡
    </script>

携带参数的话,方法1直接写在括号里面便是。方法23则是直接在等号后面写函数声明,参数写括号里。

4.2.4 事件委托

这玩意也很好理解,假如 <ul> 下面由许多个 <li> 标签 需要给每个 <li> 绑定点击事件,咱第一时间想到的肯定是,通过选择器获取到这些 <li> 标签,再用一个 for 循环给每个元素绑定点击事件。

但是,这样给点击事件绑定的函数每一个都是不一样的,当 <li> 标签过多的时候,就会产生巨大的内存开销,这个时候就会用到事件委托,请看下面的代码:

    <ul id="newslist">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
    </ul>
    <script>
        function show(event){
            alert(`你点了我一下我是${event.target.innerHTML}`)
        }
        const but = document.getElementById("newslist")
        but.addEventListener("click",show,false)
    </script>

上边代码监听的是这些 <li> 标签的父元素 <ul> 标签,然后利用事件冒泡的原理,不论点击到哪个 <li> 标签,事件都会向上传递,给到父标签,这时触发 <ul> 的点击事件,然后可以用默认的事件对象参数上边的 target 属性获取到事件源头元素

5. iframe

说实话,这个标签我在别的不同的地方瞥见过很多次,但都没有仔细看,自己也应该没有用过,反正我现在是没有多少印象了。看了下 W3school 后知道了。原来 iframe 是用来创建一个内联框架。其中的 src 属性就是显示文档的 URL 。

index.html 文件部分代码如下

    <div>我是原来页面的内容哦</div>
    <iframe id="IdData" src="./iframe.html"  style="width:100%;height:40px"> </iframe>

iframe.html 文件部分代码如下

<em>我是内联框架的内容哦</em>

页面显示效果如下:

image-20210923103432049.png

iframe 的劣势,网上找的,看着也有点不大懂

iframe会阻塞主页面的Onload事件;
搜索引擎的检索程序无法解读这种页面,不利于SEO;
​
iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。

6 .相关面试题

  1. <img> 标签的 title 和 alt 属性分别有啥用?

        图像1: <img src="https://img1.baidu.com/it/u=205189823,2307333758&fm=26&fmt=auto&gp=0.jpg" alt="不出来图片" width="40" height="40"><br/>
        图像2: <img src="https://img1.baidu.com/it/u=205189823,2307333758&fm=26&fmt=auto&gp=0.jpg" title="不出来图片" width="40" height="40">
    

    显示如图:image-20210922193957463.png

我们给个不存在的 src ,浏览器显示效果如图:

image-20210922194111089.png

alt 属性内容是图片在不能正常加载的时候,给用户看的,提供信息说明

`title` 属性内容是在鼠标悬停在图片上时显示的,当然上边也能发现,图片未正常加载的时候也会显示,只是显示在原本图片应该占据的位置。提供一些非本质的额外信息。

0. HTML 全局属性有哪些?

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

-   常见的 `class` `id` `style`-   不常见

    -   `dir` 设置元素内容的使用
    -   `data-*` 属性用来嵌入自定义数据,例 `<li data-english="bird">鸟</li>` `,这样就能保存一些数据,而不需要使用 Ajax 或服务端请求数据
    -   `title` 上边一题说过的
    -   `accesskey` 设置访问元素的键盘快捷键(使得元素获取焦点)。例 `<a href="xxx" accesskey="c">超链接</a>` ,注意在不同的浏览器中使用 `accesskey` 快捷键的方法有所不同,在 Chrome 里是按住 Alt 键,再按 `accesskey` 定义的快捷键

0. 如何在 HTML 页面上展示 <div></div> 这几个字符

看到这题,瞬间就想到了之前关于 JS 转义符的乌龙,显示在 HTML 里面显示特殊字符也是需要转义的,向大于小于号这种。我第一时间想到的就是 `innerText` 因为记得 `innerHTML` 是会解析 HTML 标签的,而 `innerText` 不会。第二种方法就是转义了

```
    <div id="box"></div>
    <div>&lt;div&gt;&lt;/div&gt;</div>
    <script>
        const box = document.getElementById("box")
        box.innerText = "<div></div>"
    </script>
```

0. label 有什么作用?如何使用?

很尴尬的一件事情是,`label` 这几个字母我总是拼不对,总是将它和 “babel” 联系起来。而且这题还可以和另一题 "`input` 中的 `name` 属性有啥作用" 联系起来。

`label` 标签在样式上没有特殊效果,通过 `for` 属性 与表单控件的 `id` 值(只见过 `input`,以前记错是 `input``name` 属性)联系起来。当用户选择该标签时,相关联的控件会获得焦点

```
 <label for="name">姓名:</label>
  <input type="radio" name="username" id="name" placeholder="请输入用户名">
````input``name` 属性到底有啥用呢?

-   服务端使用,我记得在 JSP 中获取表单信息就是用 `request.getParameter(name)` ,其中的 `name` 就是 `input``name` 属性。而使用 Node.js 写服务端,表单信息会是一个对象。这时 `name` 就是对象属性名
-   JS 使用 `getElementsByName` 根据元素 `name` 属性值获取元素
-`input``type``radio``name` 属性值相同的为一组,用户只能选中其中一个

二、CSS

1.position

定位这个属性可有意思了

  • absolute 绝对定位,相对于开启了除了 static 的定位的第一个父元素进行定位,可以设置 left right top bottom 来偏移元素。一般打算使用 absolute 的时候,都会给它的父元素开启 relative 定位

  • relative 相对定位,同样可以使用 left right top bottom 来给元素设置偏移量,只是是相对与自身本来的位置偏移,而且元素不会脱离文档流

  • fixed 固定定位,相对于窗口(也就是屏幕左上角)定位,脱离文档流

  • sticky 粘性定位,也是非常有意思,相对于 relativefixed 的有机结合。平常的时候就像 relative ,但是当页面滚出窗口,它就会像 fixed 用这个可以做网站的导航栏。稍稍写了下代码实验

    <div class="container"><div class="contentBox"></div></div>
    
    .contentBox{
        background-color: blue;
        width: 100px;
        height: 100px;
        position: sticky;
        top: 0;
    }
    .container{
        position: relative; 
        top: 100px;
        width: 100px;
        height: 2000px;
        background-color: brown;
    }
    

    一开始是页面显示效果这样的:

image-20210923210441215.png

滑动后页面效果如下:

image-20210923210532366.png

  • static 默认值,没有定位

  • inherit 从父元素继承 position 的值

  • z-index 只能在 position 属性值为 relative/absolute/fixed 的元素上有效,数值越大,越在上边。,一般定位元素会层叠在浮动元素上面。

2. display

这个属性的值挺多的,上边写行内块元素的时候,介绍了三个值,在这里再补充两个常用的

2.1 none

display 设置为 none 后,该元素不会被显示,但是该 DOM 节点还在哦

2.2 flex

display: flex; 就表示开启弹性布局。一般是父元素开启弹性布局,对子元素进行布局,会对用得到的属性记录下来,但不会太全面,会用方便我自己的方式记录,因为写这篇博客的初衷就是帮助自己梳理基础知识嘛!,忘记的话可以去看菜鸟教程,入门很快的。

2.2.1 父元素属性

父元素开启了弹性布局以后,可以通过自己的一下属性对子元素进行布局

  • flex-direction 决定主轴方向,即子元素的排列方向 不得不说在一些需求上使用 flex 会简单很多,比如:让三个 div 元素水平排列。按照传统的盒模型布局,也是可以做到的,方式还挺多

    • div 设置为 inline-block

    • 利用定位

    • 利用浮动

      定位浮动脱离文档流的话会影响其他元素,设置为行内块元素也不能设置顺序,只能默认从左到右排,而已开启弹性布局,默认主轴方向就是从左往右,轻易实现这种效果 image-20210924112446080.png

  • flex-wrap 决定元素挤满后是否以及怎样换行,默认不换行,就是硬挤,将上边三个盒子的容器设置小一点的 width 之后,它们就被挤成这样了!

image-20210924114451175.png

  • justify-content 决定子元素在主轴上的对齐方式,默认左对齐,当设置了 center 的时候,效果如下

image-20210924114354364.png

  • align-items 决定子元素在交叉轴(垂直与主轴方向)上的对齐方式,也有一个有意思的值 ,去掉给子元素设置的高度后 ,将 align-items 的值设置为 stretch ,也是默认值。效果显示如下,直接被拉满了。

image-20210924115424165.png

  • align-content 和上边的 align-items 很像,但只有在多根轴线的时候起作用,什么是多根轴线,就是不知一行啦哈哈哈 但是在效果上也是有区别的,就比如给他们的值都设置 centeralign-item 的效果是这样的

image-20210924122531452.png

align-content 的效果是这样的

image-20210924122620936.png

可以发现 align-item 是给每一条度后居中,align-content 则是看作一个整体居中

  • 最后还有一个充数的 flex-flow hhh,它是 flex-direction 属性和 flex-wrap 属性的简写形式

2.2.2 子元素属性

定义在子元素身上的属性,通过设置不同的属性值也是可以达到布局的效果的

  • order 定义子元素的排列顺序,根据主轴方向,数值越小,越靠前
  • flex-grow 定义子元素的放大比例,当父元素有剩余空间时,根据每个子元素的该数值按比例分配剩余空间,为 0 则不分配
  • flex-shrink 定义子元素的缩小比例,当父元素空间不够时 根据每个子元素的该数值按比例缩小自身空间,为 0 则不缩小
  • flex-basis 定义子元素在主轴上占据空间,就像设置元素的 widthheight 一样,默认是元素本来大小,浏览器是根据该值的长度去计算主轴是否有多余空间的
  • align-self 允许设置了该属性的子元素和其他子元素不一样对齐,可以覆盖掉 align-items 的值 但是好像 align-content 不能被覆盖呢!效果如下!

image-20210924125453608.png

  • flexflex-grow, flex-shrinkflex-basis 的简写,默认值为0 1 auto,我记得之前好像在这个属性上的写法上遇到过一些问题,最终是看张鑫旭大佬的博客解决的,可以去大佬的网站看看的哦!

2.3 flow-root

3.float

浮动的概念感觉有点说不明白,首先是文档流,就是 css 布局中元素的一种默认流动方式,块级元素,行内元素都有着自己的排列规则,让元素浮动的话,就是会脱离这种标准文档流,按照 left/right,朝着向左或者向右的方向移动,直到自己的边界紧贴着其他浮动元素或者父元素。使用了 float ,行内元素也会变成块元素,可以设置宽高。注意,没有给父元素设置高度或者的话,可能会出现父元素崩塌的情况

开启了浮动后,可以通过 margin 设置外边距的大小来控制元素内容的偏移位置

3.1 高度塌陷

高度塌陷简单来说就是没有给父元素设置高度,子元素脱离文档流后,就塌陷了,看到有很多种解决方法,但其中一大部分都是基于 BFC 的,这个稍微后面一点我再记录,在这里就写用 clear 解决,一般都是再添加一个空白子元素,写入样式 clear:both 解决,或者是使用伪元素 :after ,同样在里面写入 clear:both ,意思是不允许周围有浮动

4 响应式布局

这种概念性的东西也不是特别了解,应该就是一套样式代码能够同时适应 PC 端和移动端等各种客户端。好像还有个概念叫自适应布局,它会需要开发者创建多个静态布局,每个静态布局对应一定的屏幕分辨率范围。

对于自适应的响应式布局的区别,我查了一下资料,虽然它们都能适应不同的客户端,但自适应布局时给每个范围的分辨率写一套完整的样式代码,这样就会使得项目变得厚重,而且自适应得每一套样式都是静态布局得,即页面得每个板块的相对位置时不会变化得,只是改变元素或者板块的大小。而响应式的话页面的布局以及板块大小都可能发生变化,采用的时流式布局,这里就要知道文档流3,利用 floatdisplay 都能使得元素脱离文档流。

现在主流的应该就是响应式布局了吧。与之一同可能被提及的概念,可能还有 自适应布局静态布局流式布局弹性布局。详情可以参考 这篇博客

响应式布局的几个要点

4.1 相对单位

我也还没做过响应式布局的项目,不应该说,我在自己做过的项目用只是到了一些相对单位,下面呢给这些单位一个总结吧,而且在 chrome 浏览器里面文字最小就是 12px

  • px 就是像素,1px 就是一个像素点。比如 1920×1080 就是液晶屏的分辨率,它单位就是 px.静态布局基本就是使用 px
  • em 参考父元素的 font-size 大小,对了,关于 font-size 的大小,没有写就会继承父元素的大小。而且记住了,你如果这样写 width:2em 这个 em 是元素自己的字体大小,不是父元素的。但是感觉怪麻烦的,你需要记住很多个元素它们的父元素的大小
  • rem 参考根元素 html 标签的 font-size 的大小。这样就好了,你只需要设置一个元素的大小,整个项目的 1rem 大小都一样,默认是 16px
  • % 参考父元素,例如 width:65%; 就表示父元素宽的60%,但是呢,对于开启了绝对定位的元素,父元素是指开启了定位的父元素,对于开启了固定定位(fixed)的元素,父元素是整个窗口
  • vw 就是 viewpoint width ,1vw 等于浏览器窗口宽度的 1%,浏览器窗口大小是可以拖拽变化的
  • vh 就是 viewpoint height,1vh 等于浏览器窗口高度的 1%

4.1 媒体查询

不管是自适应还是响应式都需要用到 @media 的吧,在 css 文件中使用

@media screen and (max-device-width:960px){
    body{background:red;}
}

加载时使用

<link rel="stylesheet" type="text/css" media="screen and (max-device-width: 400px)" href="example.css" />

还有一个是我们前面记录过的 viewport ,意思是网页宽度默认等于屏幕宽度

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

5.BFC

这个可以创建无副作用的 BFC,关于 BFC 我们后面会记录的 不知道是不是忘记的原因,真的第一次听说 BFC 的概念。但是呢,好像我们不知不觉中就用到了。

具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的一些特性。 是Web页面中盒模型布局的CSS渲染模式。

我想大家伙应该都听说过/见识过 margin 纵向重叠的特性,这特性在某些时候是很方便的,可以借助这个特性来体验一下 BFC 的妙处

    <div class="container"><div class="box"></div></div>
    <div class="container"><div class="box"></div></div>
.container{
    background-color: brown;
    /* overflow: hidden; */
}
.box{
    width: 100px;
    height: 100px;
    background-color: blue;
    margin: 100px;
}

image-20211002213124248.png

可以看到,两个元素之间的上下外边距重合了,接下来我们取消样式中的注释,利用 overflow 触发 BFC ,效果如下图

image-20211002213335601.png

不仅上下边距没有重合,容器 div 也被里面的外边距撑开了,这就是 BFC 的特性之一。这个时候你再去看上边那句话,就会觉得容易理解一些了。接下来,再学点难的

5.1 触发

上边我使用的是 overflow 来触发的,还有好几种方式可以触发

  • 根元素 html,就是一个具有 BFC 特性的元素
  • float 设定除 none 以外的值
  • 使用 position 使得元素脱离文档流 (absolutefixed
  • displayinline-blocktable-cellsflex
  • overflow 除了 visible 以外的值
  • display: flow-root 这个属性值专门用来触发 BFC,不干别的

5.2 特性

  • 同一个 BFC 下外边距会发生折叠,这个上边写到过,想让它们不折叠就弄两个 BFC。
  • 作为一个独立渲染的容器,里面的子元素不会影响外边的元素,上边出发了 BFC 就把子元素的上下外边距也包进来了就是如此
  • 触发 BFC 的元素会包含浮动子元素,能够实现清除浮动的效果
  • 触发了 BFC 的区域不会与浮动元素重叠

5.3 案例

5.3.1 浮动触发

    <div class="container"><div class="box"></div></div>
    <div class="container"><div class="box"></div></div>
.container{
    background-color: brown;
    width: 200px;
    /* float: left; */
}
.box{
    width: 100px;
    height: 100px;
    background-color: blue;
    margin: 50px;
}

页面效果如下

image-20211003164605955.png

上下外边距超出了父元素,但是我们解开 css 样式文件中的注释,触发父元素的 BFC ,页面展示效果如下

image-20211003164802979.png

上下左右的外边距都包含在父元素了,只是开启 BFC 的副作用就是,父元素浮动了

5.3.2 实现清除浮动

依旧是上边的 HTML,样式代码如下

.container{
    background-color: brown;
    width: 200px;
    border: 2px solid black;
    /* overflow: hidden; */
}
.box{
    float: left;
    width: 100px;
    height: 100px;
    background-color: blue;
    margin: 50px;
}

这时的页面效果如下

image-20211003165500727.png

可以看到,因为浮动脱离文档流的原因,父元素已经坍塌了,这时我们解开注释,触发 BFC 效果如下

image-20211003165617938.png

父元素的高度包括了浮动的元素

5.3.3 不与浮动元素重叠

    <div class="floatBox">我是一个浮动元素,我要飘向左边</div>
    <div class="box">我是一个平平无奇的盒子</div>
.box{
    /* overflow: hidden; */
    width: 200px;
    height: 200px;
    background-color: blue;
​
}
.floatBox{
    float: left;
    width: 100px;
    height: 100px;
    background-color: chartreuse;
}

页面效果一开始如下

image-20211003170607663.png

但是我们解开注释,触发 BFC 之后,效果显示如下

image-20211003170647570.png

看完了有没有觉得明白了点什么,哈哈哈哈。应该大概能明白 BFC 是个啥东西了。

6. 相关面试题

  • 引入样式的方法

    • 行内式:<div style="background-color: black;width: 100px;height: 100px;"></div>

    • 嵌入式:<style type="text/css"></style>

    • 导入式:<style>@import"index.css"</style>

    • 链接式:<link rel="stylesheet" type="text/css" href="./index.css"/>

      写一下导入式和链接式的区别,@import 是 CSS 提供的,只有导入样式表的作用,而且是页面加载完毕后才开始导入的,这样就可能会出现一瞬间没有样式的页面,link 是 HTML 提供的标签,好像不止引入样式这一个功能哦具体的我也不太了解,会在解析 HTML 的时候加载,而且因为是标签的原因,可以利用 JS 操作 DOM 来改变样式

  • 实现水平垂直居中的方式

    这个可能用 flex 比较多

        <div class="container">
            <div class="box">我要水平垂直居中</div>
        </div>
    
    1. absolute+margin:auto;

      .container{
          position: relative;
          border: 2px solid black;
          background-color: chartreuse;
          width: 200px;
          height: 200px;
      }
      .box{
          position: absolute;
          background-color: cornflowerblue;
          width: 70px;
          height: 70px;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
          margin: auto;
      }
      

      这个就是要给子元素设置宽高,偏移量都设置为 0,不写默认是 auto,然后利用 marginauto 自己合理分配空间。

    2. line-height+vertical-align

      .container{
          border: 2px solid black;
          background-color: chartreuse;
          width: 200px;
          height: 200px;
          text-align: center;
          line-height: 200px;
      }
      .box{
          display: inline-block;
          line-height: normal ;
          font-size: 1rem;
          vertical-align: middle;
          background-color: cornflowerblue;
      }
      

      这个需要注意的地方,在我的另一篇博客上有提到一些

    3. flex

      .container{
          border: 2px solid black;
          background-color: chartreuse;
          width: 200px;
          height: 200px;
          display: flex;
          justify-content: center;
          align-items: center;
      }
      .box{
          width: 70px;
          height: 70px;
          background-color: cornflowerblue;
      }
      

      还算比较简单,定义一下子元素在主轴和交叉轴上的排列即可

  • png,jpg,gif,webp 的区别

    gif:采用了无损压缩,尺寸较小,支持透明和动画,最多能表达 256 种颜色,不适合色彩丰富的图片

    jpg:支持 1600w 多种颜色,适合色彩丰富的图片,文件比较大

    png-8:对透明支持比gif更好,同等质量下尺寸也更小,但是不支持动画

    png-24:能丰富的表达图片细节,但是比 jpg 大得多,除非对品质要求极高,一般不用

    webp:由 Google 开发,支持有损压缩,无损压缩,透明和动画,但是 现在还没有全面支持

  • 优先级

    从样式表的位置来看:内联样式(写在标签里面) >内部样式(使用style标签)> 外部样式(Link 或者@import)

    从代码来看:!important > id > class > tag,而且权重依次为正无穷,100,10,1,在使用组合选择器的适合计算权重加起来即可

    后代选择器:用空格隔开

    子元素选择器:用>隔开

三,总结一下

css 的内容有很多,感觉一篇博客根本不能写全,所以写的基本都是平常我用到过的,这样才敢写出来,下面参考里面的链接因为一些原因也没写全,但不会差很多,因为这些字都是自己一个一个敲上去的。然后下面两条链接的话,第一条是真的通过他认识 BFC 的,第二个链接的作者也是一位大三的同学,是看着他写了这么一些,自己才动了心思去写总结的,但是我连写个 HTML 和 CSS 的总结都花九牛二虎之力,JS 的都不敢写,对那位同学真的佩服。自己也要继续加油啊!

然后面试的话,我也现大三,还没有参加过实习面试(现在也在准备中),所以关于面试题啥的都是参照一些大佬的博客面经啥的,可能没啥参考价值,见谅哈!

参考:

10 分钟理解 BFC 原理

前端面试必不可少的基础知识,虽然少但是你不能不知道