# CSS 响应式布局面试题答案解析

关于答案解析

  • CSS 响应式布局相关面试题答案解析过程是根据自身项目实践以及查阅官方文档等最终的得出结论。
  • 仅供学习参考,评论区感谢补充和纠错 !

# 1、CSS 单位 px em remvw vh 的区别和联系(58、字节)

答案解析

  • px 就是 pixel(像素)的缩写,相对长度单位,相对于屏幕分辨率。
  • em 参考物是父元素的 font-size,具有继承的特点。如果父元素 font-size:14px;则 1em 就是 14px 大小
  • rem 是 CSS3 新增的一个相对单位,但相对的只是 HTML 根元素的 font-size 大小
  • vm、vh 也是一种相对单位,他们分别相对于视窗宽度和高度的百分比。比如 (10vw 代表视窗的宽的 10%)

补充两个:

  • vmin: 选择视窗最小的那一个 (坚屏时 100vmin = 100vw)
  • vmax:选择视窗最大的那一个 (竖屏时 100vmax = 100vh)

# 2、rem 怎么实现页面等比例放大/缩小 ?(创业公司)

答案解析


① rem 如何适配

  • rem 是相对于 html 根元素的字体大小的单位
  • 我们通过修改 html 中 font-size 的字体大小来控制 rem 的大小

比如:

html {
  font-size: 10px;
}
.box {
  width: 10rem;
  height: 20rem;
}
  • 当 html 中 font-size: 10px; 时,此时 1rem = 10px,所以 box 盒子的宽高分别为:100px 和 200px
  • 当我们把 html 中 font-size: 20px; 时,此时 1rem = 20px,此时 box 盒子的宽高就为 200px 和 400px

② 实际开发中如何适配,如何将设计稿对应的 px 单位转换为 rem 单位

  • 在实际的开发中,我们通常会以 750px 的移动端设计稿来开发。
  • 我们在代码写完后,统一会把所有 px 单位全部转成 rem 来实现。

在 px 单位下,一个盒子的样式如下:

.box {
  width: 700px;
  height: 500px;
  font-size: 20px;
  padding: 10px;
  background-color: red;
}
  • 如果我们把总宽 750px 分成 10rem,些时1rem = 75px;,转成对应的 rem 单位,就是用对应的 px/75px

得到如下结果:

.box {
  width: 9.3333rem;
  height: 6.6667rem;
  font-size: 0.2667rem;
  padding: 0.1333rem;
  background-color: red;
}
  • 以上单位的转换,我们可以利用 vscode 的插件 px to rem 来自动实现
  • 把所有代码全部写完,然后一次性用 px to rem 插件转换成 rem 单位

③ 接下来如何适配不同的浏览器,实现等比例的缩放呢 ?

  • 比如:现在有 5 个同尺寸的屏幕 (750 640 480 375 320),所有屏幕整体宽分成 10rem
  • 那我们就需要分别得到这几种不同屏幕下对应的 html 根元素的 font-size 大小了
屏幕尺寸 html 中 font-size 大小 (1rem 大小)
750px 75px
640px 64px
480px 48px
375px 37.5px
320px 32px
  • 我们可以通过 js 来动态修改不同屏幕尺寸下的 font-size 大小就可以实现等比例放大和缩小了
  • js 动态修改 html 根元素的 font-size 的大小,能适配不同尺寸的屏幕,不再局限于这 5 种

代码如下:

<script>
  initPage();
  function initPage() {
    var clientWidth =
      document.documentElement.clientWidth || document.body / clientWidth; //获取屏幕可视区宽
    var html = document.getElementsByTagName("html")[0]; //获取html根元素
    html.style.fontSize = clientWidth / 10 + "px"; //动态设置font-size大小
  }
  window.onresize = initPage;
</script>

# 3、响应式布局如何实现及原理?(小米、58、字节、商汤)

答案解析

响应式布局:只需要开发一套代码,只需要一套代码使页面适应不同的屏幕

  • 响应式设计通过检测视口分辨率,针对不同客户端在客户端做代码处理,来展现不同的布局和内容

