目录
一、对BFC规范(块级格式化上下文:block formatting context)的理解?
三、 如何居中div?如何居中一个浮动元素?如何让绝对定位的div居中?如何居中一个img(position定位)
a标签里嵌套img时,有些浏览器(例如IE浏览器)下会出现有颜色的边框
一、对BFC规范(块级格式化上下文:block formatting context)的理解?
W3C CSS 2.1 规范中的一个概念,它是一个独立容器,决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。)
一个页面是由很多个 Box 组成的,元素的类型和 display 属性,决定了这个 Box 的类型。
不同类型的 Box,会参与不同的 Formatting Context(决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染,也就是说BFC内部的元素和外部的元素不会互相影响。
BFC 规定了内部的 Block Box 如何布局。
定位方案:
内部的 Box 会在垂直方向上一个接一个放置。
Box 垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠。
每个元素的 margin box 的左边,与包含块 border box 的左边相接触。
BFC 的区域不会与 float box 重叠。
BFC 是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。
计算 BFC 的高度时,浮动元素也会参与计算。
满足下列条件之一就可触发 BFC根元素,即 html
float 的值不为none(默认)
overflow 的值不为 visible(默认)
display 的值为 inline-block、table-cell、table-caption
position 的值为 absolute 或 fixed
二、css新增伪类有哪些?
- :first-of-type选择属于其父元素的首个元素的每个元素
- :last-of-type选择属于其父元素的最后元素的每个元素
- :only-of-type选择属于其父元素唯一的元素的每个元素
- :only-child选择属于其父元素的唯一子元素的每个元素
- :nth-child(2)选择属于其父元素的第二个子元素的每个元素
- :disabled控制表单控件的禁用状态
- :checked单选框或复选框被选中
- :before在元素之前添加内容,也可以用来清除浮动
- :after在元素之后添加内容
三、 如何居中div?如何居中一个浮动元素?如何让绝对定位的div居中?如何居中一个img(position定位)
方法一:
父元素和子元素同时左浮动,然后父元素相对左移动50%,再然后子元素相对右移动50%,或者子元素相对左移动-50%
<div class="box">
<p>我是浮动的</p>
<p>我也是居中的</p>
</div>
<style>
.box{
float:left;
position:relative;
left:50%;
}
p{
float:left;
position:relative;
right:50%;
}
</style>
方法二:
父元素和子元素同时左浮动,然后父元素相对左移动50%,再然后子元素相对左移动-50%
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>页面浮动元素的水平居中</title>
<style type="text/css">
ul li {
list-style: none;
}
a {
text-decoration: none;
}
.clearfix:after {
content: "";
height: 0;
visibility: hidden;
display: block;
clear: both;
}
.clearfix {
zoom: 1;
}
.wrap {
margin: 20px auto;
padding: 10px 0;
background: orange;
overflow: hidden;
position: relative;
}
.inwrap {
float: left;
position: relative;
left: 50%;
}
.page {
float: left;
position: relative;
left: -50%;
}
.page li {
float: left;
margin: 0 5px;
}
.page li a {
display: block;
padding: 2px 9px;
background: white;
border: 1px solid red;
float: left;
}
</style>
</head>
<body>
<div class="wrap clearfix">
<div class="inwrap">
<ul class="page">
<li> <a href="#">上一页</a> </li>
<li> <a href="#">1</a> </li>
<li> <a href="#">2</a> </li>
<li> <a href="#">3</a> </li>
<li> <a href="#">4</a> </li>
<li> <a href="#">2</a> </li>
<li> <a href="#">3</a> </li>
<li> <a href="#">2</a> </li>
<li> <a href="#">3</a> </li>
<li> <a href="#">4</a> </li>
<li> <a href="#">5</a> </li>
<li> <a href="#">6</a> </li>
<li> <a href="#">下一页</a> </li>
</ul>
</div>
</div>
</body>
</html>
方法三:
可以多套一层的方式设置left:-50%
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>页面元素的水平居中</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
list-style: none;
font-size: 14px;
}
.clearfix:after {
content: "";
height: 0;
visibility: hidden;
display: block;
clear: both;
}
.clearfix {
zoom: 1;
}
a {
text-decoration: none;
}
h1 {
text-align: center;
padding: 10px;
font-size: 20px;
margin: 30px 0;
}
.wrap {
margin: 20px auto;
padding: 10px 0;
background: orange;
overflow: hidden;
position: relative;
}
.inwrap {
float: left;
position: relative;
left: 50%;
}
.page {
float: left;
position: relative;
left: -50%;
}
.page li {
float: left;
margin: 0 5px;
}
.page li a {
display: block;
padding: 2px 9px;
background: white;
border: 1px solid red;
float: left;
}
</style>
</head>
<body>
<h1>页面元素的水平居中</h1>
<h2>浮动方式:</h2>
<div class="wrap clearfix">
<div class="inwrap">
<ul class="page">
<li> <a href="#">上一页</a> </li>
<li> <a href="#">1</a> </li>
<li> <a href="#">2</a> </li>
<li> <a href="#">3</a> </li>
<li> <a href="#">4</a> </li>
<li> <a href="#">2</a> </li>
<li> <a href="#">3</a> </li>
<li> <a href="#">2</a> </li>
<li> <a href="#">3</a> </li>
<li> <a href="#">4</a> </li>
<li> <a href="#">5</a> </li>
<li> <a href="#">6</a> </li>
<li> <a href="#">下一页</a> </li>
</ul>
</div>
</div>
</body>
</html>
四、移动端css面试题
4.1居中
利用css库实现
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 在这里用link标签引入中文布局 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/chinese-layout">
<!-- 在这里用link标签引入中文渐变色 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/chinese-gradient">
<style>
/* 清除默认样式 */
* {
padding: 0;
margin: 0;
}
/* 令html和body全屏显示 */
html,
body {
height: 100%;
}
body {
/* 先在父元素上设置grid布局 */
display: grid;
grid: var(--居中);
/* 给个好看的渐变色 */
background: var(--霾灰);
}
.center {
/* 指定子元素在中心位置 */
grid-area: 中;
/* 给子元素设置宽高,不然宽高为0导致什么也看不见 */
width: 150px;
height: 150px;
/* 给一个好看的背景色 */
background: var(--胭脂粉);
}
</style>
</head>
<body>
<div class="center"></div>
</body>
</html>
绝对定位实现
- 如果不给定宽高,盒子将会和父元素一样大,因为绝对定位上下左右都是 0,意为紧贴着父元素的边。
- 给了固定宽高,但没写 margin 的话盒子会固定在左上角,因为 top 和 left 的优先级更高。
- 给了 margin: auto; 的话,浏览器会自动填充边距,令其居中。
- 此种实现方式优点是兼容性很好,几乎没用到任何 CSS 的新特性,全部都是经典属性。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 清除默认样式 */
* {
padding: 0;
margin: 0;
}
/* 令html和body全屏显示, 并有一个灰色背景 */
html,
body {
height: 100%;
background: gray;
}
/* 先在父元素上设置相对定位 */
body {
position: relative
}
.center {
/* 绝对定位 */
position: absolute;
/* 上下左右全部为0 */
top: 0;
right: 0;
bottom: 0;
left: 0;
/* 给定宽高 */
width: 70%;
height: 25%;
/* 令外边距自动填充 */
margin: auto;
/* 白色背景 */
background: white;
}
</style>
</head>
<body>
<div class="center"></div>
</body>
</html>
绝对定位+负边距
注意,"绝对定位+负边距"这种方法不适合那种宽百分之多少、高百分之多少这种相对单位,取而代之的是具体的数值。
因为边距的百分比和宽高的百分比相对的不是同一参考物,它是相对于父元素的宽来计算的,这点要注意。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 清除默认样式 */
* {
padding: 0;
margin: 0;
}
/* 令html和body全屏显示, 并有一个灰色背景 */
html,
body {
height: 100%;
background: gray;
}
/* 先在父元素上设置相对定位 */
body {
position: relative
}
.center {
/* 绝对定位 */
position: absolute;
/* 上方和左方为50% */
top: 50%;
left: 50%;
/* 给定宽高 */
width: 300px;
height: 200px;
/* 上外边距为负的给定高度的一半 */
margin-top: -100px;
/* 左外边距为负的给定宽度的一半 */
margin-left: -150px;
/* 白色背景 */
background: white;
}
</style>
</head>
<body>
<div class="center"></div>
</body>
</html>
绝对定位+平移
- margin 的百分比是相对于父元素的宽;
- 而
translate
函数的百分比是相对于自身;- 不仅适用于未知宽高,也同样适用于固定宽高的居中布局。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 清除默认样式 */
* {
padding: 0;
margin: 0;
}
/* 令html和body全屏显示, 并有一个灰色背景 */
html,
body {
height: 100%;
background: gray;
}
/* 先在父元素上设置相对定位 */
body {
position: relative
}
.center {
/* 绝对定位 */
position: absolute;
/* 上方和左方为50% */
top: 50%;
left: 50%;
/* 不用给宽高,但是可以给个内边距防止内容与盒子过于贴合 */
padding: 10px;
/* 这个50%是相对于自身宽高而言的 */
transform: translate(-50%, -50%);
/* 白色背景 */
background: white;
}
</style>
</head>
<body>
<div class="center">
用内容撑开盒子
</div>
</body>
</html>
网格Grid实现
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 清除默认样式 */
* {
padding: 0;
margin: 0;
}
/* 令html和body全屏显示, 并有一个灰色背景 */
html,
body {
height: 100%;
background: gray;
}
/* 中央盒子的直接父元素 */
body {
/* 令其变成网格布局 */
display: grid;
/* 令其子元素居中 */
place-items: center;
}
.center {
/* 不用给宽高,但是可以给个内边距防止内容与盒子过于贴合 */
padding: 10px;
/* 白色背景 */
background: white;
}
</style>
</head>
<body>
<div class="center">用内容撑开盒子</div>
</body>
</html>
Flex弹性盒子
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 清除默认样式 */
* {
padding: 0;
margin: 0;
}
/* 令html和body全屏显示, 并有一个灰色背景 */
html,
body {
height: 100%;
background: gray;
}
/* 找到中央盒子的直接父元素 */
body {
/* 令其变成弹性布局 */
display: flex;
}
.center {
/* 自动外边距 */
margin: auto;
/* 白色背景 */
background: white;
/* 不用给宽高,但是可以给个内边距防止内容与盒子过于贴合 */
padding: 10px;
}
</style>
</head>
<body>
<div class="center">用内容撑开盒子</div>
</body>
</html>
表格布局
此布局的关键点在于:
父元素上 3 个样式设置:
display: table-cell;
text-align: center;
vertical-align: center;
子元素上设置:
display: inline-block;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 清除默认样式 */
* {
padding: 0;
margin: 0;
}
body {
/* 令body全屏显示 */
width: 100vw;
height: 100vh;
/* 显示为表格的格子 */
display: table-cell;
/* 水平居中 */
text-align: center;
/* 垂直居中 */
vertical-align: middle;
/* 灰色背景 */
background: gray;
}
.center {
/* 显示为行内块元素 */
display: inline-block;
/* 不用给宽高,但是可以给个内边距防止内容与盒子过于贴合 */
padding: 10px;
/* 白色背景 */
background: white;
}
</style>
</head>
<body>
<div class="center">用内容撑开盒子</div>
</body>
</html>
五、常见浏览器兼容性问题
5.1什么是浏览器兼容
不同的浏览器对同一段代码解析不同造成浏览器显示效果不同,我们把这样的问题叫做浏览器兼容性问题
5.2问题及解决方案
双倍浮动的bug
块元素float后,又设置了横向的margin值,在IE6下显示的margin值比设置的值要大,并且是二倍关系
解决方案:给float的块元素添加display:inline
表单元素行高不一致
解决方案:
- 给表单元素添加一致的vertical-align属性值
- 给表单元素添加一致的float属性值
在IE6中,不能识别较小高度的容器(一般为20px)
解决方案:元素{height:1px;overflow:hidden;}
a标签里嵌套img时,有些浏览器(例如IE浏览器)下会出现有颜色的边框
解决方案:img{border:0}或img{border:none}
在IE6中不能识别min-height属性
解决方案:min-height:100px;_height:100px;
图片默认有空隙
解决方案:
- img{display:block;}
- img{float:left;}
- img{vertical-align:bottom;}
IE8及一下浏览器不能识别opacity属性
解决方案:
元素{
opacity:0.5;
filter:alpha(opacity=50);
}
鼠标指针bug
cursor:hand;只有IE8及以下浏览器识别,其它浏览器不识别
解决方案:设置为cursor:pointer;所有浏览器都识别,将鼠标指针设置为手的形状
百分比bug
在IE6下,子元素百分之五十加百分之五十大于父元素设置的百分之百
解决方案:给右边左浮动的元素添加clear:right;