HTML & CSS 常见面试题

267 阅读6分钟

HTML面试题

如何理解HTML语义化

让人更容易读懂 让搜索引擎容易读懂(方便SEO)

块级元素&内联元素

块级:div h1/2/3/4/5 table ul ol p 内联:span img input button

CSS面试题

1. 布局

盒子模型的宽度如何计算

  1. box-sizing: content-box (默认) 尺寸计算公式: width = 内容的宽度 height = 内容的高度 宽度和高度的计算值都不包含内容的边框(border)和内边距(padding)。
  2. box-sizing: border-box 尺寸计算公式: width = border + padding + 内容的宽度 height = border + padding + 内容的高度

margin纵向重叠的问题 (外边距塌陷)

相邻元素的margin-top和margin-bottom会发生重叠。

外边距的计算: 正数 & 正数:取最大 负数 & 负数: 绝对值最大的数 正数 & 负数:相加的和

此外注意内容为空的块级元素,因为高度为零所以正常情况下是被无视的,但是存在margin,如果设置了上下边距则取最大,如若上下相邻元素的外边距存在则取四个中最大。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>margin 纵向重叠</title>
    <style type="text/css">
        p {
            font-size: 16px;
            line-height: 1;
            margin-top: 10px;
            margin-bottom: 15px;
        }
    </style>
</head>
<body>
    
    <p>AAA</p>
    <p></p>
    <p></p>
    <p></p>
    <p>BBB</p>

</body>
</html>

在这里插入图片描述

对margin的 top left right bottom 设置负值,分别有何效果?

margin-top 和 margin-left 为负值,元素向上、向左移动
margin-right 负值,右侧元素左移,自身不受影响
margin-bottom 负值,下方元素上移,自身不受影响

在这里插入图片描述 当 margin-top 为负值时: 在这里插入图片描述 当 margin-left 为负值时: 在这里插入图片描述 当 margin-bottom 为负值时: 在这里插入图片描述 当 margin-right 为负值时: 在这里插入图片描述

BFC理解和应用,什么是BFC,怎么利用

  1. 什么是BFC -> Block format context,块级格式化上下文,是一块独立渲染区域,内部元素的渲染不会影响边界以外的元素。

  2. 怎么生成 BFC -> 一个元素形成BFC的常见条件:

     a. float 不是 none
    
     b. position 是 absolute 或 fixed
    
     c. overflow 不是 visible (hidden)
    
     d. displayflex inline-block 等
    
  3. BFC 怎么利用 ->用于清除 float 布局中的浮动造成的父元素高度坍塌(这个是利用bfc解决 float 的副作用,不是清除浮动)。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style type="text/css">
        .container {
            background-color: #f1f1f1;
        }
        .left {
            float: left;
        }
        .bfc {
            overflow: hidden; /* 触发元素 BFC */
        }
    </style>
</head>
<body>
    <div class="container bfc">
        <img src="https://img3.sycdn.imooc.com/5e87e32c0001c80707000700-140-140.jpg" class="left" style="margin-right: 10px;"/>
        <p class="bfc">某一段文字……</p>
    </div>
</body>
</html>

float布局的问题

  1. 如何实现圣杯布局和双飞翼布局

/ 圣杯布局和双飞翼布局的目的:

a. 三栏布局,中间一栏最先加载和渲染(内容最重要)

b. 两侧内容固定,中间内容随宽度自适应

c. 一般用于 PC 网页

// 圣杯布局和双飞翼布局的技术总结:

a. 使用 float 布局

b. 两侧使用 margin 负值,以便和中间内容横向重叠

c. 防止中间内容被两侧覆盖,一个用 padding(圣杯) 一个用 margin(双飞翼)
圣杯布局:
  1. 用 padding 给左右两栏预留空间

  2. 左栏使用 margin-left:-100%,移动一个 center 的距离,再使用position:relative right:left栏宽度,向左偏移以填充预留左栏空间 (这里为什么使用百分比?无法得知正确的中间栏宽度所以使用百分比。)

  3. 右栏相对简单,使用 margin-right: -150px即可 (如果你想也可以使用margin-left,但是要添加position relative,以及相对偏移>得不偿失)

  4. 以上就要求了三栏最好被一个容器div包裹,以方便中间栏被内边距压缩出两栏的空间,另外左边栏需要相对容器边缘进行移动,如果没用就相对body,理解起来更难。当然,使用双飞翼布局就没有这些要求了