响应式布局的 5 种实现方案

  • 百分比布局
  • 媒体查询布局
  • rem 响应式布局
  • vw 响应式布局
  • flex 弹性布局

详细解读如下:

# ① 百分比布局

详细解读

比如,当浏览器的宽度或者高度发生变化时,通过百分比单位可以使得浏览器中的组件的宽和高随着浏览器的变化而变化,从而实现响应式的效果。

  • height、width 属性的百分比依托于父标签的宽高。但是 padding、border、margin 等属性的情况又不一样

    • 子元素的 top 和 bottom 如果设置百分比,则相对于直接非 static 定位(默认定位)的父元素的高度,同样,子元素的 left 和 right 如果设置百分比,则相对于直接非 static 定位(默认定位的)父元素的宽度。
    • 子元素的 padding 和 margin 如果设置百分比,不论是垂直方向或者是水平方向都相对于直接父亲元素的 width,而与父元素的 height 无关。
  • border-radius 为百分比,则是相对于自身的宽度

缺点

计算困难,如果我们要定义一个元素的宽度和高度,按照设计稿,必须换算成百分比单位。

# ② 媒体查询布局

详细解读

通过@media 媒体查询,可以通过给不同屏幕的大小编写不同的样式来实现响应式的布局。

响应式缺点:如果浏览器大小改变时,需要改变的样式太多,那么多套样式代码会很繁琐。

点击查看源代码
<style>
  .box {
    width: 500px;
    height: 500px;
    background-color: aqua;
  }
  @media screen and (max-width: 1280px) {
    .box {
      width: 400px;
      height: 400px;
    }
  }
  @media screen and (max-width: 980px) {
    .box {
      width: 300px;
      height: 300px;
    }
  }
  @media screen and (max-width: 765px) {
    .box {
      width: 200px;
      height: 200px;
    }
  }
</style>
<body>
  <div class="box"></div>
</body>

在实际开发中,常用的响应断点阈值设定

(括号后面是样式的缩写)

  • <576px (Extra small)
  • >=576px (Small --- sm)
  • >=769px (Medium --- md)
  • >=992px (Large --- lg)
  • >=1200px (X-Large --- xl)
  • >=1400px (XX-Large ---- xxl)

在实际开发中,常用的两种适配方案

a、移动端 到 PC 端适配原则 (min-width 从小到大)

点击查看源代码
<style>
  body {
    background-color: #000;
  }
  @media screen and (min-width: 576px) {
    body {
      background-color: red;
    }
  }
  @media screen and (min-width: 769px) {
    body {
      background-color: yellow;
    }
  }
  @media screen and (min-width: 992px) {
    body {
      background-color: blue;
    }
  }

  @media screen and (min-width: 1200px) {
    body {
      background-color: green;
    }
  }
  @media screen and (min-width: 1400px) {
    body {
      background-color: orange;
    }
  }
</style>

b、PC 端 到 移动端适配原则 (max-width 从大到小)

点击查看源代码
<style>
  body {
    background-color: #000;
  }
  @media screen and (max-width: 1400px) {
    body {
      background-color: red;
    }
  }
  @media screen and (max-width: 1200px) {
    body {
      background-color: yellow;
    }
  }
  @media screen and (max-width: 992px) {
    body {
      background-color: blue;
    }
  }

  @media screen and (max-width: 769px) {
    body {
      background-color: green;
    }
  }
  @media screen and (max-width: 576px) {
    body {
      background-color: orange;
    }
  }
</style>

在实际开发时,@media 会结合删格系统一起来使用,实现真正意义上的响应式开发。

  • 栅格布局+断点设定 实现响应式
