一直以来对前端抱有莫名的兴趣,这次换工作后如愿以偿的接手了很多前端的任务。借着之前粗浅的经验上手的还算快,可是深入的方面就不太跟得上了。众所周知,前端的学习离不开实践和积累,为了快速而有效的进步,在此制定了第一阶段的学习任务 -- 收集和实现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的实现比较长,直接上注释解释。
* {
margin: 0;
padding: 0;
box-sizing: border-box; // padding和border的宽度包含在width和height中
}
body {
display: block;
width: 100%;
height: 100vh; // 1vh代表浏览器viewport高度的1%. Viewport代表浏览器窗口的大小,如果拖动浏览器边框,浏览器的viewport会根据窗口边界的拖动而改变大小。
background: #ecf0f1;
}
.container {
position: relative; // 相对于正常位置。在这里,container的位置确定是相对于body的元件的。
display: flex; // 盒模型,可以定义其子组件的排列方式
width: 100%;
height: 100vh;
justify-content: center; // Horizontal alignment,水平居中
align-items: center; // Vertical alignment,垂直居中
.smiley__face {
padding: 10px;
position: absolute; // 元件的位置是相对于最近的positioned的父元件来确定的。Positioned的元件是指任何具有position属性但是其值不是static的父元件。在这里,smiley__face的位置是相对于container来定的。
display: flex;
align-items: flex-start; // 垂直靠顶端排列
justify-content: center;
border: 12px solid #2c3e50;
width: 170px;
height: 190px;
background: #ffffff;
border-radius: 15px;
overflow: hidden;
.face {
background: #f1c40f;
width: 100%;
height: 120px;
border-radius: 5px;
display: flex;
flex-direction: column; // 定义子元件们的排列方式为竖直的一列。
justify-content: center;
align-items: center;
position: relative; // 位置定义相对于smiley__face,因为smiley__face有position的属性(并且值不是static),并且是最近的父元件
overflow: hidden;
z-index: 1; // z-index定义了层级关系,数字越大层级越高
.eyes {
display: flex;
justify-content: space-between; // 定义了子元件们之间间隔的平均排列方式
align-items: center;
height: 20px;
width: 60%;
.eye {
display: block;
width: 15px;
height: 15px;
background: #2c3e50;
border-radius: 50px;
}
}
.mouth {
display: block;
width: 32px;
height: 20px;
background: #2c3e50;
border-top-left-radius:15px;
border-top-right-radius:15px;
border-bottom-left-radius:50px;
border-bottom-right-radius:50px;
position: relative;
overflow: hidden;
&::before { // 舌头
content: "";
display: block;
width: 20px;
height: 10px;
background: #e74c3c;
border-radius:50%;
position: absolute;
left: 50%;
bottom: 2px;
transform: translateX(-50%); // Move 50% of the width of the element
}
}
}
&.smiley__face--01 {
z-index: 3;
}
&.smiley__face--02,
&.smiley__face--03 {
z-index: 2;
}
&.smiley__face--02 {
transform: rotate(-25deg) translate(-100px, -8px) scale(.9);
.face {
background: #3498db;
&::before { // 脸部非阴影部分
content: "";
position: absolute;
left: 0;
top: 0;
display: block;
width: 70%;
height: 100%;
background: #0abde3;
z-index: -1;
transform: skewX(-25deg) translateX(-30%);
}
}
}
&.smiley__face--03 {
transform: rotate(25deg) translate(100px, -8px) scale(.9);
.face { // 脸部非阴影部分
background: #ff7f50;
&::before {
content: "";
position: absolute;
left: 0;
top: 0;
display: block;
width: 70%;
height: 100%;
background:#ff6348;
z-index: -1;
transform: skewX(25deg) translateX(-30%);
}
}
}
}
.underground {
display: block;
width: 200px;
margin: 0 auto;
border: 6px solid #2c3e50;
position: relative;
height: 1px;
transform: translateY(180px);
border-radius: 50px;
}
.sparkles {
position: absolute;
display: block;
width: 500px;
height: 80%;
.star {
display: block;
width: 50px;
height: 50px;
margin: 20px;
position: absolute;
overflow: hidden;
&::before { // 星星中横杠
content: "";
display: block;
width: 80%;
position: absolute;
left: 0;
top: 50%;
transform: translate(0, -50%);
border:4px solid #2c3e50;
border-radius: 50px;
}
&::after { // 星星中竖杠
content:"";
display: block;
height:80%;
position: absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%);
border:4px solid #2c3e50;
border-radius:50px;
}
&.star--01 {
top:10%;
left:30%;
transform:translate(-30%,-10%) scale(.4);
&::before {
border-color:#f1c40f;
}
&::after {
border-color:#f1c40f;
}
&::before,
&::after {
border-width:6px;
}
}
&.star--02 {
top: 20%;
left: 90%;
transform: translate(-90%, -20%) scale(.3);
&::before {
border-color: #3498db;
}
&::after {
border-color: #3498db;
}
&::before,
&::after {
border-width: 6px;
}
}
&.star--03 {
top: 2%;
left: 60%;
transform: translate(-60%, -2%) scale(.7);
&::before {
border-color: #ff7f50;
}
&::after {
border-color: #ff7f50;
}
&::before,
&::after {
border-width: 5px;
}
}
}
.circle {
display: block;
width: 50px;
height: 50px;
border-radius: 50px;
background: #f1c40f;
position: absolute;
&.circle--01 {
border: 10px solid #f1c40f;
background: transparent;
top: 10%;
left: 15%;
transform: translate(-15%, -10%) scale(.5);
}
&.circle--02 {
background: transparent;
border: 15px solid #3498db;
top: 40%;
left: 100%;
transform: translate(-100%, -40%) scale(.2);
}
&.circle--03 {
background: #ff7f50;
top: 30%;
left: 8%;
transform: translate(8%, -30%) scale(.3);
}
&.circle--04 {
top: 70%;
left: 0%;
transform: translate(0%, -70%) scale(.2);
}
}
}
}
网友评论