<body>
    <div id="header">this is header</div>
    <div id="container" class="clearfix">
      <div id="center" class="column">this is center</div>
      <div id="left" class="column">this is left</div>
      <div id="right" class="column">this is right</div>
    </div>
    <div id="footer">this is footer</div>
</body>

<style type="text/css">
    body {
      min-width: 550px;
    }
    #header {
      text-align: center;
      background-color: #f1f1f1;
    }

    #container {
    /* 这里需要空余固定的位置给左右侧框 */
      padding-left: 200px;
      padding-right: 150px;
    }
    #container .column {
      float: left;
    }

    #center {
      background-color: #ccc;
      width: 100%;
    }
    #left { /* 重点在此 */ 使用了 margin 负值和 position relative
      position: relative;
      background-color: yellow;
      width: 200px;
      margin-left: -100%; 
      /* 这里设置-100%使其向左移动一个container的长度,
      即上移一层,然后设置其相对原点右侧200px(自身长度)即向左平移自身长度,
      填充container固定左侧的200px */
      right: 200px;
    }
    #right { /* 同样使用了 margin 负值,但注意左边和右边使用的负值不同,因为需要移动的位置不同 */
      background-color: red;
      width: 150px;
      margin-right: -150px
    }

    #footer {
      text-align: center;
      background-color: #f1f1f1;
    }

    .clearfix:after {
      content: '';
      display: block;
      clear: both;
    }

</style>
双飞翼布局
  1. 双飞翼布局使用 margin 给两边留出空间
  2. 没有了 padding 的阻挡,left 栏使用 margin-left:-100% 以后,即可平移至中栏左侧
  3. right 栏这里使用 margin-left 将自己平移至右侧,使用 margin-right 会导致自己贴边 中栏,因为这里中栏的右侧使用 margin 占据空间,right 栏只有使用 margin-left负值 将自己的宽度减小为0,以求平移至右侧。 4.简单从代码上看,双飞翼布局比圣杯布局减少了很多工作量。
<body>
    <div id="main" class="col">
        <div id="main-wrap">
            this is main
        </div>
    </div>
    <div id="left" class="col">
        this is left
    </div>
    <div id="right" class="col">
        this is right
    </div>
</body>

<style type="text/css">
    body {
        min-width: 550px;
    }
    .col {
        float: left;
    }

    #main {
        width: 100%;
        height: 200px;
        background-color: #ccc;
    }
    #main-wrap {
        margin: 0 190px 0 190px;
    }

    #left {
        width: 190px;
        height: 200px;
        background-color: #0000FF;
        margin-left: -100%;
    }
    #right {
        width: 190px;
        height: 200px;
        background-color: #FF0000;
        margin-left: -190px;
    }
</style>

flex布局

容器属性: 项目属性: 阮一峰老师的 flex 实战篇

2. 定位

absolute和relative分别依据什么定位

relative 依据自身定位

absolute 依据最近一层的定位元素定位

定位元素有哪些 absolute relative fixed (body,没有前三个时)

居中对齐的实现方式

  • 水平居中

inline 元素:text-align:center

block 元素:margin:auto

absolute 元素: left:50% + margin-left 负值自身宽度一半

<body>
    <div class="container container-1">
        <span>一段文字</span>
    </div>

    <div class="container container-2">
        <div class="item">
            this is block item
        </div>
    </div>

    <div class="container container-3">
        <div class="item">
            this is absolute item
        </div>
    </div>
</body>

<style type="text/css">
    .container {
        border: 1px solid #ccc;
        margin: 10px;
        padding: 10px;
    }
    .item {
        background-color: #ccc;
    }
    
	/*inline 元素:text-align:center*/
    .container-1 {
        text-align: center; 
    }
     
	/*block 元素:margin:auto*/
    .container-2 .item { 
        width: 500px;
        margin: auto;
    }

 	/*absolute 元素: left:50% + margin-left 负值自身宽度一半*/
    .container-3 {
        position: relative;
        height: 100px;
    }
    .container-3 .item {
        width: 300px;
        height: 100px;
        position: absolute;
        left: 50%;
        margin-left: -150px;
    }
</style>
  • 垂直居中

inline 元素:line-height 的值等于 height 值