点击查看源代码
@media screen and (min-width: 576px) {
  .col-sm-1 {
    grid-area: auto/auto/auto/span 1;
  }
  .col-sm-2 {
    grid-area: auto/auto/auto/span 2;
  }
  .col-sm-3 {
    grid-area: auto/auto/auto/span 3;
  }
  .col-sm-4 {
    grid-area: auto/auto/auto/span 4;
  }
  .col-sm-5 {
    grid-area: auto/auto/auto/span 5;
  }
  .col-sm-6 {
    grid-area: auto/auto/auto/span 6;
  }
  .col-sm-7 {
    grid-area: auto/auto/auto/span 7;
  }
  .col-sm-8 {
    grid-area: auto/auto/auto/span 8;
  }
  .col-sm-9 {
    grid-area: auto/auto/auto/span 9;
  }
  .col-sm-10 {
    grid-area: auto/auto/auto/span 10;
  }
  .col-sm-11 {
    grid-area: auto/auto/auto/span 11;
  }
  .col-sm-12 {
    grid-area: auto/auto/auto/span 12;
  }
}
@media screen and (min-width: 768px) {
  .col-md-1 {
    grid-area: auto/auto/auto/span 1;
  }
  .col-md-2 {
    grid-area: auto/auto/auto/span 2;
  }
  .col-md-3 {
    grid-area: auto/auto/auto/span 3;
  }
  .col-md-4 {
    grid-area: auto/auto/auto/span 4;
  }
  .col-md-5 {
    grid-area: auto/auto/auto/span 5;
  }
  .col-md-6 {
    grid-area: auto/auto/auto/span 6;
  }
  .col-md-7 {
    grid-area: auto/auto/auto/span 7;
  }
  .col-md-8 {
    grid-area: auto/auto/auto/span 8;
  }
  .col-md-9 {
    grid-area: auto/auto/auto/span 9;
  }
  .col-md-10 {
    grid-area: auto/auto/auto/span 10;
  }
  .col-md-11 {
    grid-area: auto/auto/auto/span 11;
  }
  .col-md-12 {
    grid-area: auto/auto/auto/span 12;
  }
}
@media screen and (min-width: 992px) {
  .col-lg-1 {
    grid-area: auto/auto/auto/span 1;
  }
  .col-lg-2 {
    grid-area: auto/auto/auto/span 2;
  }
  .col-lg-3 {
    grid-area: auto/auto/auto/span 3;
  }
  .col-lg-4 {
    grid-area: auto/auto/auto/span 4;
  }
  .col-lg-5 {
    grid-area: auto/auto/auto/span 5;
  }
  .col-lg-6 {
    grid-area: auto/auto/auto/span 6;
  }
  .col-lg-7 {
    grid-area: auto/auto/auto/span 7;
  }
  .col-lg-8 {
    grid-area: auto/auto/auto/span 8;
  }
  .col-lg-9 {
    grid-area: auto/auto/auto/span 9;
  }
  .col-lg-10 {
    grid-area: auto/auto/auto/span 10;
  }
  .col-lg-11 {
    grid-area: auto/auto/auto/span 11;
  }
  .col-lg-12 {
    grid-area: auto/auto/auto/span 12;
  }
}
.......xl xxl两种省略;

# ③ rem 布局

rem 如何适配

  • rem 是相对于 html 根元素的字体大小的单位。
  • 我们通过修改 html 中 font-size 的字体大小来控制 rem 的大小。

比如:

html {
  font-size: 10px;
}
.box {
  width: 10rem;
  height: 20rem;
}
  • 当 html 中 font-size: 10px; 时,此时 1rem = 10px,所以 box 盒子的宽高分别为:100px 和 200px;
  • 当我们把 html 中 font-size: 20px; 时,此时 1rem = 20px,此时 box 盒子的宽高就为 200px 和 400px;

实际开发中如何适配,如何将设计稿对应的 px 单位转换为 rem 单位

TIP

  • 在实际的开发中,我们通常会以 750px 的移动端设计稿来开发。
  • 我们在代码写完后,统一会把所有 px 单位全部转成 rem 来实现。

在 px 单位下,一个盒子的样式如下:

.box {
  width: 700px;
  height: 500px;
  font-size: 20px;
  padding: 10px;
  background-color: red;
}

如果我们把总宽 750px 分成 10rem,些时 1rem = 75px; ,转成对应的 rem 单位,就是用对应的 px/75px,得到如下结果。

.box {
  width: 9.3333rem;
  height: 6.6667rem;
  font-size: 0.2667rem;
  padding: 0.1333rem;
  background-color: red;
}
  • 以上单位的转换,我们可以利用 vscode 的插件 px to rem 来自动实现。
  • 把所有代码全部写完,然后一次性用 px to rem 插件转换成 rem 单位

