一直以来对前端抱有莫名的兴趣,这次换工作后如愿以偿的接手了很多前端的任务。借着之前粗浅的经验上手的还算快,可是深入的方面就不太跟得上了。众所周知,前端的学习离不开实践和积累,为了快速而有效的进步,在此制定了第一阶段的学习任务 -- 收集和实现CodePen上100个前端小项目。此阶段的目的是借着一个个小项目快速熟悉HTML, CSS, JS的简单应用和套路。
下面开始进入正题,第一个项目是我在CodePen上看到的,觉得图案可爱就把代码扒了下来实现了一遍(图案见下图)。这个项目精髓主要在于CSS,研究完这个项目,基本上可以对CSS盒模型,瀑布流模式,DOM分层有基本的掌握。
https://codepen.io/xinxhe/pen/PooQNXJ?editors=1100

image.png
下面是HTML的实现,这里是用了pug,语法上更简洁。可以看出,HTML元素的分层是自外向内的,最外面是一个大的container,向内一层分为了三个大块:笑脸,下划线,和背景装饰物,再向内就是三大块中的各种细节。
1 div.container 2 div.smiley__face.smiley__face--01 // 笑脸中间 3 div.face 4 div.eyes 5 div.eye.eye__left 6 div.eye.eye__right 7 div.mouth 8 div.smiley__face.smiley__face--02 // 笑脸左边 9 div.face 10 div.eyes 11 div.eye.eye__left 12 div.eye.eye__right 13 div.mouth 14 div.smiley__face.smiley__face--03 // 笑脸右边 15 div.face 16 div.eyes 17 div.eye.eye__left 18 div.eye.eye__right 19 div.mouth 20 div.underground // 下划线 21 div.sparkles // 星星和圈圈 22 div.star.star--01 23 div.star.star--02 24 div.star.star--03 25 div.circle.circle--01 26 div.circle.circle--02 27 div.circle.circle--03 28 div.circle.circle--04
CSS的实现比较长,直接上注释解释。
1 * {
2 margin: 0;
3 padding: 0;
4 box-sizing: border-box; // padding和border的宽度包含在width和height中
5 }
6 body {
7 display: block;
8 width: 100%;
9 height: 100vh; // 1vh代表浏览器viewport高度的1%. Viewport代表浏览器窗口的大小,如果拖动浏览器边框,浏览器的viewport会根据窗口边界的拖动而改变大小。
10 background: #ecf0f1;
11 }
12 .container {
13 position: relative; // 相对于正常位置。在这里,container的位置确定是相对于body的元件的。
14 display: flex; // 盒模型,可以定义其子组件的排列方式
15 width: 100%;
16 height: 100vh;
17 justify-content: center; // Horizontal alignment,水平居中
18 align-items: center; // Vertical alignment,垂直居中
19 .smiley__face {
20 padding: 10px;
21 position: absolute; // 元件的位置是相对于最近的positioned的父元件来确定的。Positioned的元件是指任何具有position属性但是其值不是static的父元件。在这里,smiley__face的位置是相对于container来定的。
22 display: flex;
23 align-items: flex-start; // 垂直靠顶端排列
24 justify-content: center;
25 border: 12px solid #2c3e50;
26 width: 170px;
27 height: 190px;
28 background: #ffffff;
29 border-radius: 15px;
30 overflow: hidden;
31 .face {
32 background: #f1c40f;
33 width: 100%;
34 height: 120px;
35 border-radius: 5px;
36 display: flex;
37 flex-direction: column; // 定义子元件们的排列方式为竖直的一列。
38 justify-content: center;
39 align-items: center;
40 position: relative; // 位置定义相对于smiley__face,因为smiley__face有position的属性(并且值不是static),并且是最近的父元件
41 overflow: hidden;
42 z-index: 1; // z-index定义了层级关系,数字越大层级越高
43 .eyes {
44 display: flex;
45 justify-content: space-between; // 定义了子元件们之间间隔的平均排列方式
46 align-items: center;
47 height: 20px;
48 width: 60%;
49 .eye {
50 display: block;
51 width: 15px;
52 height: 15px;
53 background: #2c3e50;
54 border-radius: 50px;
55 }
56 }
57 .mouth {
58 display: block;
59 width: 32px;
60 height: 20px;
61 background: #2c3e50;
62 border-top-left-radius:15px;
63 border-top-right-radius:15px;
64 border-bottom-left-radius:50px;
65 border-bottom-right-radius:50px;
66 position: relative;
67 overflow: hidden;
68 &::before { // 舌头
69 content: "";
70 display: block;
71 width: 20px;
72 height: 10px;
73 background: #e74c3c;
74 border-radius:50%;
75 position: absolute;
76 left: 50%;
77 bottom: 2px;
78 transform: translateX(-50%); // Move 50% of the width of the element
79 }
80 }
81 }
82 &.smiley__face--01 {
83 z-index: 3;
84 }
85 &.smiley__face--02,
86 &.smiley__face--03 {
87 z-index: 2;
88 }
89 &.smiley__face--02 {
90 transform: rotate(-25deg) translate(-100px, -8px) scale(.9);
91 .face {
92 background: #3498db;
93 &::before { // 脸部非阴影部分
94 content: "";
95 position: absolute;
96 left: 0;
97 top: 0;
98 display: block;
99 width: 70%;
100 height: 100%;
101 background: #0abde3;
102 z-index: -1;
103 transform: skewX(-25deg) translateX(-30%);
104 }
105 }
106 }
107 &.smiley__face--03 {
108 transform: rotate(25deg) translate(100px, -8px) scale(.9);
109 .face { // 脸部非阴影部分
110 background: #ff7f50;
111 &::before {
112 content: "";
113 position: absolute;
114 left: 0;
115 top: 0;
116 display: block;
117 width: 70%;
118 height: 100%;
119 background:#ff6348;
120 z-index: -1;
121 transform: skewX(25deg) translateX(-30%);
122 }
123 }
124 }
125 }
126 .underground {
127 display: block;
128 width: 200px;
129 margin: 0 auto;
130 border: 6px solid #2c3e50;
131 position: relative;
132 height: 1px;
133 transform: translateY(180px);
134 border-radius: 50px;
135 }
136 .sparkles {
137 position: absolute;
138 display: block;
139 width: 500px;
140 height: 80%;
141 .star {
142 display: block;
143 width: 50px;
144 height: 50px;
145 margin: 20px;
146 position: absolute;
147 overflow: hidden;
148 &::before { // 星星中横杠
149 content: "";
150 display: block;
151 width: 80%;
152 position: absolute;
153 left: 0;
154 top: 50%;
155 transform: translate(0, -50%);
156 border:4px solid #2c3e50;
157 border-radius: 50px;
158 }
159 &::after { // 星星中竖杠
160 content:"";
161 display: block;
162 height:80%;
163 position: absolute;
164 left:50%;
165 top:50%;
166 transform:translate(-50%,-50%);
167 border:4px solid #2c3e50;
168 border-radius:50px;
169 }
170 &.star--01 {
171 top:10%;
172 left:30%;
173 transform:translate(-30%,-10%) scale(.4);
174 &::before {
175 border-color:#f1c40f;
176 }
177 &::after {
178 border-color:#f1c40f;
179 }
180 &::before,
181 &::after {
182 border-width:6px;
183 }
184 }
185 &.star--02 {
186 top: 20%;
187 left: 90%;
188 transform: translate(-90%, -20%) scale(.3);
189 &::before {
190 border-color: #3498db;
191 }
192 &::after {
193 border-color: #3498db;
194 }
195 &::before,
196 &::after {
197 border-width: 6px;
198 }
199 }
200 &.star--03 {
201 top: 2%;
202 left: 60%;
203 transform: translate(-60%, -2%) scale(.7);
204 &::before {
205 border-color: #ff7f50;
206 }
207 &::after {
208 border-color: #ff7f50;
209 }
210 &::before,
211 &::after {
212 border-width: 5px;
213 }
214 }
215 }
216 .circle {
217 display: block;
218 width: 50px;
219 height: 50px;
220 border-radius: 50px;
221 background: #f1c40f;
222 position: absolute;
223 &.circle--01 {
224 border: 10px solid #f1c40f;
225 background: transparent;
226 top: 10%;
227 left: 15%;
228 transform: translate(-15%, -10%) scale(.5);
229 }
230 &.circle--02 {
231 background: transparent;
232 border: 15px solid #3498db;
233 top: 40%;
234 left: 100%;
235 transform: translate(-100%, -40%) scale(.2);
236 }
237 &.circle--03 {
238 background: #ff7f50;
239 top: 30%;
240 left: 8%;
241 transform: translate(8%, -30%) scale(.3);
242 }
243 &.circle--04 {
244 top: 70%;
245 left: 0%;
246 transform: translate(0%, -70%) scale(.2);
247 }
248 }
249 }
250 }