Fork me on GitHub

m-CSS

CSS 的一些例子和面试题
参考 1

盒子水平垂直居中

  • position

    1. margin 盒子要固定宽高
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    .outer {
    position: relative;
    }

    .box {
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -50px;
    margin-top: -25px;
    }
    1. margin:auto 不用固定宽度,但是要有宽高
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    .outer {
    position: relative;
    }
    .box {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    margin: auto
    }
    1. transform:translate(-50%,-50%)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    .outer {
    position: relative;
    }

    .box {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    }
  • display:flex
    兼容性存在问题,但是可以使用浏览器头

    1
    2
    3
    4
    5
    .outer {
    display: flex;
    justify-content: center;
    align-items: center;
    }
  • JS 性能不好

  • display:table-cell

    1
    2
    3
    4
    5
    6
    .outer{
    display: table-cell;
    vertical-align: middle;
    text-align: center;
    //=>宽高不能是百分比
    }

CSS 盒模型

组成:margin+border+padding+content

  • 标准盒模型 box-sizing:content-box
    标准盒模型
  • IE 盒模型 box-sizing:border-box
    IE 盒模型

区别

标准模型的宽高=content 的宽高,内容的宽高
IE 模型的宽高=border 的宽高+padding 的宽高+content 的宽高,就是盒子的大小

回答: 标准盒子模型,即 box-sizing:content-box,默认的盒子模型,这种情况下设置的宽高不是盒子的宽高而是 content 的,盒子的宽高是 content+padding+border,这样在项目里面如果要设置了宽高,后面要增加 padding 或 border,就要调整三个值,改动麻烦。
后面 CSS3 提供了 IE 盒模型,能够直接控制盒子大小,调整之后,会自动计算 content 宽高,以及我平时用的 antd 大部分样式也用到了 IE 盒模型。

如何设置获取盒模型的宽高

  • dom.style.width/height
    只能获取内联样式的宽高
    返回字符串(含有 px)
  • dom.currentStyle.width/height
    仅支持 IE 浏览器
  • window.getComputedStyle(dom).width/height
    兼容性比上一个好
    返回字符串(含有 px)
  • dom.getBoundingClientRect().width/height
    返回数值

边界重叠

边界重叠是指两个或多个盒子(相邻或嵌套)的相邻边界(其间没有任何非空内容、补白、边框)重合在一起而形成一个单边界

  • 父子元素的边界重叠
    父元素截取子元素的外边距,高度坍塌。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <section>
    <style>
    .parent {
    background-color: chocolate
    }

    .parent .child {
    width: 100px;
    height: 100px;
    margin-top: 10px;
    background-color: aqua
    }
    </style>
    <div class='parent'>
    <div class='child'></div>
    </div>
    </section>

    边界重叠
    父元素的高度并没有包含子元素的外边距。
    如果块元素的margin-top与它的第一个子元素的margin-top之间没有border,padding,inline,content,clearance等来分隔,那么父元素的margin-top和第一个子元素的margin-top重叠,取较大值。
    margin-bottom的道理一样

  • 兄弟元素的边界重叠

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <section class='box'>
    <style>
    .box {
    background-color: antiquewhite
    }

    .box>div {
    height: 50px;
    margin: 20px auto 30px;
    background-color: aqua
    }
    </style>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    </section>

    边界重叠

    外边距并不是 30+20,而是取较大的值

  • 空元素边界重叠
    一个空元素,它有外边距,但是没有边框或填充。在这种情况下,上外边距与下外边距就碰到了一起,它们会发生合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 <section >
<style>
hr {
margin: 0
}

div {
margin-top: 20px;
margin-bottom:100px;
background-color: tomato
}

p {
margin: 0;
height: 20px;
background-color: tomato
}
</style>
<hr />
<div></div>
<p>p标签高20px</p>
<hr />
<div>111</div>
<p>p标签高20px</p>
</section>

无内容
无内容
实际高度只有 100px,margin-top 的 20 被 bottom 覆盖,通过元素检查高 20px 的 p 标签被遮挡可以看到。
有内容
有内容
实际占用位置是较大的那个外边距

CSS 选择符有哪些

  • id选择器 - #id
  • 类选择器 - .class
  • 标签选择器 - div
  • 后代选择器 - h1 p
  • 相邻后代选择器(子)选择器 - ul>li
  • 兄弟选择器 - li~a
  • 相邻兄弟选择器 - li+a
  • 属性选择器 - a[rel='externam']
  • 伪类选择器 - a:hover,li:nth-child
  • 伪元素选择器 - ::afther ::before
  • 通配符选择器 - *

