mirror of
https://github.com/qianguyihao/Web.git
synced 2024-11-01 13:34:46 +08:00
511 lines
11 KiB
Markdown
511 lines
11 KiB
Markdown
|
---
|
|||
|
title: 01-页面布局
|
|||
|
publish: true
|
|||
|
---
|
|||
|
|
|||
|
<ArticleTopAd></ArticleTopAd>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
## 前端面试(前言)
|
|||
|
|
|||
|
|
|||
|
### 面试基础
|
|||
|
|
|||
|
- 页面布局
|
|||
|
|
|||
|
- CSS盒模型:是CSS的基石。
|
|||
|
|
|||
|
- DOM事件
|
|||
|
|
|||
|
- HTTP协议
|
|||
|
|
|||
|
- 面向对象
|
|||
|
|
|||
|
- 原型链:能说出原型链的始末
|
|||
|
|
|||
|
|
|||
|
### 面试进阶
|
|||
|
|
|||
|
|
|||
|
- 通信:普通的通信、跨域通信
|
|||
|
|
|||
|
- 安全:CSRF、XSS。
|
|||
|
|
|||
|
- 算法
|
|||
|
|
|||
|
|
|||
|
### 回答问题时要注意的
|
|||
|
|
|||
|
(1)题干的要求真的是字面要求的这么简单吗?
|
|||
|
|
|||
|
(2)答案怎么写,技巧在哪里
|
|||
|
|
|||
|
(3)如果想证明我的实力,应该有几种答案?
|
|||
|
|
|||
|
本文来讲一下页面布局。
|
|||
|
|
|||
|
## 题目:页面布局
|
|||
|
|
|||
|
问题:假设容器的高度默认100px,请写出**三栏布局**,其中左栏、右栏的宽度各为300px,中间的宽度自适应。
|
|||
|
|
|||
|
![](http://img.smyhvae.com/20180305_1520.png)
|
|||
|
|
|||
|
分析:
|
|||
|
|
|||
|
初学者想到的答案有两种:
|
|||
|
|
|||
|
- 方法1:浮动
|
|||
|
|
|||
|
- 方法2:绝对定位。
|
|||
|
|
|||
|
但要求你能至少写出三四种方法,才算及格。剩下的方法如下:
|
|||
|
|
|||
|
- 方法3:flexbox。移动开发里经常用到。
|
|||
|
|
|||
|
- 方法4:表格布局 table。虽然已经淘汰了,但也应该了解。
|
|||
|
|
|||
|
- 方法5:网格布局 grid。
|
|||
|
|
|||
|
下面分别讲解。
|
|||
|
|
|||
|
|
|||
|
### 方法1 和方法2
|
|||
|
|
|||
|
**方法1、浮动:**
|
|||
|
|
|||
|
左侧设置左浮动,右侧设置右浮动即可,中间会自动地自适应。
|
|||
|
|
|||
|
|
|||
|
**方法2、绝对定位:**
|
|||
|
|
|||
|
左侧设置为绝对定位, left:0px。右侧设置为绝对定位, right:0px。中间设置为绝对定位,left 和right 都为300px,即可。中间的宽度会自适应。
|
|||
|
|
|||
|
|
|||
|
使用`article`标签作为容器,包裹左、中、右三个部分。
|
|||
|
|
|||
|
|
|||
|
方法1 和方法2 的代码如下:
|
|||
|
|
|||
|
```html
|
|||
|
<!DOCTYPE html>
|
|||
|
<html lang="en">
|
|||
|
|
|||
|
<head>
|
|||
|
<meta charset="UTF-8">
|
|||
|
<title>Document</title>
|
|||
|
<style>
|
|||
|
html * {
|
|||
|
padding: 0px;
|
|||
|
margin: 0px;
|
|||
|
}
|
|||
|
|
|||
|
.layout {
|
|||
|
margin-bottom: 150px;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
.layout article div { /*注意,这里是设置每个小块儿的高度为100px,而不是设置大容器的高度。大容器的高度要符合响应式*/
|
|||
|
height: 100px;
|
|||
|
}
|
|||
|
|
|||
|
/* 方法一 start */
|
|||
|
|
|||
|
.layout.float .left {
|
|||
|
float: left;
|
|||
|
width: 300px;
|
|||
|
background: red;
|
|||
|
}
|
|||
|
|
|||
|
.layout.float .right {
|
|||
|
float: right;
|
|||
|
width: 300px;
|
|||
|
background: blue;
|
|||
|
}
|
|||
|
|
|||
|
.layout.float .center {
|
|||
|
background: green;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/* 方法一 end */
|
|||
|
|
|||
|
|
|||
|
/* 方法二 start */
|
|||
|
.layout.absolute .left-center-right {
|
|||
|
position: relative;
|
|||
|
}
|
|||
|
|
|||
|
.layout.absolute .left {
|
|||
|
position: absolute;
|
|||
|
left: 0;
|
|||
|
width: 300px;
|
|||
|
background: red;
|
|||
|
}
|
|||
|
|
|||
|
/* 【重要】中间的区域,左侧定位300px,右侧定位为300px,即可完成。宽度会自使用 */
|
|||
|
.layout.absolute .center {
|
|||
|
position: absolute;
|
|||
|
left: 300px;
|
|||
|
right: 300px;
|
|||
|
background: green;
|
|||
|
}
|
|||
|
|
|||
|
.layout.absolute .right {
|
|||
|
position: absolute;
|
|||
|
right: 0;
|
|||
|
width: 300px;
|
|||
|
background: blue;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/* 方法二 end */
|
|||
|
</style>
|
|||
|
</head>
|
|||
|
|
|||
|
<body>
|
|||
|
|
|||
|
<!-- 方法一:浮动 start -->
|
|||
|
<!-- 输入 section.layout.float,即可生成 -->
|
|||
|
<section class="layout float">
|
|||
|
<!-- 用 article 标签包裹左、中、右三个部分 -->
|
|||
|
<article class="left-right-center">
|
|||
|
<!-- 输入 div.left+div.right+div.center,即可生成 -->
|
|||
|
<div class="left">
|
|||
|
我是 left
|
|||
|
</div>
|
|||
|
<div class="right">
|
|||
|
我是 right
|
|||
|
</div>
|
|||
|
<div class="center">
|
|||
|
浮动解决方案
|
|||
|
我是 center
|
|||
|
</div>
|
|||
|
|
|||
|
</article>
|
|||
|
|
|||
|
</section>
|
|||
|
<!-- 方法一:浮动 end -->
|
|||
|
|
|||
|
<section class="layout absolute">
|
|||
|
<article class="left-center-right">
|
|||
|
<div class="left">
|
|||
|
我是 left
|
|||
|
</div>
|
|||
|
<div class="right">
|
|||
|
我是 right
|
|||
|
</div>
|
|||
|
<div class="center">
|
|||
|
<h1>绝对定位解决方案</h1>
|
|||
|
我是 center
|
|||
|
</div>
|
|||
|
</article>
|
|||
|
</section>
|
|||
|
</body>
|
|||
|
</html>
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
注意上方代码中, className 定义和使用,非常规范。
|
|||
|
|
|||
|
|
|||
|
效果如下:
|
|||
|
|
|||
|
![](http://img.smyhvae.com/20180305_1640.gif)
|
|||
|
|
|||
|
|
|||
|
### 方法3、flexbox布局
|
|||
|
|
|||
|
将左中右所在的容器设置为`display: flex`,设置两侧的宽度后,然后让中间的`flex = 1`,即可。
|
|||
|
|
|||
|
|
|||
|
```html
|
|||
|
<!DOCTYPE html>
|
|||
|
<html lang="en">
|
|||
|
|
|||
|
<head>
|
|||
|
<meta charset="UTF-8">
|
|||
|
<title>Document</title>
|
|||
|
<style>
|
|||
|
html * {
|
|||
|
padding: 0;
|
|||
|
margin: 0;
|
|||
|
}
|
|||
|
|
|||
|
.layout article div {
|
|||
|
height: 100px;
|
|||
|
}
|
|||
|
|
|||
|
.left-center-right {
|
|||
|
display: flex;
|
|||
|
}
|
|||
|
|
|||
|
.layout.flex .left {
|
|||
|
width: 300px;
|
|||
|
background: red;
|
|||
|
}
|
|||
|
|
|||
|
.layout.flex .center {
|
|||
|
flex: 1;
|
|||
|
background: green;
|
|||
|
}
|
|||
|
|
|||
|
.layout.flex .right {
|
|||
|
width: 300px;
|
|||
|
background: blue;
|
|||
|
}
|
|||
|
</style>
|
|||
|
|
|||
|
</head>
|
|||
|
|
|||
|
<body>
|
|||
|
<section class="layout flex">
|
|||
|
<article class="left-center-right">
|
|||
|
<div class="left">
|
|||
|
我是 left
|
|||
|
</div>
|
|||
|
<div class="center">
|
|||
|
<h1>flex布局解决方案</h1>
|
|||
|
我是 center
|
|||
|
</div>
|
|||
|
<div class="right">
|
|||
|
我是 right
|
|||
|
</div>
|
|||
|
|
|||
|
</article>
|
|||
|
</section>
|
|||
|
|
|||
|
</body>
|
|||
|
|
|||
|
</html>
|
|||
|
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
效果如下:
|
|||
|
|
|||
|
![](http://img.smyhvae.com/20180305_1700.gif)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
### 方法4、表格布局 table
|
|||
|
|
|||
|
设置整个容器的宽度为100%,设置三个部分均为表格,然后左边的单元格为 300px,右边的单元格为 300px,即可。中间的单元格会自适应。
|
|||
|
|
|||
|
```html
|
|||
|
<!DOCTYPE html>
|
|||
|
<html lang="en">
|
|||
|
|
|||
|
<head>
|
|||
|
<meta charset="UTF-8">
|
|||
|
<title>Document</title>
|
|||
|
<style>
|
|||
|
html * {
|
|||
|
padding: 0;
|
|||
|
margin: 0;
|
|||
|
}
|
|||
|
|
|||
|
.layout.table div {
|
|||
|
height: 100px;
|
|||
|
}
|
|||
|
|
|||
|
/* 重要:设置容器为表格布局,宽度为100% */
|
|||
|
.layout.table .left-center-right {
|
|||
|
width: 100%;
|
|||
|
display: table;
|
|||
|
height: 100px;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
.layout.table .left-center-right div {
|
|||
|
display: table-cell; /* 重要:设置三个模块为表格里的单元*/
|
|||
|
}
|
|||
|
|
|||
|
.layout.table .left {
|
|||
|
width: 300px;
|
|||
|
background: red;
|
|||
|
}
|
|||
|
|
|||
|
.layout.table .center {
|
|||
|
background: green;
|
|||
|
}
|
|||
|
|
|||
|
.layout.table .right {
|
|||
|
width: 300px;
|
|||
|
background: blue;
|
|||
|
}
|
|||
|
</style>
|
|||
|
|
|||
|
</head>
|
|||
|
|
|||
|
<body>
|
|||
|
<section class="layout table">
|
|||
|
<article class="left-center-right">
|
|||
|
<div class="left">
|
|||
|
我是 left
|
|||
|
</div>
|
|||
|
<div class="center">
|
|||
|
<h1>表格布局解决方案</h1>
|
|||
|
我是 center
|
|||
|
</div>
|
|||
|
<div class="right">
|
|||
|
我是 right
|
|||
|
</div>
|
|||
|
|
|||
|
</article>
|
|||
|
</section>
|
|||
|
|
|||
|
</body>
|
|||
|
|
|||
|
</html>
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
![](http://img.smyhvae.com/20180305_1855.gif)
|
|||
|
|
|||
|
### 方法5、网格布局 grid
|
|||
|
|
|||
|
```html
|
|||
|
<!DOCTYPE html>
|
|||
|
<html lang="en">
|
|||
|
|
|||
|
<head>
|
|||
|
<meta charset="UTF-8">
|
|||
|
<title>Document</title>
|
|||
|
<style>
|
|||
|
html * {
|
|||
|
padding: 0;
|
|||
|
margin: 0;
|
|||
|
}
|
|||
|
|
|||
|
/* 重要:设置容器为网格布局,宽度为100% */
|
|||
|
.layout.grid .left-center-right {
|
|||
|
display: grid;
|
|||
|
width: 100%;
|
|||
|
grid-template-rows: 100px;
|
|||
|
grid-template-columns: 300px auto 300px; /* 重要:设置网格为三列,并设置每列的宽度。即可。*/
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
.layout.grid .left {
|
|||
|
background: red;
|
|||
|
}
|
|||
|
|
|||
|
.layout.grid .center {
|
|||
|
background: green;
|
|||
|
}
|
|||
|
|
|||
|
.layout.grid .right {
|
|||
|
background: blue;
|
|||
|
}
|
|||
|
</style>
|
|||
|
|
|||
|
</head>
|
|||
|
|
|||
|
<body>
|
|||
|
<section class="layout grid">
|
|||
|
<article class="left-center-right">
|
|||
|
<div class="left">
|
|||
|
我是 left
|
|||
|
</div>
|
|||
|
<div class="center">
|
|||
|
<h1>网格布局解决方案</h1>
|
|||
|
我是 center
|
|||
|
</div>
|
|||
|
<div class="right">
|
|||
|
我是 right
|
|||
|
</div>
|
|||
|
|
|||
|
</article>
|
|||
|
</section>
|
|||
|
|
|||
|
</body>
|
|||
|
|
|||
|
</html>
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
效果:
|
|||
|
|
|||
|
![](http://img.smyhvae.com/20180305_1920.gif)
|
|||
|
|
|||
|
|
|||
|
### 延伸:五种方法的对比
|
|||
|
|
|||
|
- 五种方法的优缺点
|
|||
|
|
|||
|
- 考虑中间模块的高度问题
|
|||
|
|
|||
|
- 兼容性问题:实际开发中,哪个最实用?
|
|||
|
|
|||
|
|
|||
|
方法1:浮动:
|
|||
|
|
|||
|
- 优点:兼容性好。
|
|||
|
|
|||
|
- 缺点:浮动会脱离标准文档流,因此要清除浮动。我们解决好这个问题即可。
|
|||
|
|
|||
|
|
|||
|
方法:2:绝对定位
|
|||
|
|
|||
|
|
|||
|
- 优点:快捷。
|
|||
|
|
|||
|
- 缺点:导致子元素也脱离了标准文档流,可实用性差。
|
|||
|
|
|||
|
|
|||
|
方法3:flex 布局(CSS3中出现的)
|
|||
|
|
|||
|
- 优点:解决上面两个方法的不足,flex布局比较完美。移动端基本用 flex布局。
|
|||
|
|
|||
|
|
|||
|
方法4:表格布局
|
|||
|
|
|||
|
- 优点:表格布局在很多场景中很实用,兼容性非常好。因为IE8不支持 flex,此时可以尝试表格布局
|
|||
|
|
|||
|
- 缺点:因为三个部分都当成了**单元格**来对待,此时,如果中间的部分变高了,其会部分也会被迫调整高度。但是,在很多场景下,我们并不需要两侧的高度增高。
|
|||
|
|
|||
|
什么时候用 flex 布局 or 表格布局,看具体的场景。二者没有绝对的优势,也没有绝对的不足。
|
|||
|
|
|||
|
方法5:网格布局
|
|||
|
|
|||
|
- CSS3中引入的布局,很好用。代码量简化了很多。
|
|||
|
|
|||
|
PS:面试提到网格布局,说明我们对新技术是有追求的。
|
|||
|
|
|||
|
### 延伸:如果题目中去掉高度已知
|
|||
|
|
|||
|
问题:题目中,如果去掉高度已知,我们往中间的模块里塞很多内容,让中间的模块撑开。会发生什么变化?哪个布局就不能用了?
|
|||
|
|
|||
|
|
|||
|
分析:其实可以这样理解,我们回去看上面的动画效果,当中间的模块变得很挤时,会发生什么效果?就是我们想要的答案。
|
|||
|
|
|||
|
答案是:**flex 布局和表格布局可以通用**,其他三个布局都不能用了。
|
|||
|
|
|||
|
|
|||
|
### 页面布局的变通
|
|||
|
|
|||
|
![](http://img.smyhvae.com/20180305_1931.png)
|
|||
|
|
|||
|
`上下高度固定,中间自适应`,这个在移动端的页面中很常见。
|
|||
|
|
|||
|
### 总结
|
|||
|
|
|||
|
涉及到的知识点:
|
|||
|
|
|||
|
(1)语义化掌握到位:每个区域用`section`、`article`代表容器、`div`代表块儿。如果通篇都用 div,那就是语义化没掌握好。
|
|||
|
|
|||
|
(2)页面布局理解深刻。
|
|||
|
|
|||
|
(3)CSS基础知识扎实。
|
|||
|
|
|||
|
(4)思维灵活且积极上进。题目中可以通过`网格布局`来体现。
|
|||
|
|
|||
|
(5)代码书写规范。注意命名。上面的代码中,没有一行代码是多的。
|
|||
|
|