absolute 元素:top:50% + margin-top 负值

absolute 元素: transform(-50%, -50%),兼容性不好

absolute 元素: top,left,bottom,right = 0 + margin:auto,兼容性好

<body>
    <div class="container container-1">
        <span>一段文字</span>
    </div>

    <div class="container container-2">
        <div class="item">
            this is item
        </div>
    </div>

    <div class="container container-3">
        <div class="item">
            this is item
        </div>
    </div>

    <div class="container container-4">
        <div class="item">
            this is item
        </div>
    </div>
</body>

<style type="text/css">
    .container {
        border: 1px solid #ccc;
        margin: 10px;
        padding: 10px;
        height: 200px;
    }
    .item {
        background-color: #ccc;
    }
    
	/*inline 元素:line-height 的值等于 height 值*/
    .container-1{
        text-align: center;
        line-height: 200px;
        height: 200px;
    }
    
	/*absolute 元素:top:50% + margin-top 负值*/
    .container-2 {
        position: relative;
    }
    .container-2 .item {
        width: 300px;
        height: 100px;
        position: absolute;
        left: 50%;
        margin-left: -150px;
        top: 50%;
        margin-top: -50px;
    }

	/*absolute 元素: transform(-50%, -50%)这里是水平垂直居中对齐*/
    .container-3 {
        position: relative;
    }
    .container-3 .item {
        width: 200px;
        height: 80px;
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%)
    }

	/*absolute 元素: top,left,bottom,right = 0 + margin:auto,这里也是水平垂直居中对齐*/
    .container-4 {
        position: relative;
    }
    .container-4 .item {
        width: 100px;
        height: 50px;
        position: absolute;
        top: 0;
        left: 0;
        bottom: 0;
        right: 0;
        margin: auto;
    }
</style>

3.图文样式

line-height 如何继承

  • 固定数字10px,子元素直接继承,line-height也为10px

  • 数字比例1.5,子元素继承该比例,使用本子元素的 line-height = font-size:10px * 1.5 = 15px 计算

  • 百分比比例200%,计算时,使用父元素的font-size: 20px,计算后得出固定数字40px,子元素继承该数字 40px 而不是百分比。

<style type="text/css">
    body {
        font-size: 20px;
        line-height: 200%; /* 40px */
    }
    p {
        background-color: #ccc;
        font-size: 16px;
    }
</style>

<body>
    <p>这是一行文字</p>
</body>

4.响应式

响应式方案有很多,但还是用rem。

rem是什么

rem 一个长度单位

  • px,绝对长度单位,最常用
  • em,相对长度单位,相对父元素,不常用
  • rem,相对长度单位,相对于根元素,常用于响应式布局

响应式布局的常用方案

  • media-query(媒体查询),根据不同的屏幕宽度设置根元素font-size + rem,这些比例固定以后不会再改变
<body>
    <div id="div1">
        this is div
    </div>
</body>

<style type="text/css">
    @media only screen and (max-width: 374px) {
        /* iphone5 或者更小的尺寸,以 iphone5 的宽度(320px)比例设置 font-size */
        html {
            font-size: 86px;
        }
    }
    @media only screen and (min-width: 375px) and (max-width: 413px) {
        /* iphone6/7/8 和 iphone x */
        html {
            font-size: 100px;
        }
    }
    @media only screen and (min-width: 414px) {
        /* iphone6p 或者更大的尺寸,以 iphone6p 的宽度(414px)比例设置 font-size */
        html {
            font-size: 110px;
        }
    }

    body {
        font-size: 0.16rem;
    }
    #div1 {
        width: 1rem;
        background-color: #ccc;
    }

</style>
  • vw,vh方案,兼容性不好 rem有弊端: 阶梯性,374-xxx 375-xxx

网页视口尺寸: window.screen.height //屏幕高度 667

window.innerHeight //网页视口高度 553,使用模拟器的时候,由于没有导航栏,所以高度变成了667

document.body.clienHeight //body高度

vh 即网页视口高度的 1/100

vw 即网页视口宽度的 1/100

vmax 取两者最大值,vmin 取两者最小值

<body>
    <p>vw vh 测试</p>
    <div id="container">
    </div>
</body>
<style>
    body {
        margin: 0;
        padding: 0;
    }

    #container {
        background-color: red;
        width: 10vw;
        height: 10vh;
    }
</style>