一,盒模型

  说到 CSS 布局这块的内容,首当其冲的就是我们的盒模型宽度计算问题,在开始我们的问题之前,我们首先要搞懂这些概念:

  • 盒模型里面的内容(content): 也就是实实在在要展现的内容,比如 P 标签里面的文字。在没有设置box-sizing: border-box之前我们可以把它的宽度理解为就是width的值,不包括paddingborder
  • 盒模型的内边距(padding): 是内容与边框内部之间的距离
  • 盒模型的边框(border): 边框也可以设置宽度
  • 盒模型的外边距(margin): 盒模型的边框外部与其他盒模型边框外部之间的距离

  了解了这些,我们再来看下面的几个进阶概念:

  • offsetWidth: 指的是盒模型的边框(border) + 内边距(padding) + 内容的宽度(width)
  • clientWidth: 指的是盒模型的内边距(padding) + 内容的宽度(width)
  • scrollWidth: 如果内容超出边框,需要有滚动条,那么scrollWidth获取的是整个文档的内容(而clientWidth获取的只是可见部分的宽度)

  OK,我们来看一道简单的计算题


<style>
    #main {
        width: 100px;
        border: 1px solid #ccc;
        padding: 10px
    }
</style>

//offsetWidth => 122px

  很明显,我们想要的结果offsetWidth就等于 100+20+2=122px。那么,我们如果想要offsetWidth=100px,代码该怎么写呢?很简单,加入一句box-sizing: border-box就可以了。

二,margin 的纵向重叠问题

  我们先来看一段代码:


/*css*/
p{
    margin-top: 10px;
    margin-bottom: 15px;
}

/*HTML*/
<p>小宏</p>
<p></p>
<p></p>
<p></p>
<p>小宏</p>

  运行出来的效果是这样的:

[面试仓库]CSS面试题汇总--布局篇-LMLPHP

  很明显,并没有像我们想象中的,二者之间应该会有很大的距离。所以我们不难得出:相邻元素的margin-topmargin-bottom是会重叠的,以数值大的为主。空白内容的块级标签也是会重叠的,只不过他们的margin我们可以忽略不计。

三,margin 负值问题

  我们直接把知识点摆出来:

  • margin-topmargin-left设置负值,元素会分别向上、向左移动相应的长度
  • margin-right设置负值,当前元素的右侧元素左移相应的长度,自身不受影响。如果右边没有元素,自身也不会受到影响
  • margin-bottom设置负值,当前元素的下侧元素上移相应的长度,自身不受影响。如果下边没有元素,自身也不会受到影响

  我们来看看效果:

[面试仓库]CSS面试题汇总--布局篇-LMLPHP

[面试仓库]CSS面试题汇总--布局篇-LMLPHP

[面试仓库]CSS面试题汇总--布局篇-LMLPHP

[面试仓库]CSS面试题汇总--布局篇-LMLPHP

四,BFC(Block Format Context)

  何谓 BFC 呢?大部分都将其解析为块级格式化上下文,是 Web 页面中盒模型布局的 CSS 渲染模式,指一个独立的渲染区域或者说是一个隔离的独立容器。其内部元素的渲染不会影响到边界以外的元素。我们主要从以下几个方面来理解它。

形成条件

  • float 不是 none
  • position 是 absolute 或 fixed
  • overflow 不是 visible
  • display 是 flex、inline-block、table-cell、table-caption 其中之一

实际应用

  阻止元素被浮动元素覆盖

  两栏布局,左边固定宽度,右边不设宽,随浏览器自适应


/*html*/
<div class="column"></div>
<div class="column"></div>

/*css*/
.column:nth-of-type(1) {
    float: left;
    width: 200px;
    height: 300px;
    margin-right: 10px;
    background-color: red;
}

.column:nth-of-type(2) {
    overflow: hidden;/*创建BFC */
    height: 300px;
    background-color: purple;
}

[面试仓库]CSS面试题汇总--布局篇-LMLPHP

  阻止相邻元素的 margin 合并

  我们在 margin 负值的问题中提到过合并问题。我们可以通过设置 BFC 来解决:

/*html*/
<div class="container">
    <div class="box1"></div>
    <div class="box2"></div>//会出现合并的情况

    <div class="wrapper">
        <div class="box1"></div>//让二者其一处于另一个BFC中
    </div>
    <div class="box2"></div>
</div>

/*css*/
.container {
    overflow: hidden;
    width: 100px;
    height: 100px;
    background-color: red;
}

.wrapper {
    overflow: hidden;//设置BFC
}

.box1 {
    height: 20px;
    margin: 10px 0;
    background-color: green;
}

.box2 {
    height: 20px;
    margin: 20px 0;//未设置BFC,以大的为准,二者距离本为20px
    background-color: green;
}

[面试仓库]CSS面试题汇总--布局篇-LMLPHP

  阻止字体环绕

[面试仓库]CSS面试题汇总--布局篇-LMLPHP

  很简单,给我们的 p 标签设置 BFC 就好了

[面试仓库]CSS面试题汇总--布局篇-LMLPHP

五,float 的应用

  float 是我们 CSS 中非常常用的属性了,我们在开发中经常用它来实现三栏布局。主要特点是:

1.中间一栏最先加载和渲染 2.两侧内容固定,中间内容随宽度自适应 3.主要用于 PC

