最终效果是这样的,下面我们一步步实现它

file

编写dom结构

我们需要的dom结构很少,只要一个container和一个content就可以了

1
2
3
4
5
<div class="container">
<div class="content">
Genius only means hard-working all one's life.
</div>
</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
38
39
body, h1{
margin: 0;
padding: 0;
}
html, body {
font-size: 19px;
font-family: serif;
color: rgba(0,0,0,0.8);
}
.container {
width: 100%;
height: 100%;
position: relative;
background-image: url("./resource/images/bg.bmp");
background-repeat: no-repeat;
background-position: center top;
background-size: cover;
display: flex;
justify-content: center;
align-items: center;
}
.content {
width: 800px;
height: 400px;
position: relative;
border-radius: 8px;
box-shadow: 0 10px 20px rgba(0,0,0,0.5);
padding: 50px;
box-sizing: border-box;
background: transparent;
}
.content h1 {
text-align: center;
margin-bottom: 20px;
}
.content p {
text-indent: 2em;
line-height: 1.7;
}

在应用了这些样式后,我们的页面成了这个样子

file

container占满整个屏幕,content在container里水平居中,因为content设置了背景透明,所以可以直接透过content看到container的内容(背景)

编写核心css样式

我们要做的事情很简单,设置content的一个伪元素,让它的层叠等级低于content,这样伪元素就可以在content的下面作为背景,然后设置伪元素的背景,背景设置除了background-attachment一定要设置成fixed,让背景相对视口定位,其他的都直接照抄,这样伪元素的背景就会和container的背景重合,但是伪元素和content大小一样,而元素的背景的范围又不能超过元素本身,所以只显示content大小的模糊化背景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.content::before {
/* 让伪元素铺满content */
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
/* 设置伪元素的背景,最重要的是设置背景图片的位置是视口固定 */
/* 其他的设置直接照抄container的设置,否则可能导致不重合 */
background-image: url("./resource/images/bg.bmp");
background-position: center top;
background-size: cover;
background-attachment: fixed;
/* 让伪元素模糊化 */
filter: blur(20px);
/* 降低伪元素的层级,让伪元素在content的下面展现 */
z-index: -1;
}
.content {
overflow: hidden;
z-index: 1;
}

现在的样子是这样的

file

收尾工作

看起来一切顺利,但是如果你放大页面,效果就显得不是那么完美

file

没错,边缘部分的模糊化看起来效果不大好,不过解决也很简单

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
.content {
/* 因为设置了溢出隐藏, 所以看上去伪元素是没有变大的 */
overflow: hidden;
z-index: 1;
}
.content::before {

content: '';
position: absolute;
/* 让伪元素比content每边多30px */
/* 这样就可以避开filter: blur(20px)带来的边缘模糊效果不好 */
top: -30px;
left: -30px;
right: -30px;
bottom: -30px;
/* 设置伪元素的背景,最重要的是设置背景图片的位置是视口固定 */
/* 其他的设置直接照抄container的设置,否则可能导致不重合 */
background-image: url("./resource/images/bg.bmp");
background-position: center top;
background-size: cover;
background-attachment: fixed;
/* 让伪元素模糊化 */
filter: blur(20px);
/* 降低伪元素的层级,让伪元素在content的下面展现 */
z-index: -1;
}

我们只要设置top, left, right, bottom都为-30px就好了,这样模糊不全的部分其实就是移除content的部分,但那部分被裁剪掉了,只剩下内部模糊效果较好的部分

file