接下来如何适配不同的浏览器,实现等比例的缩放呢 ?

TIP

  • 比如现在有 5 个同尺寸的屏幕 (750 640 480 375 320),所有屏幕整体宽分成 10rem
  • 那我们就需要分别得到这几种不同屏幕下对应的 html 根元素的 font-size 大小了。
屏幕尺寸 html 中 font-size 大小 (1rem 大小)
750px 75px
640px 64px
480px 48px
375px 37.5px
320px 32px
  • 我们可以通过 js 来动态修改不同屏幕尺寸下的 font-size 大小就可以实现等比例放大和缩小了
  • js 动态修改 html 根元素的 font-size 的大小,能适配不同尺寸的屏幕,不再局限于这 5 种
点击查看源代码
<script>
  initPage();
  function initPage() {
    var clientWidth =
      document.documentElement.clientWidth || document.body / clientWidth; //获取屏幕可视区宽
    var html = document.getElementsByTagName("html")[0]; //获取html根元素
    html.style.fontSize = clientWidth / 10 + "px"; //动态设置font-size大小
  }
  window.onresize = initPage;
</script>

注:

我们可以用 flexible.js 插件来帮我们实现

  • flexible 原理就是根据不同的屏幕宽度动态的设置网页中 html 根节点的 font-size
  • 然后咱们将所有的 px 用 rem 来代替,这样就实现了不同大小的屏幕都适应相同的样式了。

# ④ vw、vh 响应式布局

详细解读

vw 和 vh 分别相对的是视图窗口的宽度和视口窗的高度。

  • 100vw = 视图窗宽度 ,100vh = 100 视图窗高度
  • 如果移动端有 5 个不同的视口宽尺寸 750 ,640,480,375,320,则在不同尺寸下,对应的 1vw 的 px 值如下表
移动端尺寸 1vw
750px 7.5px
640px 6.4px
480px 4.8px
375px 3.75px
320px 320px
  • 我们在实际开发时,只需要按其中的某一个尺寸来的 px 单位的设计稿来开发就好(一般是以 750px 的大小为主)
  • 代码全部开发好后,我们再利用 vscode 的插件 px to vw 来实现单位的自动转换。

案例: 宽为 750px 设计稿下的某个元素样式如下

<style>
  body {
    margin: 0;
  }
  .box {
    width: 750px;
    height: 300px;
    background-color: red;
  }
</style>
<body>
  <div class="box"></div>
</body>

转换为 vw 后的代码如下:

<style>
  body {
    margin: 0;
  }
  .box {
    width: 100vw;
    height: 40vw;
    background-color: red;
  }
</style>
<body>
  <div class="box"></div>
</body>
  • 在宽为 750px 的设计稿下,把 px 转换为 vw,是用 px/7.5 得到对应的 vw 单位值
  • 转换好后,vw 是自动适应视口宽的,所以就达到了响应式开发的效果。

# ⑤ flex 弹性布局

详细解读

弹性布局是一种十分方便的,只需要依赖于 CSS 样式的实现响应式布局的方式,也是最多用到的一种实现响应式的方法。

弹性布局在父、子元素上都有相对应的属性来规范子元素在父元素中的 “ 弹力 ”。

  • 在父元素上,我们经常会用到的有关弹性布局的属性主要有 flex-direction , flex-wrap , justify-content , align-items , align-content ,这几个属性分别从 主轴的方向、是否换行、项目在主轴上的对齐方式、项目在交叉轴上的对齐方式、项目在多根轴线上的对齐方式来规范了项目在父元素中的弹性。
  • 在子元素上,我们经常会用到的有关弹性布局的属性主要有 order , flex-grow , flex-shrink ,flex-basis , align-self ,这几个属性分别从 项目的排序、项目放大比例、项目缩小比例、项目占据主轴空间、单个项目在交叉轴上的对齐方式来规范了项目自身的弹性。
上次更新时间: 6/8/2023, 9:23:17 PM

大厂最新技术学习分享群

大厂最新技术学习分享群

微信扫一扫进群,获取资料

X