圣杯布局

  圣杯布局的方法实现主要是针对容器 div 的padding这块来下手的,我们整理一下实现步骤:

  1. 首先用一个大的 div 来包裹我们的三栏 left、center、right,并给大 div 的padding-left设置为 left 栏的宽度,padding-right设置为 right 栏的宽度
  2. 给我们的三栏分别设置float:left属性
  3. center 栏:设置width:100%
  4. left 栏:设置position:relative;right:[自身宽度];margin-left:-100%
  5. right 栏:设置margin-right:-[自身宽度]; 6.注意:要给body设置min-width属性,且值要大于或等于2*left的width+1*right的width,不然中间会被挤上去

[面试仓库]CSS面试题汇总--布局篇-LMLPHP

  这是 HTML 方面的代码

<div class="container">
  <div class="center">中间</div>
  <div class="left">左</div>
  <div class="right">右</div>
</div>

双飞翼布局

  双飞翼布局的方法实现主要是针对margin这块来下手的,相比于圣杯布局,理解起来也方便一些,只是在 HTML 代码方面我们要与圣杯布局的稍作区别:

<div class="main-container col">
    <div class="main">中间(将中间包裹在div中,方便留白)</div>
</div>

<div class="left col">左</div>
<div class="right col">右</div>

我们整理一下实现步骤:

  1. 三栏都设置float: left属性,即上面的col
  2. main-container处留白。给main框设置margin: 0 left的宽度 0 right的宽度
  3. left框设置margin-left: -100%
  4. right框设置margin-left: -[自身宽度]
  5. 注意:要给body设置min-width属性,且值要大于或等于left的width+right的width,不然中间会被挤上去

[面试仓库]CSS面试题汇总--布局篇-LMLPHP

六,手写 clearFix

  回到我们的圣杯布局,我们总觉得好像缺点什么要素。没错,这三栏就像我们的网页中主要内容,我们还应该要有我们的头部和尾部布局。于是我们理所当然的把上面的 HTML 代码改成了下面这样:

<div class="header">头部内容</div>
<div class="container">
  <div class="center">中间</div>
  <div class="left">左</div>
  <div class="right">右</div>
</div>
<div class="footer">底部内容</div>

  可渲染出的效果,并不是很理想

[面试仓库]CSS面试题汇总--布局篇-LMLPHP

  可以看到,我们的底部内容跑到了右边,并且被 container 框压住了,这是因为有 float 的原因。当然,我们给 footer 一个clear:both就可以让他下去了,这里呢,我们不准备操作 footer,我们尝试着自己写一个 clearFix 来实现这个功能。

/*html*/
<div class="container clearFix">
  <div class="center">中间</div>
  <div class="left">左</div>
  <div class="right">右</div>
</div>

/*css*/
.clearFix:after {
    content: '';
    display: table;
    clear: both;
}

[面试仓库]CSS面试题汇总--布局篇-LMLPHP

七,flex 布局

  flexBox 布局,指的是在display: flex下的布局操作。首先呢,我们要记住一些我们常见的有关 flex 的 css 属性:

  1. flex-direction 定义容器要在哪个方向上堆叠 flex 项目。有四个属性值,分别为:
    • column [设置垂直堆叠 flex 项目(从上到下)]
    • column-reverse[垂直堆叠 flex 项目(从下到上)]
    • row[水平堆叠 flex 项目(从左到右)]
    • row-reverse[水平堆叠 flex 项目(从右到左)]
  2. justify-content 用于对齐 flex 项目。有五个属性值,分别为:
    • center [将 flex 项目在容器的中心对齐]
    • flex-start [将 flex 项目在容器的开头对齐(默认)]
    • flex-end [将 flex 项目在容器的末尾对齐]
    • space-around[显示行之前、之间和之后带有空格的 flex 项目]
    • space-between [显示行之间带有空格的 flex 项目]
  3. align-items 用于垂直对齐 flex 项目。也有五个属性值,分别为:
    • center [将 flex 项目在容器的中心对齐]
    • flex-start [将 flex 项目在容器的顶部对齐]
    • flex-end [将 flex 项目在容器的底部对齐]
    • stretch[拉伸 flex 项目填充容器]
    • space-between [使 flex 项目基线对齐]
  4. flex-wrap 规定是否应该对 flex 项目换行.有三个属性值,分别为:
    • wrap [规定 flex 项目将在必要时进行换行]
    • nowrap [规定 flex 项目不要换行(默认)]
    • wrap-reverse [规定 flex 项目将在必要时以相反的顺序进行换行]
  5. align-self 这个属性实际上是重写了align-items,我们主要来用它实现居中对齐,因此,我们记住center这一常用属性值就好了,其他的属性值和align-items差不多。也可以理解为align-self: center;=justify-content: center;align-items: center;

  ok,我们来一个简单的案例:色子。为了方便大家看,我们只实现点数为3的这一面

/*主要代码*/
.container{
    display: flex;
    justify-content: space-between;/*容器*/
}

.item:nth-child(2){
    align-self: center;/*第二个点*/
}
.item:nth-child(3){
    align-self: flex-end;/*第三个点*/
}

[面试仓库]CSS面试题汇总--布局篇-LMLPHP


  以上就是css常考的一些重要知识点,我也会在后面做出适当的更新补充。下次见!

04-15 04:40