一直以来对前端抱有莫名的兴趣,这次换工作后如愿以偿的接手了很多前端的任务。借着之前粗浅的经验上手的还算快,可是深入的方面就不太跟得上了。众所周知,前端的学习离不开实践和积累,为了快速而有效的进步,在此制定了第一阶段的学习任务 -- 收集和实现CodePen上100个前端小项目。此阶段的目的是借着一个个小项目快速熟悉HTML, CSS, JS的简单应用和套路。
下面开始进入正题,第一个项目是我在CodePen上看到的,觉得图案可爱就把代码扒了下来实现了一遍(图案见下图)。这个项目精髓主要在于CSS,研究完这个项目,基本上可以对CSS盒模型,瀑布流模式,DOM分层有基本的掌握。
https://codepen.io/xinxhe/pen/PooQNXJ?editors=1100
下面是HTML的实现,这里是用了pug,语法上更简洁。可以看出,HTML元素的分层是自外向内的,最外面是一个大的container,向内一层分为了三个大块:笑脸,下划线,和背景装饰物,再向内就是三大块中的各种细节。
div.container
div.smiley__face.smiley__face--01 // 笑脸中间
div.face
div.eyes
div.eye.eye__left
div.eye.eye__right
div.mouth
div.smiley__face.smiley__face--02 // 笑脸左边
div.face
div.eyes
div.eye.eye__left
div.eye.eye__right
div.mouth
div.smiley__face.smiley__face--03 // 笑脸右边
div.face
div.eyes
div.eye.eye__left
div.eye.eye__right
div.mouth
div.underground // 下划线
div.sparkles // 星星和圈圈
div.star.star--01
div.star.star--02
div.star.star--03
div.circle.circle--01
div.circle.circle--02
div.circle.circle--03
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 }