新增伪类

  • ele:nth-child(n)
    父元素下标签名为 ele 的第 n 个子元素,n 可以是数值也可以接收函数
  • ele:nth-last-child(n)
    从后开始第 n 个元素
  • ele:last-child(n)
    最后一个子元素
  • ele:only-child
    父元素下的唯一的标签为 ele 的子元素
  • ele:nth-of-type(n)
    父元素下的第 n 个类型为 ele 的子元素
  • ele:first-of-type
    父元素下的第一个类型为 ele 的子元素
  • ele:last-of-type
    父元素下的最后一个类型为 ele 的子元素
  • ele:only-of-type
    父元素下的唯一的一个类型为 ele 的子元素
  • ele:empty
    不包含子元素和内容的 elem 类型的元素
  • ele:target
    当前活动的 elem 元素
  • :enabled
    控制表单控件的禁用状态
  • :disabled
    控制表单控件的禁用状态
  • :checked
    单选框或复选框被选中

BFC(解决边距重叠)

基本概念

Block Formatting Context
块级格式化上下文
(IFC,内联元素格式化上下文)

原理

  • BFC 中的元素会在垂直方向发生边距重叠
  • BFC 是一个独立的容器,容器里面的子元素不会影响到外面的元素,反之亦然
  • 计算 BFC 的高度时,考虑所有子元素,包括浮动元素
  • 浮动元素的盒不会叠加到 BFC

创建 BFC

  • 根元素,(html)
  • 浮动元素, float 的值不是 none
  • 绝对定位,position 的值 absolute、fixed
  • 行内块元素,display:inline-block
  • 表格单元格,display:table-cell
  • 表格标题,display:table-caption
  • 弹性布局,display 为 flex、inline-flex 元素的直接子元素
  • 网格元素,display 为 grid、inline-grid 元素的直接子元素
  • overflow 的值不为 visible,如:hidden/auto

实例

  • 解决垂直方向边距重叠
    盒子垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻盒子的 margin 会发生重叠。创建不属于同一个 BFC,就不会发生 margin 重叠了。嵌套的关系也不会发生重叠。
    父元素创建BFC(overflow:hidden)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <section>
    <style>
    .parent {
    background-color: chocolate;
    overflow: hidden;
    }

    .parent .child {
    width: 100px;
    height: 100px;
    margin-top: 10px;
    background-color: aqua
    }
    </style>
    <div class='parent'>
    <div class='child'></div>
    </div>
    </section>

边界重叠

  • 浮动布局,行高不固定,侵占左侧
    左侧元素创建BFCBFC 不会与 float 元素发生重叠。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <section id="layout1">
    <style>
    #layout1 {
    background: red;
    }

    #layout1 .left {
    float: left;
    width: 100px;
    height: 100px;
    background: pink;
    }

    #layout1 .right {
    height: 110px;
    background: #ccc;
    overflow: auto
    }
    </style>
    <!--左边宽度固定,右边自适应-->
    <div class="left">左</div>
    <div class="right">右</div>
    </section>
  • 清除浮动
    为父元素创建BFC,浮动子元素的高度也会参与到父元素的高度计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<section>
<style>
.clear {
background-color: aqua;
overflow: hidden;
}

.clear>div {
width: 100px;
height: 100px;
float: left;
background-color: antiquewhite
}
</style>
<div class='clear'>
<div>
清除浮动
</div>
</div>
</section>

IFC 是什么

行级格式化上下文

  1. 行级上下文内部的盒子会在水平方向上,一个接一个的放置
  2. 当一行不够的时候会自动切换到下一行
  3. 行级上下文的高度由内部最高的内联盒子高度决定

使用 css,让一个 div 消失在视野中

  1. display:none
    不占页面空间,元素消失。会引起浏览器的重排和重绘。无法点击
  2. visible:hidden
    占页面空间。所以只引起重绘不会引起重排。无法点击
    适用于元素隐藏后不改变页面布局。
    transition 无效。(会延迟 n 秒后 hidden,但不会渐变)
  3. opacity:0
    元素完全透明,可以点击。
    会被子元素继承,且子元素无法反隐藏。
  4. position:absolute;top:-999em,position:relative;top:-999em
    不占页面空间,利用元素位置,将元素移出视野,会引起浏览器的重排和重绘,不可点击。
  5. position: absolute; visibility: hidden;
    不占据空间,无法点击
  6. overflow:hidden;width:0;height:0;box-sizing:border-box;
    点击事件可以触发
  7. transform:translateX(-999px),transform:translateY(-999px),transform:translate(-999px,-999px)
    占用页面空间,可以点击
  8. transform: scale(0)
    不占据空间,无法点击
  9. z-index:-1
    只有元素脱离文档流时,才有效果。即拥有 relative, absolute, fixed 属性的 position 元素。
    商业转载请联系作者获得授权,非商业转载请注明出处。
    原文: https://www.w3cplus.com/css/how-z-index-works.html © w3cplus.com
    本质是改变当前 dom 的层叠上下文,把元素隐藏在其他元素之下。
    部分重排
    被其他元素遮挡部分,无法响应事件。
  10. margin-top: -999px;
    父元素

