css的一些面试题
作为一名大三快大四的学生,也快到面试的时候,总结了一些关于css的相关的面试题,希望对各位看官有点作用,同时也给自己当一下笔记。
常见的块级元素有:
-
<div>:通用的块级容器。 -
<h1>-<h6>:标题元素,从大到小表示不同级别的标题。 -
<p>:段落元素。 -
<ul>(无序列表)和<ol>(有序列表)。 -
<li>:列表项。 -
<blockquote>:块引用。 -
<form>:表单。 -
<header>:页面头部。 -
<footer>:页面底部。 -
<section>:文档节。
块级元素的特点包括:
- 独占一行,前后会有换行。
- 可以设置宽度、高度、内外边距等属性。
常见的行内元素有:
-
<span>:通用的行内容器。 -
<a>:超链接。 -
<img>:图片。 -
<strong>和<b>:强调(通常为粗体)。 -
<em>和<i>:强调(通常为斜体)。 -
<input>:输入框。
行内元素的特点包括:
- 不会独占一行,多个行内元素可以在一行显示。
- 宽度和高度通常由内容决定,不能直接设置宽度和高度。
- 上下内边距会影响布局,左右内边距有效。
文档流
文档流是网页排版的基础规则,它决定了 HTML 元素在页面上的初始排列和布局方式。
我们把网页想象成一个房间,文档流就是规定了各种元素如何在这个房间里摆放的默认方式。
对于块级元素,就像一个个独立的大箱子,比如 <div>、<p>、<h1> 等。它们具有以下特点:
每个块级元素都会独自占据一行,就像大箱子一个叠一个竖着放置,彼此不会在同一行出现。
例如:
<!DOCTYPE html>
<html>
<body>
<div>这是第一个块</div>
<div>这是第二个块</div>
</body>
</html>
在上述代码中,两个 <div> 元素会一个在上一个在下排列。
块级元素的默认宽度会自动填满父元素的宽度,高度则由其内部的内容决定。
比如:
<!DOCTYPE html>
<html>
<body>
<div style="width: 50%;">这个<div>的宽度是父元素的一半</div>
</body>
</html>
这里的 <div> 元素宽度就是父元素宽度的 50%。
行内元素则像房间里的小物件,比如 <span>、<a> 等。它们会在一行里尽量挨着排列,如果一行放不下,才会换行到下一行。
例如:
<!DOCTYPE html>
<html>
<body>
<p>这是一段文字,里面有 <span>这个是行内元素</span> 接着其他文字。</p>
</body>
</html>
其中的 <span> 元素会在这一行文字里紧跟着排列。
还有一个重要的概念是外边距合并。当两个相邻的块级元素存在外边距时,它们的外边距会发生合并。
比如:
<!DOCTYPE html>
<html>
<body>
<div style="margin-bottom: 20px;">上面的块</div>
<div style="margin-top: 30px;">下面的块</div>
</body>
</html>
在这种情况下,两个块之间的实际间距不是 50 像素,而是 30 像素,因为取了两个外边距中的较大值。
当元素设置为浮动时,就好像这个大箱子飘起来了,不再占据原来在文档流中的位置,后面的元素会挤过来填充这个空位。
例如:
<!DOCTYPE html>
<html>
<body>
<div style="float: left;">这是浮动的<div></div>
<div>这个<div>会跑到浮动元素的旁边</div>
</body>
</html>
后面的 <div> 元素会跑到浮动元素的旁边。
总之,理解文档流的规则对于实现理想的网页布局非常重要,它是网页布局的基础,我们可以在此基础上通过浮动、定位等方式实现更复杂和灵活的布局效果。
重排
回流,也称为重排,是指浏览器在计算和更新页面元素的几何属性(如位置、大小、形状等)和布局信息的过程。
当页面中的某些操作导致元素的布局发生变化时,浏览器就需要重新计算所有受影响元素的位置和大小,以确定它们在页面中的正确显示方式。
例如,以下这些操作通常会导致回流的发生:
-
更改元素的宽度、高度、内外边距、边框等尺寸相关的样式。
-
更改元素的位置,如设置
position: absolute并修改其top、left等属性。 -
内容的添加、删除或修改,比如动态地向一个元素中添加大量文本。
-
窗口大小的改变。
回流是一个相对耗费性能的操作,因为它可能涉及到对整个页面或部分页面的重新布局计算。频繁的回流会导致页面性能下降,出现卡顿或加载缓慢的情况。
举个例子:
<!DOCTYPE html>
<html>
<body>
<div id="myDiv">这是一个 div 元素</div>
<script>
var div = document.getElementById('myDiv');
div.style.width = '500px';
</script>
</body>
</html>
在上述代码中,通过 JavaScript 动态地将 div 元素的宽度修改为 500px ,这就会导致浏览器进行回流操作,重新计算该元素以及相关元素的布局。
重绘
重绘(Repaint)是指在不改变页面布局(元素的位置和几何形状)的情况下,只重新绘制元素的外观,比如颜色、背景、边框样式等的改变。
例如,如果只是修改了一个元素的背景颜色,或者给一个文本元素更改了字体颜色,这就会触发重绘。重绘的性能开销比重流小,但如果频繁发生也可能影响页面性能。
以下是一个简单的重绘示例代码:
<!DOCTYPE html>
<html>
<body>
<div id="myDiv">这是一个 div 元素</div>
<script>
var div = document.getElementById('myDiv');
div.style.backgroundColor ='red';
</script>
</body>
</html>
在上述代码中,修改 div 元素的背景颜色会触发重绘。
标准盒模型(W3C 盒模型)
在标准盒模型中,一个元素的总宽度(width)和总高度(height)的计算方式是:
总宽度 = width + padding(左右) + border(左右) + margin(左右)
总高度 = height + padding(上下) + border(上下) + margin(上下)
也就是说,width 和 height 只包含内容的宽度和高度,不包含内边距(padding)、边框(border)和外边距(margin)。
例如:
div {
width: 200px;
height: 100px;
padding: 20px;
border: 10px solid black;
margin: 10px;
}
在标准盒模型中,这个 div 元素的总宽度为:200 + 20×2 + 10×2 + 10×2 = 280px;总高度为:100 + 20×2 + 10×2 + 10×2 = 180px。
IE 盒模型(怪异盒模型)
在 IE 盒模型中,元素的总宽度和总高度的计算方式是:
总宽度 = width + margin(左右)
总高度 = height + margin(上下)
这里的 width 和 height 包含了内容、内边距和边框的宽度。
例如,对于上述同样的 div 元素设置:
div {
width: 200px;
height: 100px;
padding: 20px;
border: 10px solid black;
margin: 10px;
}
在 IE 盒模型中,这个 div 元素的总宽度为:200 + 10×2 + 20×2 = 260px;总高度为:100 + 10×2 + 20×2 = 160px。
在 CSS 中,可以通过 box-sizing 属性来切换使用标准盒模型还是 IE 盒模型。box-sizing: content-box 表示使用标准盒模型,box-sizing: border-box 表示使用 IE 盒模型。
隐藏的方式:
-
display: none:-
元素完全从文档流中移除,就好像它根本不存在一样。
-
不占据任何空间,不会影响页面布局。
-
无法触发鼠标交互事件,因为元素实际上已被隐藏且不存在于页面的渲染中。
-
例如:
-
.hidden-element {
display: none;
}
-
width: 0; height: 0;:-
元素从文档流中消失,不占据空间。
-
无法绑定事件,因为在视觉和布局上它已被视为不存在。
-
例如:
-
.zero-sized-element {
width: 0;
height: 0;
}
-
opacity: 0:-
元素仍然在文档流中,占据着原来的空间。
-
只是透明度设置为 0,使其看起来不可见,但实际上它仍在那里,可以与其他元素产生交互。
-
可以绑定事件,例如鼠标点击事件等。
-
例如:
-
.transparent-element {
opacity: 0;
}
-
visibility: hidden:-
元素在文档流中,但不可见。
-
无法绑定事件。
-
虽然不可见,但它所占据的空间仍然保留,其他元素不会挤占其位置。
-
例如:
-
.invisible-element {
visibility: hidden;
}
-
clip-path:-
元素在文档流中,但通过裁剪路径将其显示部分裁剪掉。
-
无法绑定事件。
-
元素所占空间不变。
-
例如:
-
.clipped-element {
clip-path: circle(0);
}
在实际应用中,根据具体的需求选择合适的隐藏方式。如果希望完全移除元素对布局的影响,可使用 display: none;如果需要保留空间且能进行交互,opacity: 0 可能更合适;如果既不想占据空间又不希望有交互,可选择 width: 0; height: 0; 等方式。
以下是对这三种清除浮动方式的详细解释:
-
在浮动元素内部最后面添加一个空的块级元素,并设置
clear: both:这种方式通过在浮动元素内部添加一个新的块级元素来清除浮动的影响。
clear: both属性表示该元素的两侧不允许有浮动元素,从而强制该元素下方的内容不会受到前面浮动元素的影响。示例代码:
<div class="float-container">
<div class="float-left">浮动元素 1</div>
<div class="float-left">浮动元素 2</div>
<div style="clear: both;"></div>
</div>
-
在父容器的尾元素(如
ul)使用::after伪元素,并设置clear: both:这种方式利用了 CSS 的伪元素来在父容器的末尾添加一个用于清除浮动的元素。通过这种方式,不需要在 HTML 结构中额外添加新的元素。
示例代码:
.parent-container ul::after {
content: "";
display: block;
clear: both;
}
-
将父容器设置为 BFC(块级格式化上下文,Block Formatting Context),例如通过设置
overflow: hidden:当父元素成为 BFC 时,它内部的浮动元素不会影响到外部元素的布局,从而达到清除浮动的效果。
示例代码:
.parent-container {
overflow: hidden;
}
这三种方式都可以有效地清除浮动,但在实际使用中,根据具体的场景和代码结构选择最合适的方法。
谈谈你对 BFC 的理解
block formating context 块级格式化上下文 BFC 是 CSS 中一种叫做块级格式化上下文的容器,他拥有一些特殊的渲染规则
规则
1.BFC 容器里的子元素依然是按照正常容器的渲染规则 有块级 行内 行内块
2.BFC 容器会将内部浮动的子容器的高度计算在内 能够清除浮动带来的元素高度丢失的原因
作用:本质目的不是为了清除浮动,而是为了解决父容器和子容器垂直方向上 margin 重叠的问题,但是其内部元素的垂直 margin 重叠无法解决
将容器变为 BFC 的手段: overflow:hidden || auto || overlay || scroll float : left,right 脱离文档流 display:flex grid inline-xxx || table-xxx position : absolute || fixed
应用场景:
1.清除浮动
2.防止垂直方向上的 margin 重叠
代码实例
HTML 代码:
<!DOCTYPE html>
<html>
<head>
<style>
.parent {
border: 2px solid red;
overflow: hidden; /* 创建 BFC */
}
.float-child {
float: left;
width: 100px;
height: 100px;
background-color: blue;
}
.normal-child {
height: 50px;
background-color: green;
}
</style>
</head>
<body>
<div class="parent">
<div class="float-child">浮动元素</div>
<div class="normal-child">普通元素</div>
</div>
<p>这是父元素后面的文本。</p>
</body>
</html>
在上述代码中,通过给 .parent 元素设置 overflow: hidden 创建了 BFC。这样,父元素能够正确包含浮动的子元素,不会出现高度丢失的情况。
弹性布局(Flex Layout)
弹性布局是 CSS 中一种非常强大和灵活的布局方式,用于更方便地控制元素在容器中的排列和对齐。
一、基本概念
-
弹性容器(Flex Container) :应用
display: flex或display: inline-flex的父元素。 -
弹性项目(Flex Items) :弹性容器内的子元素。
二、容器属性
-
flex-direction:决定项目的排列方向,可取值有:row(默认值,从左到右水平排列)row-reverse(从右到左水平排列)column(从上到下垂直排列)column-reverse(从下到上垂直排列)
-
justify-content:定义项目在主轴(主要的排列方向)上的对齐方式,可取值有:flex-start(左对齐或顶部对齐,取决于方向)flex-end(右对齐或底部对齐)center(居中对齐)space-between(两端对齐,项目之间间隔相等)space-around(每个项目两侧的间隔相等)
-
align-items:定义项目在交叉轴(与主轴垂直的方向)上的对齐方式,可取值有:flex-start(顶部对齐或左对齐)flex-end(底部对齐或右对齐)center(居中对齐)stretch(拉伸填满容器,默认值,如果项目未设置高度)baseline(项目根据其文本基线对齐)
-
flex-wrap:决定项目是否换行,可取值有:nowrap(默认值,不换行)wrap(换行)wrap-reverse(反向换行)
-
align-content:当项目换行时,定义多行在交叉轴上的对齐方式,可取值类似于justify-content。
三、项目属性
-
order:定义项目的排列顺序,值越小越靠前,默认值为 0 。 -
flex-grow:定义项目的放大比例,默认值为 0 ,表示不放大。 -
flex-shrink:定义项目的缩小比例,默认值为 1 ,表示空间不足时会缩小。 -
flex-basis:定义项目在分配多余空间之前的默认大小。 -
flex:是flex-grow、flex-shrink和flex-basis的简写形式。
示例代码
<!DOCTYPE html>
<html>
<head>
<style>
.flex-container {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
height: 300px;
background-color: lightgray;
}
.flex-item {
width: 100px;
height: 100px;
margin: 10px;
background-color: lightblue;
}
</style>
</head>
<body>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
</div>
</body>
</html>
在上述示例中,创建了一个弹性容器,项目水平排列,两端对齐,并且当一行放不下时会换行。每个项目具有固定的宽度和高度,并带有一定的外边距。
弹性布局极大地提高了页面布局的灵活性和可维护性,能够适应不同的屏幕尺寸和设计需求。
网格布局(Grid Layout)
网格布局是 CSS 中一种强大的二维布局方式,能够实现复杂而精确的页面布局。
一、基本概念
-
网格容器(Grid Container) :应用
display: grid或display: inline-grid的父元素。 -
网格单元(Grid Cell) :网格中的最小单位。
-
网格线(Grid Line) :划分网格的线条,包括水平和垂直的线。
-
网格轨道(Grid Track) :两条相邻网格线之间的空间,分为行轨道(Row Track)和列轨道(Column Track)。
二、容器属性
-
grid-template-columns:定义列轨道的尺寸,可以是固定长度、百分比、fr(分数单位)等,多个值用空格分隔。- 例如,
grid-template-columns: 1fr 2fr 1fr;表示三列,宽度比例为 1:2:1 。
- 例如,
-
grid-template-rows:定义行轨道的尺寸,用法与grid-template-columns类似。 -
grid-gap(或gap):用于设置网格单元格之间的间距,包括行间距和列间距,可以分别指定row-gap和column-gap。 -
justify-items:定义网格项目在单元格内沿水平方向的对齐方式,可取值有start、end、center、stretch。 -
align-items:定义网格项目在单元格内沿垂直方向的对齐方式,取值与justify-items类似。 -
justify-content:定义网格整体在容器内沿水平方向的对齐方式,可取值有start、end、center、space-between、space-around、space-evenly。 -
align-content:定义网格整体在容器内沿垂直方向的对齐方式,取值与justify-content类似。
三、项目属性
-
grid-column:指定项目跨越的列范围,例如grid-column: 1 / 3;表示从第 1 列开始到第 3 列结束。 -
grid-row:指定项目跨越的行范围,用法与grid-column类似。 -
justify-self:定义单个项目在单元格内沿水平方向的对齐方式,覆盖justify-items的设置。 -
align-self:定义单个项目在单元格内沿垂直方向的对齐方式,覆盖align-items的设置。
示例代码
<!DOCTYPE html>
<html>
<head>
<style>
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 100px 200px;
grid-gap: 10px;
justify-content: center;
align-content: center;
}
.item1 {
background-color: red;
grid-column: 1 / 3;
grid-row: 1 / 2;
}
.item2 {
background-color: green;
grid-column: 3 / 4;
grid-row: 1 / 2;
}
.item3 {
background-color: blue;
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.item4 {
background-color: yellow;
grid-column: 2 / 4;
grid-row: 2 / 3;
}
</style>
</head>
<body>
<div class="grid-container">
<div class="item1">Item 1</div>
<div class="item2">Item 2</div>
<div class="item3">Item 3</div>
<div class="item4">Item 4</div>
</div>
</body>
</html>
在上述示例中,创建了一个网格容器,定义了列和行的轨道尺寸,并通过项目属性将各个元素放置在不同的网格位置上。
相对定位(relative) :
是相对于元素在文档流中的原始位置进行移动。
- 元素仍然占据在文档流中的原始位置,其周围的元素不会受到影响。
- 通过设置
top、bottom、left、right属性,可以相对于其原始位置进行偏移。 - 偏移量不会改变元素原本所占的空间。
.relative-element {
position: relative;
top: 20px;
left: 30px;
}
绝对定位(absolute) :
绝对定位(absolute) :是相对于其最近的已定位的祖先元素进行移动,如果没有已定位的祖先元素(即祖先元素中没有设置 position: relative、position: absolute 或 position: fixed),则相对于文档的根元素(<html>)进行定位。
-
元素会从文档流中移除,不再占据原来的空间,其位置相对于最近的已定位祖先元素(如果没有已定位的祖先元素,则相对于文档的 body 元素)。
-
同样可以使用
top、bottom、left、right属性来精确指定位置。
例如:
.absolute-element {
position: absolute;
top: 50px;
right: 100px;
}
以下是一个包含相对定位和绝对定位元素的示例代码:
<!DOCTYPE html>
<html>
<head>
<style>
.parent {
position: relative;
width: 500px;
height: 500px;
background-color: lightgray;
}
.relative-child {
position: relative;
top: 50px;
left: 50px;
width: 200px;
height: 200px;
background-color: lightblue;
}
.absolute-child {
position: absolute;
bottom: 50px;
right: 50px;
width: 100px;
height: 100px;
background-color: lightcoral;
}
</style>
</head>
<body>
<div class="parent">
<div class="relative-child">相对定位的子元素</div>
<div class="absolute-child">绝对定位的子元素</div>
</div>
</body>
</html>
在上述示例中,.parent 是相对定位的容器,.relative-child 相对于其在容器中的原始位置进行了偏移,而 .absolute-child 则相对于 .parent 容器进行了定位