前端面试 -- 页面布局与设备适配
页面布局与设备适配
在前端面试专栏的前几篇文章中,我们了解到了JS相关的一些面试重点考察内容,本篇文章将重点讲述面试中经常遇到的一些页面布局与设备适配问题。废话不多说,一起来看看吧!
1-div在页面中水平垂直居中
方法1:绝对定位
方法2:固定定位
方法3:绝对定位 + margin
注意:方法1和方法3只适用于页面没有滚动条的情形;而方法2适用于各种情形,div始终在页面正中央
<!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>01-div在页面中水平垂直居中</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
height: 2000px;
}
/* 方法1 */
/* div {
width: 200px;
height: 100px;
background: red; */
/* absolute 只适用于页面没有滚动条的情形 */
/* position: absolute; */
/* fixed 适用于各种情形,div始终在页面正中央 */
/* position: fixed; */
/* top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
} */
/* 方法2 只适用于页面没有滚动条的情形 */
div {
width: 200px;
height: 100px;
background: red;
position: absolute;
top: 50%;
left: 50%;
margin: -100px 0 0 -50px;
}
</style>
</head>
<body>
<div></div>
</body>
</html>
方法4:flex布局
注意:使用方法4,如果页面中有滚动条,则div在整个页面中是居中的
<!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>01-flex让div在页面中水平垂直居中</title>
<style>
/* 如果页面中有滚动条,则div在整个页面中是居中的 */
* {
margin: 0;
padding: 0;
}
html,body {
height: 100%;
}
body {
display: flex;
height: 2000px;
justify-content: center;
align-items: center;
}
div {
width: 200px;
height: 200px;
background: red;
}
</style>
</head>
<body>
<div></div>
</body>
</html>
2-布局自适应
2-1-左右布局自适应
- 左右布局自适应:左边固定,右边自适应
- 要点:左边向左浮动,右边不设宽度,隐藏浮动
<!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>02-1-左右布局自适应</title>
<style>
/* 左右布局自适应:左边固定,右边自适应 */
/*
要点:左边向左浮动,右边不设宽度,隐藏浮动
*/
* {
margin: 0;
padding: 0;
}
.left {
width: 200px;
height: 300px;
background: red;
float: left;
}
.main {
height: 500px;
background: yellow;
overflow: hidden;
}
</style>
</head>
<body>
<div class="left"></div>
<div class="main"></div>
</body>
</html>
2-2-左中右布局自适应
- 左右布局自适应(双飞翼布局):左右两边固定,中间自适应
- 要点:左边向左浮动,右边向右浮动,中间隐藏浮动
- 隐藏浮动为什么可以实现自适应?
- overflow:hidden; 可以触发bfc
- bfc: block format context 块级格式化上下文
- bfc渲染规则:bfc里计算高度时,浮动的元素也参与计算
<!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>02-2-左中右布局自适应</title>
<style>
/* 左右布局自适应(双飞翼布局):左右两边固定,中间自适应 */
/*
要点:左边向左浮动,右边向右浮动,中间隐藏浮动
overflow:hidden; 可以触发bfc bfc: block format context 块级格式化上下文
渲染规则:bfc里计算高度时,浮动的元素也参与计算
*/
* {
margin: 0;
padding: 0;
}
.left {
width: 200px;
height: 300px;
background: red;
float: left;
}
.main {
height: 500px;
background: yellow;
overflow: hidden;
}
.right {
width: 200px;
height: 200px;
background: #999;
float: right;
}
</style>
</head>
<body>
<div class="left"></div>
<div class="right"></div>
<div class="main">文字文字</div>
</body>
</html>
3-解决高度塌陷
高度塌陷:父元素没有高度,当子元素没有浮动时,父元素的高度由子元素决定;当子元素有浮动时,父元素的高度=0
由于高度塌陷是子元素浮动引起的,所以解决高度塌陷要点就是要清除浮动(清除浮动后,父元素自动检测子元素的高度,以最高的为准),主要有以下4种方法:
3-1-额外标签法
- 在最后一个浮动的子元素后面,新添加一个标签,设置这个标签clear: both;
- 优点:通俗易懂,书写方便
- 缺点:添加许多无意义的标签,结构化较差
3-2-给父元素添加overflow:hidden;
3-3-使用:after伪元素清除浮动
- 这个方法是额外标签法的升级版,好处是不用单独加标签
3-4-使用before和after双伪元素清除浮动
<!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>03-解决高度塌陷</title>
<style>
/*
高度塌陷:父元素没有高度,当子元素没有浮动时,父元素的高度由子元素决定;当子元素有浮动时,父元素的高度=0
由于高度塌陷是子元素浮动引起的,所以解决高度塌陷要点就是要清除浮动(清除浮动后,父元素自动检测子元素的高度,
以最高的为准),主要有以下4种方法:
1-额外标签法:在最后一个浮动的子元素后面,新添加一个标签,设置这个标签clear: both;
优点:通俗易懂,书写方便
缺点:添加许多无意义的标签,结构化较差
2-给父元素添加overflow:hidden;
3-使用:after伪元素清除浮动 这个方法是额外标签法的升级版,好处是不用单独加标签
哪个元素要清除浮动,就在哪个元素的class后调用clearfix
正常浏览器清除浮动
.clearfix:after {
content: "";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
4-使用before和after双伪元素清除浮动
.clearfix:before, .clearfix:after {
content: "";
两种都行
display: block;
display: table;
}
.clearfix:after {
clear: both;
}
IE6清除浮动 *表示IE7以下的版本所识别
.clearfix {
*zoom: 1;
}
*/
* {
margin: 0;
padding: 0;
}
/* .clearfix:after {
content: "";
display: block;
height: 0;
clear: both;
visibility: hidden;
} */
.clearfix:before, .clearfix:after {
content: "";
display: table;
/* display: block; */
}
.clearfix:after {
clear: both;
}
.top {
background: red;
/* overflow: hidden; */
}
.left {
width: 200px;
height: 100px;
background: yellow;
float: left;
}
.right {
width: 300px;
height: 300px;
background: blue;
float: right;
}
.clear {
display: block;
clear: both;
}
</style>
</head>
<body>
<div class="top clearfix">
<div class="left"></div>
<div class="right"></div>
<!-- <span class="clear"></span> -->
</div>
</body>
</html>
4-rem与vw转换
- vw:Viewport Width 视口宽度的百分比 1vw = 设备宽度的百分之一
- rem:根据html(顶级元素)的font-size来计算
- em:根据父元素的font-size来计算
- rem与vw的转换:
- 假设设备宽度为320px
- 则1vw=3.2px
- 假设html的font-size是100px
- 则1rem=100px
- 所以1rem = 100px = 100/3.2vw
<!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>04-rem与vw转换</title>
<style>
* {
margin: 0;
padding: 0;
}
html {
font-size: 50px;
}
body {
font-size: 25px;
}
div {
/* html的font-size是50px,所以div的高度是100px */
height: 2rem;
background: red;
}
nav {
/* nav的父元素body的font-size是25px,所以nav的高度是50px */
height: 2em;
background: yellow;
}
</style>
</head>
<body>
<div></div>
<nav></nav>
</body>
</html>
5-IE低版本兼容性问题
5-1-ie6双边距问题
- 解决办法:添加display: inline;
5-2-ie6默认高度问题
- ie6默认高度问题:ie6会把高度小于10px的元素解析成16px
- 解决办法:给高度小于10px的元素添加font-size: 0;或者overflow: hidden;
5-3-ie6支持CSS属性前添加*和_,但其他现代浏览器不支持
<!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>05-IE低版本兼容性问题</title>
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
width: 200px;
height: 200px;
background: red;
margin: 0 10px;
float: left;
display: inline;
/*
第3个
ie6支持CSS属性前添加*和_,但其他现代浏览器不支持
*/
*background: #000;
/* _background: #00f; */
}
div {
height: 10px;
background: #999;
/* font-size: 0; */
overflow: hidden;
}
</style>
</head>
<body>
<!--
第2个
ie6默认高度问题:ie6会把高度小于10px的元素解析成16px
解决办法:给高度小于10px的元素添加font-size: 0;或者overflow: hidden;
-->
<div></div>
<!--
第1个
ie6双边距问题 :列表最左端的边距是20px
解决办法:添加display: inline;
-->
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</body>
</html>
注意:如果自己电脑上没有安装IE低版本,可以去下载"IETester"这个软件,里面有IE各个版本可以满足我们的测试需求。另外,如果想要知道HTML和CSS等相关属性的浏览器支持情况,可以去canisue(https://caniuse.com/)这个网站进行查询,可以查询到几乎所有现代浏览器的支持情况。
6-插入图片问题
6-1-插入图片会把图片所在的父级元素默认向下撑大3px
解决办法:
- 1-给img元素添加display: block; ie6和现代浏览器都支持
- 2-让父级元素结束标签紧跟在img标签后面 只有ie6支持
- 3-img标签默认display: inline-block; 给img元素添加vertical-align: top;(所有属性值均可) ie6和现代浏览器都支持
6-2-ie6会给a标签中的图片添加默认边框
解决办法:
- 给img元素添加border: 0;或者border: none;
<!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>06-插入图片问题1-2</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
background: red;
}
img {
/* 插入图片问题1 */
/* display: block; */
vertical-align: middle;
/* 插入图片问题2 */
/* border: 0; */
border: none;
}
</style>
</head>
<body>
<div>
<img src="avatar.jpg" alt="">
</div>
<a href="#"><img src="avatar.jpg" alt=""></a>
</body>
</html>
6-3-如何让大小不同的图片在父级元素中水平垂直居中
解决办法:
- 首先,给img元素添加vertical-align: middle;
- 其次,在img元素后添加空span,并设置span样式如下
span {
display: inline-block;
vertical-align: middle;
width: 0;
height: 100%;
}
<!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>06-插入图片问题3</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 800px;
height: 800px;
background: red;
border: 1px solid black;
float: left;
text-align: center;
}
img {
vertical-align: middle;
}
span {
display: inline-block;
vertical-align: middle;
width: 0;
height: 100%;
}
</style>
</head>
<body>
<div>
<img src="avatar.jpg" alt=""><span></span>
</div>
<div>
<img src="baidu.jpeg" alt=""><span></span>
</div>
</body>
</html>
7-内容多左对齐,内容少居中对齐
解决办法:
- 让文本的父级元素text-align: center; 文本元素display: inline-block;text-align: left;
<!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>07-内容多左对齐,内容少居中对齐</title>
<style>
div {
text-align: center;
}
p {
display: inline-block;
text-align: left;
}
</style>
</head>
<body>
<div>
<p>内容多左对齐,内容少居中对齐</p>
<p>内容多左对齐,内容少居中对齐内容多左对齐,内容少居中对齐内容多左对齐,内容少居中对齐内容多左对齐内容少居中对齐内容多左对齐内容少居中对齐内容多左对齐内容少居中对齐内容多左对齐内容少居中对齐内容多左对齐,内容少居中对齐内容多左对齐,内容少居中对齐内容多左对齐,内容少居中对齐内容多左对齐,内容少居中对齐内容多左对齐,内容少居中对齐内容多左对齐,内容少居中对齐内容多左对齐,内容少居中对齐内容多左对齐,内容少居中对齐内容多左对齐,内容少居中对齐内容多左对齐,内容少居中对齐内容多左对齐,内容少居中对齐内容多左对齐,内容少居中对齐内容多左对齐,内容少居中对齐内容多左对齐,内容少居中对齐</p>
</div>
</body>
</html>
8-多行文本显示省略号CSS实现
解决办法:
- 使用:after伪元素
<!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>08-多行文本显示省略号CSS实现</title>
<style>
#top {
width: 100px;
background: red;
text-align: left;
}
#top:after {
content: "...";
}
</style>
</head>
<body>
<div id="top">
内容多左对齐,内容少居中对齐
</div>
</body>
</html>
9-设置透明问题
- 问题:opacity和filter设置背景透明:里面的内容也会跟着透明
- 解决办法:
- 1-用rgba设置背景透明
- 2-用定位,背景颜色是单独的一个标签,内容是另外一个标签,用定位将两个标签叠加在一起
<!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>09-设置背景和内容透明</title>
<style>
* {
margin: 0;
padding: 0;
}
.div {
width: 800px;
height: 800px;
background: red;
position: relative;
/* overflow: hidden; */
}
nav {
background: #000;
color: #ff0;
width: 300px;
height: 300px;
position: absolute;
left: 800px;
top: 0;
/* opacity: 0.1; */
filter: opacity(0.1);
}
.div:hover {
left: 0;
opacity: 0.5;
/* background: rgba(255, 0, 0, 0.5); */
}
.div1 {
width: 800px;
height: 800px;
background: black;
opacity: 0.5;
}
.div2 {
width: 800px;
height: 800px;
position: relative;
left: 0;
top: -800px;
}
</style>
</head>
<body>
<div class="div">
<img src="avatar.jpg" alt="">
<nav>我是nav<nav>
</div>
<div class="div1"></div>
<div class="div2">
<img src="avatar.jpg" alt="">
</div>
</body>
</html>
10-实现1像素边框
- 问题:移动端1像素的边框,解析时会显示成两像素
- 解决办法:
- 用缩放去实现
<!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>10-实现1像素边框</title>
<style>
div {
width: 200px;
height: 50px;
border: 1px solid #000;
}
nav {
width: 200px;
height: 50px;
background: black;
}
nav:after {
content: "";
display: block;
width: 100%;
height: 1px;
background: yellow;
/* 以下两种缩放方式都可以 */
transform: scale(1, 0.5);
/* transform: scaleY(0.5); */
}
</style>
</head>
<body>
<div></div>
<nav></nav>
</body>
</html>
11-doctype-html问题
- 如果不存在会发生什么事:
- ie8以下会触发怪异盒模型,(ie8以下不支持box-sizing)
- 怪异盒模型的实际宽高=设置的width,height(会将border、padding计算在width、height里边)
- 标准盒模型实际宽高=border+padding+width/height
- 怪异盒模型和标准盒模型之间转换的属性box-sizing: border-box; 怪异盒 ox-sizing: content-box; 标准盒
<!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>14-doctype-html问题</title>
<style>
div {
width: 100px;
height: 100px;
background: red;
border: 5px solid black;
padding: 10px;
/* box-sizing: content-box; */
box-sizing: border-box;
}
</style>
</head>
<body>
<div></div>
</body>
</html>
12-img标签的alt和title的区别
- alt和title都有利于SEO(搜索引擎优化)
- alt是当图片不存在或者路径错误的时候显示alt里的内容
- title是当鼠标放在图片上时显示title里的内容
面试问题:说一说你在写页面的时候会从哪些角度考虑网站的优化问题:(从HTNL和CSS两方面考虑) - 1-超链接最好用文本,不用Flash动画或图片热区
- 2-图片alt和title都要添加,对于一些没有意义的小图这两个属性最好也要添加,只需把它们的属性值置空就好,即alt=“” title=“”
- 3-图片整合(精灵图、雪碧图)
- 4-代码结构清晰
13-鼠标悬停图片上触发蒙层动画
<!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>16-鼠标悬停图片上触发蒙层动画</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 700px;
height: 700px;
position: relative;
/* 添加overflow: hidden;后,nav不再显示,并且蒙层滑入的时候无法显示初始位置 */
/* overflow: hidden; */
}
nav {
width: 700px;
height: 700px;
background: black;
position: absolute;
top: 0;
left: 700px;
transition: 1s;
opacity: 0;
/* filter: alpha(opacity=0); */
/* background: rgba(0, 0, 0, 0); */
/* 添加pointer-events: none;后,nav如果初始透明度不是0就可以显示,并且蒙层滑入的时候可以显示初始位置 */
/* pointer-events: none;--屏蔽鼠标事件 */
pointer-events: none;
}
div:hover nav{
left: 0;
/* background: black; */
opacity: 0.5;
/* background: rgba(0, 0, 0, 0.5); */
}
</style>
</head>
<body>
<div>
<img src="cat.jpeg" alt="">
<nav></nav>
</div>
</body>
</html>