z-index 的工作原理,适用范围

  • 堆叠顺序
    HTML 文档的元素存在于三维中,z-index控制元素在z轴上的位置,垂直于屏幕。
    <html>元素位于层叠上下文的 root 级别,根层叠,默认情况下,所有元素都说是属于此根层叠上下文,但是任何元素节点也可以是其”局部层叠上下文“中的根层叠。
    position 属性值为 relative 或 absolute 或 fixed 的对象

z-index

  • 如果父元素 z-index 有效,那么子元素无论是否设置 z-index 都和父元素一致,会在父元素上方。如图元素#3 和元素#5
  • 如果兄弟元素的 z-index 生效,那么其子元素覆盖关系有父元素决定。如图元素#1 和元素#4

应用

  • 定位 弹框
  • 文档流

div 里面的文字垂直居中,且该文字的大小根据屏幕大小自适应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
* {
margin: 0;
}

.inner {
width: 10rem;
height: 5rem;
line-height: 5rem;
text-align: center;
border: 1px solid #000;
font-size: 1rem;
box-sizing: border-box;
}
</style>

<body>
<div class='inner'> 文字垂直居中</div>

</body>
<script>
let body = document.documentElement;

let width = body.clientWidth;
let font = width / 40;
body.style.fontSize = font + 'px'
</script>

</html>

一个自适应矩形,水平垂直居中,且宽高比为 2:1

1
2
3
4
5
6
7
8
9
10
11
12
13
.box {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
margin: auto;

width: 10%;
height: 0;
padding-top: 20%;
background: tomato
}

三角型

1
2
3
4
5
6
7
.triangle {
width: 0;
height: 0;
border-width: 100px;
border-style: solid;
border-color: tomato transparent transparent transparent;
}

正方形

1
2
3
4
5
6
7
8
9
10
11
12
  .square {
width: 10%;
height: 10vw;
background-color: tomato
}

.square {
width: 20%;
height: 0;
padding-top: 20%;
background-color: tomato
}

实现单行、多行文本溢出的省略

  • 单行文本溢出

    1
    2
    3
    4
    5
    p {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    }
  • 多行文本溢出
    适合 WebKit 浏览器或移动端

1
2
3
4
5
6
7
p {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}

绝对定位

问题:

  • 单行文本也会出现…,
  • 可能只遮挡半个文字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
p {
position:relative;
line-height:1.5em;
/* 高度为需要显示的行数*行高,比如这里我们显示两行,则为3 */
height:3em;
overflow:hidden;
word-break: break-all;
}
p:after {
content:"...";
position:absolute;
bottom:0;
right:0;
padding: 0 5px;
background-color: #fff;
}

隐藏元素的 background-image 到底加不加载

  • 元素的背景图片
    • 元素本身设置display:none,会请求图片
    • 父元素设置display:none,不会请求图片
    • background-image没有使用,不会请求
    • hover伪类设置的背景图片,触发时请求
  • img标签图片在任何情况下都会请求图片

如果需要手动写动画,你认为最小时间间隔是多久,为什么?(阿里)

多数显示器默认频率是 60Hz,即 1 秒刷新 60 次,所以理论上最小间隔为 1/60*1000ms = 16.7ms

如何去除inline-block元素间距

移除空格使用margin负值,使用font-size:0letter-spacingword-spacing

overflow:scroll 时不能平滑滚动的问题怎么处理

以下代码可解决这种卡顿的问题:-webkit-overflow-scrolling:touch,是因为这行代码启用了硬件加速特性,所以滑动很流畅。

.png、jpg、gif 这些图片格式解释一下,分别什么时候用。有没有了解过 webp

(1)第一种是 BMP 格式,它是无损压缩的,支持索引色和直接色的点阵图。由于它基本上没有进行压缩,因此它的文件体积一般比较大。

(2)第二种是 GIF 格式,它是无损压缩的使用索引色的点阵图。由于使用了 LZW 压缩方法,因此文件的体积很小。并且 GIF 还支持动画和透明度。但因为它使用的是索引色,所以它适用于一些对颜色要求不高且需要文件体积小的场景。

(3)第三种是 JPEG 格式,它是有损压缩的使用直接色的点阵图。由于使用了直接色,色彩较为丰富,一般适用于来存储照片。但由于使用的是直接色,可能文件的体积相对于 GIF 格式来说更大。

(4)第四种是 PNG-8 格式,它是无损压缩的使用索引色的点阵图。它是 GIF 的一种很好的替代格式,它也支持透明度的调整,并且文件的体积相对于 GIF 格式更小。一般来说如果不是需要动画的情况,我们都可以使用 PNG-8 格式代替 GIF 格式。

(5)第五种是 PNG-24 格式,它是无损压缩的使用直接色的点阵图。PNG-24 的优点是它使用了压缩算法,所以它的体积比 BMP 格式的文件要小得多,但是相对于其他的几种格式,还是要大一些。

(6)第六种格式是 svg 格式,它是矢量图,它记录的图片的绘制方式,因此对矢量图进行放大和缩小不会产生锯齿和失真。它一般适合于用来制作一些网站 logo 或者图标之类的图片。

(7)第七种格式是 webp 格式,它是支持有损和无损两种压缩方式的使用直接色的点阵图。使用 webp 格式的最大的优点是,在相同质量的文件下,它拥有更小的文件体积。因此它非常适合于网络图片的传输,因为图片体积的减少,意味着请求时间的减小,这样会提高用户的体验。这是谷歌开发的一种新的图片格式,目前在兼容性上还不是太好。

浏览器如何判断是否支持 webp 格式图片

  • 宽高判断法
    通过创建image对象,将其src属性设置webp格式的图片,然后在onload事件中获取图片宽高,如果能够获取,则说明浏览器支webp 格式图片。如果不能获取或者触发了onerror函数,那么就说明浏览器不支持webp格式的图片。

  • canvas判断法
    动态创建一个canvas对象,将canvastoDataURL设置 webp格式,然后判断返回值中是否含有image/webp字段,如果包含则说明支持WebP02,反之则不支持。

画一个宽度 0.5px 的线

  • transform
1
2
height: 1px;
transform: scaleY(0.5);
  • linear-gradient

  • viewport

<meta name="viewport" content="width=device-width,initial-scale=0.5">

  • border-image

transitionanimation的区别

transition关注的是CSS property的变化,property值和时间的关系是一个三次贝塞尔曲线
animation作用于元素本身而不是样式属性,可以使用关键帧,实现更自由的动画效果。

浏览器兼容性问题

  • png24 位的图片在 IE6 浏览器上出现背景
    换成 png8,或者引用一段脚本处理
  • 浏览器默认的marginpadding不同
    加一个全局的*{margin:0;padding:0}来统一

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    //淘宝的样式初始化代码:

    body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend
    ,button,input,textarea,th,td{margin:0;padding:0;}
    body,button,input,select,textarea{font:12px/1.5tahoma,arial,\5b8b\4f53;}
    h1,h2,h3,h4,h5,h6{font-size:100%;}
    address,cite,dfn,em,var{font-style:normal;}
    code,kbd,pre,samp{font-family:couriernew,courier,monospace;}
    small{font-size:12px;}
    ul,ol{list-style:none;}
    a{text-decoration:none;}
    a:hover{text-decoration:underline;}
    sup{vertical-align:text-top;}
    sub{vertical-align:text-bottom;}
    legend{color:#000;}
    fieldset,img{border:0;}
    button,input,select,textarea{font-size:100%;}
    table{border-collapse:collapse;border-spacing:0;}

简单介绍使用图片 base64 编码的优点和缺点

base64 编码是一种图片处理格式,通过特定的算法将图片编码成一长串字符串,在页面上显示的时候,可以用该字符串来代替图片的 url 属性。
优点:减少一个 HTTP 请求
缺点:

  1. 编码后的文件会比原文件大 1/3,如果把大图片编码到html/css中,不仅会造成文件体积的增加,影响文件的加载速度,还会增加浏览器对 html 或 css 文件解析渲染的时间。
  2. base64 不能直接缓存,只能缓存包含 base64 的文件,比如 HTML 或者 CSS,相比于直接缓存图片的效果差很多
  3. 兼容性问题,iE8 以前的浏览器不支持。

displaypositionfloat的相互关系

  1. 如果display属性为none,则positionfloat属性的值不影响元素最后的表现。

  2. 如果display属性为absolutefixed,则float属性失效,并且display的值被设置为table或者block,具体转换为需要看初始转换值。

  3. 如果display属性不是absolutefixed,则判断float属性的值是否为none,如果不是,则display的值则按上面的规则转换。注意,如果position的值为relative并且float属性的值存在,则relative相对于浮动后的最终位置定位。

  4. 如果float的值为none,则判断元素是否为根元素,如果是根元素则display属性按照上面的规则转换,如果不是,则保持指定的display属性值不变。

position:absoluteposition:fixed优先级最高,此时float不起作用,display的值也需要调整;其次,元素的float的特性值不是none的时候或者它的根元素的时候,调整display的值,最后,非根元素,并且非浮动元素,并且非绝对定位的元素,display特性值同时设置值。

-------------本文结束感谢阅读-------------