前言
在前端开发的奇妙世界里,我们常常希望用代码绘制出各种可爱又有趣的画面。今天,就带大家一起实现一个超级萌的卡通页面🎨,并且深入探索其中至关重要的定位知识~
效果展示
先给大家看看最终成果,两个带着红晕、笑眼弯弯的可爱小圆脸,还有左边脸颊戴着花朵头饰的小心机设计,背景是温柔的粉色,满满的甜蜜氛围💘。
一、HTML 基础搭建
1. 快速构建 HTML 结构
在编写 HTML 代码时,Emmet 语法是一个超级实用的工具。它基于 CSS 选择器,能让我们快速输入 HTML 结构。比如,输入 div#l-ball.ball
就能迅速创建一个带有 id
为 l-ball
和 class
为 ball
的 div
元素。这种方式大大提高了编码效率,让我们可以更专注于页面的逻辑和设计。
2. 标签与选择器的巧妙运用
div
标签是构建页面结构的主力军。通过 id
和 class
对元素进行标识和分类,能让我们更好地管理和操作页面元素。id
具有唯一性,就像每个人的身份证号码一样,能精准定位到一个元素;而 class
则可以复用,适用于多个具有相同样式或功能的元素。
在 HTML 结构中,我们还可以使用 >
子元素选择器和 +
相邻兄弟选择器。例如 .container>#l-ball.ball+#r-ball.ball
,它清晰地描述了元素之间的层次和相邻关系,让代码更具可读性和可维护性。
3. 实际应用示例
下面是这个网页具体的 HTML 代码示例,展示了如何使用上述知识点构建一个的页面结构:
<div class="container">
<!-- 左边的脸 -->
<div class="face l_face">
<div class="eye1 l_eye1"></div>
<div class="eye1 r_eye1"></div>
<div class="blush1 l_blush1"></div>
<div class="blush1 r_blush1"></div>
<div class="mouth l_mouth"></div>
</div>
<!-- 右边的脸 -->
<div class="face r_face">
<div class="eye">
<div class="eye2 l_eye2"></div>
<div class="eye2 r_eye2"></div>
</div>
<div class="blush2 l_blush2"><i>| | |</i></div>
<div class="blush2 r_blush2"><i>| | |</i></div>
<div class="mouth r_mouth"></div>
</div>
<!-- 花朵头饰 -->
<div class="flower">
<div class="petal"></div>
<div class="petal"></div>
<div class="petal"></div>
<div class="petal"></div>
<div class="petal"></div>
<div class="petal"></div>
<div class="petal"></div>
<div class="petal"></div>
<div class="center"></div>
</div>
</div>
</div>
二、CSS 样式实现
1. display
属性的奥秘
display
属性决定了元素在页面中的显示方式,常见的取值有 block
、inline
和inline-block
。
block
:块级元素,如div
、h1
-h6
、p
等,它们每个元素都会独占一行,并且可以设置宽高。这使得我们可以方便地对页面进行布局,将不同的内容划分成不同的块。inline
:行内元素,如span
、a
、img
等,它们不会独占一行,而是会在同一行内依次排列。不过,行内元素不能直接设置宽高,其大小由内容决定。inline-block
:行内块元素,结合了块级元素和行内元素的优点,既可以设置宽高,又能在一行内显示。这在实现水平排列的元素时非常有用。
2. 定位属性的灵活运用
定位属性让我们可以精确地控制元素在页面中的位置,常见的取值有 static
、relative
、absolute
、sticky
、fixed
。
<div class="box1">box1</div>
<div class="box2">box2</div>
<div class="box3">box3</div>
<style>
* {
top: 0;
left: 0;
box-sizing: border-box;
}
.box1,
.box2,
.box3 {
display: inline-block;
margin-right: 5px;
width: 100px;
height: 70px;
background-color: rgb(236, 146, 170);
}
.box2 {
background-color: rgb(241, 111, 19);
}
</style>
原始效果图
static
静态定位,是元素的默认定位方式,没有定位能力,元素会按照正常的文档流进行排列。此时 top
, right
, bottom
, left
和 z-index
属性无效。
.box2 {
position: static;
top: 20px;
left: 20px;
background-color: rgb(241, 111, 19);
}
效果图:
relative
相对定位,元素会相对于自身原来的位置进行定位。同时,设置了相对定位的元素可以作为其子元素的定位参考(我们经常会用到“子绝父相”定位),为后续的绝对定位提供基础。
“子绝父相” 是前端开发中关于 CSS 定位的一种常用搭配技巧,指的是子元素使用
position: absolute
(绝对定位) ,父元素使用position: relative
(相对定位 ) 。以下是详细介绍:原理
- 父元素(相对定位) :当父元素设置
position: relative
时,它会在文档流中占据原本的空间位置,同时为其后代中使用绝对定位的子元素提供一个定位参考基准。它本身的位置可以通过top
、left
、bottom
、right
等属性进行微调,但这种微调是相对于它在文档流中原本位置而言的 ,不会影响周围其他元素的布局。- 子元素(绝对定位) :子元素设置
position: absolute
后,会脱离文档流,不再占据原本在文档流中的空间。它会相对于最近的已定位(非static
定位,如相对定位、绝对定位、固定定位等 )祖先元素进行定位。如果没有已定位的祖先元素,就相对于html
根元素(即浏览器视口 )进行定位。在 “子绝父相” 这种搭配里,子元素就是相对于设置了相对定位的父元素来确定位置。
.box2 {
position: relative;
top: 20px;
left: 20px;
background-color: rgb(241, 111, 19);
}
效果图:
absolute
绝对定位,元素会相对于离它最近的 position
不为 static
的父元素进行定位。如果没有这样的父元素,元素会相对于 body
进行定位。
.box2 {
position: absolute;
top: 20px;
left: 20px;
background-color: rgb(241, 111, 19);
}
效果图:
sticky
元素根据正常文档流进行定位,然后相对它的最近滚动祖先(nearest scrolling ancestor)和包含块(最近块级祖先 nearest block-level ancestor),包括 table-related 元素,基于 top
、right
、bottom
和 left
的值进行偏移。偏移值不会影响任何其他元素的位置。
.bigBox {
width: 400px;
height: 200px;
background-color: bisque;
overflow: scroll;//当内容溢出时有滚动条
}
.box2 {
position: sticky;
top: 20px;
left: 20px;
background-color: rgb(241, 111, 19);
}
/*新加的盒子,为了使滚动条出现*/
.box {
margin-top: 300px;
width: 300px;
height: 50px;
background-color: gainsboro;
}
效果图:
fixed
固定定位与绝对定位相似,但元素的包含块为 viewport 视口。该定位方式常用于创建在滚动屏幕时仍固定在相同位置的元素。在下面的示例中,"One" 元素定位在离页面顶部 80px,离页面左侧 20px 的位置。
<div class="outer">
<p>
段一:Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam congue tortor
eget pulvinar lobortis. Vestibulum ante ipsum primis in faucibus orci luctus
et ultrices posuere cubilia Curae; Nam ac dolor augue. Pellentesque mi mi,
laoreet et dolor sit amet, ultrices varius risus. Nam vitae iaculis elit.
Aliquam mollis interdum libero. Sed sodales placerat egestas. Vestibulum ut
arcu aliquam purus viverra dictum vel sit amet mi. Duis nisl mauris, aliquam
sit amet luctus eget, dapibus in enim.
</p>
<p style="color:red">
段二:Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam congue tortor
eget pulvinar lobortis. Vestibulum ante ipsum primis in faucibus orci luctus
et ultrices posuere cubilia Curae; Nam ac dolor augue. Pellentesque mi mi,
laoreet et dolor sit amet, ultrices varius risus. Nam vitae iaculis elit.
Aliquam mollis interdum libero.
</p>
<div class="box">One</div>
</div>
.box {
background: rgb(12, 238, 121);
width: 100px;
height: 100px;
margin: 20px;
position: fixed;
top: 80px;
left: 10px;
}
.outer {
width: 500px;
height: 300px;
overflow: scroll;
padding-left: 150px;
}
效果图:
回到我们的代码中,我们来讲解一下:
3. 代码拆解与定位知识讲解
3.1 整体布局与容器设置
* {
top: 0;
left: 0;
box-sizing: border-box;
}
body {
background-color: pink;
}
.container {
/* background-color: chartreuse; */
width: 450px;
height: 450px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
- 首先,
*
通配符设置box-sizing: border-box
是个小窍门✨,这样元素的width
和height
就包含了padding
和border
,方便我们进行布局计算。- 对于
.container
这个容器,我们使用了position: absolute
绝对定位。绝对定位是脱离文档流的,它会相对于最近的已定位祖先元素(如果没有已定位祖先元素,就相对于body
元素 )进行定位。这里通过top: 50%; left: 50%;
先把容器的左上角移动到页面的中间位置,然后再通过transform: translate(-50%, -50%);
把容器往回移动自身一半的距离,这样就实现了容器在页面中完美居中啦🥳。
3.2 卡通脸的定位
.face {
display: inline-block;
width: 200px;
height: 200px;
background-color: azure;
border: 13px black solid;
position: relative;
top: 25%;
left: 5%;
border-radius: 50%;
}
每个卡通脸
.face
采用position: relative
相对定位。相对定位是相对于元素本身在文档流中的位置进行定位的,它不会脱离文档流哦🤓。这里设置top: 25%; left: 5%;
是让脸在容器内稍微偏移一点位置,营造出亲亲的姿态~
3.3 眼睛、腮红、嘴巴的定位
以眼睛为例:
.eye1 {
width: 30px;
height: 35px;
position: absolute;
border-radius: 50%;
border-top: 0px solid;
}
.l_eye1 {
top: 30%;
left: 35%;
border-bottom: 8px black solid;
}
.r_eye1 {
top: 30%;
left: 75%;
border-bottom: 8px black solid;
}
眼睛、腮红、嘴巴这些小部件大多采用
position: absolute
绝对定位。因为它们要精确地放置在脸这个相对定位的父元素内,绝对定位可以让它们自由地在父元素内找位置。比如左眼.l_eye1
通过top: 30%; left: 35%;
确定在脸内的具体位置,这样就能画出萌萌的眼睛啦👀。
3.4 花朵头饰的定位
.flower {
position: relative;
width: 100px;
height: 100px;
/* background-color: aqua; */
top: -100px;
left: 16px;
}
.petal {
position: absolute;
top: 37px;
left: 36px;
width: 27px;
height: 27px;
background: #ff69b4;
border-radius: 0 50%;
border: 2px #f18ac3 solid;
}
花朵整体
.flower
用相对定位来确定在页面中的大概位置,而花瓣.petal
用绝对定位在花朵内部进行精确布局。通过设置不同的旋转角度和偏移量,就能拼出一朵漂亮的小花🌺 啦。
4. 花朵的制作过程
4.1 花朵结构概述
这个花朵由两部分组成:
- 8 个花瓣(粉色的心形元素)
- 一个黄色的花蕊(圆形中心)
它们通过精心的定位和旋转组合在一起,形成一朵完整的花。
4.2 核心实现原理
让我们看看 CSS 代码:
.flower {
position: relative;
width: 100px;
height: 100px;
top: -100px;
left: 16px;
}
.petal {
position: absolute;
top: 37px;
left: 36px;
width: 27px;
height: 27px;
background: #ff69b4;
border-radius: 0 50%;
border: 2px #f18ac3 solid;
}
.petal:nth-child(1) { transform: rotate(0deg) translate(30px); }
.petal:nth-child(2) { transform: rotate(45deg) translate(30px); }
.petal:nth-child(3) { transform: rotate(90deg) translate(30px); }
.petal:nth-child(4) { transform: rotate(135deg) translate(30px); }
.petal:nth-child(5) { transform: rotate(180deg) translate(30px); }
.petal:nth-child(6) { transform: rotate(225deg) translate(30px); }
.petal:nth-child(7) { transform: rotate(270deg) translate(30px); }
.petal:nth-child(8) { transform: rotate(315deg) translate(30px); }
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 37px;
height: 37px;
background: #ffea00;
border-radius: 50%;
}
4.3 分步解析
4.3.1 花朵容器
.flower {
position: relative;
width: 100px;
height: 100px;
top: -100px;
left: 16px;
}
- 使用
position: relative
作为定位参考点top: -100px
和left: 16px
将花朵定位到左侧脸部的上方- 宽度和高度定义了花朵的整体尺寸范围
4.3.2 花瓣的形状设计
.petal {
position: absolute;
top: 37px;
left: 36px;
width: 27px;
height: 27px;
background: #ff69b4;
border-radius: 0 50%;
border: 2px #f18ac3 solid;
}
position: absolute
让花瓣相对于.flower
容器定位
border-radius: 0 50%
是关键!这个值创建了一个独特的花瓣效果
- 左上角没有圆角 (0)--直角
- 右上角有 50% 的圆角
- 这种不对称的圆角设置产生了花瓣的形状
所有花瓣初始位置都重叠在容器中心附近
4.3.3 花瓣的环形排列
.petal:nth-child(1) { transform: rotate(0deg) translate(30px); }
.petal:nth-child(2) { transform: rotate(45deg) translate(30px); }
/* ... 其余6个花瓣类似 ... */
这是整个花朵最巧妙的部分!通过组合rotate()
和translate()
实现了花瓣的环形排列:
- rotate (角度) - 将花瓣绕着容器中心旋转指定角度
- translate(30px) - 将旋转后(!!!) 的花瓣沿 X 轴正方向移动 30px (相当于沿着旋转的方向移动)
由于每个花瓣旋转角度相差 45 度 (360°/8 = 45°) ,它们最终均匀分布在一个圆周上,形成完美的花朵形状!
4.3.4 花蕊的添加
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 37px;
height: 37px;
background: #ffea00;
border-radius: 50%;
}
- 使用绝对定位和
top: 50%
+left: 50%
将元素左上角置于容器中心transform: translate(-50%, -50%)
将元素自身向左上方移动自身宽度和高度的一半- 最终效果是元素完美居中
border-radius: 50%
创建圆形,配合黄色背景形成花蕊
4.4 为什么这样设计有效?
这种花瓣排列方式利用了 CSS 变换的组合效果:
- 所有花瓣元素在 HTML 中是连续的兄弟元素
- 使用
:nth-child()
选择器为每个花瓣应用不同的旋转角度 - 每个花瓣先旋转指定角度,然后沿旋转后的 X 轴方向平移
- 由于旋转轴心是元素自身中心,这种方法可以高效地创建环形布局
三、完整代码回顾
有点长哦,不看的可以回收
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>kiss</title>
<style>
* {
top: 0;
left: 0;
box-sizing: border-box;
}
body {
background-color: pink;
}
.container {
/* background-color: chartreuse; */
width: 450px;
height: 450px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.face {
display: inline-block;
width: 200px;
height: 200px;
background-color: azure;
border: 13px black solid;
position: relative;
top: 25%;
left: 5%;
border-radius: 50%;
}
.eye1 {
width: 30px;
height: 35px;
position: absolute;
border-radius: 50%;
border-top: 0px solid;
}
.l_eye1 {
top: 30%;
left: 35%;
border-bottom: 8px black solid;
}
.r_eye1 {
top: 30%;
left: 75%;
border-bottom: 8px black solid;
}
/* 右边脸的眼睛 */
.eye2 {
width: 30px;
height: 35px;
position: absolute;
border-radius: 50%;
top: 36%;
border-bottom: 0px solid;
}
.l_eye2 {
left: 10%;
border-top: 8px black solid;
}
.r_eye2 {
left: 47%;
border-top: 8px black solid;
}
/* 腮红 */
.blush1 {
width: 28px;
height: 15px;
background-color: rgba(255, 0, 0, 0.662);
border-radius: 50%;
position: absolute;
top: 55%;
}
.l_blush1 {
left: 20%;
}
.r_blush1 {
left: 90%;
}
.blush2 {
width: 20px;
height: 17px;
background-color: rgba(255, 0, 0, 0.662);
border-radius: 50%;
position: absolute;
top: 55%;
}
i {
color: rgb(118, 109, 109);
position: absolute;
top: -1px;
font-size: x-small;
}
.l_blush2 {
left: 5%;
}
.r_blush2 {
left: 60%;
}
/* 嘴巴 */
.mouth {
border-radius: 50%;
border-top: 0px solid;
border-bottom: 10px black solid;
position: absolute;
}
.l_mouth {
width: 50px;
height: 38px;
top: 50%;
left: 48%;
}
.r_mouth {
width: 42px;
height: 38px;
top: 50%;
left: 25%;
}
/* 花头饰 */
.flower {
position: relative;
width: 100px;
height: 100px;
/* background-color: aqua; */
top: -100px;
left: 16px;
}
.petal {
position: absolute;
top: 37px;
left: 36px;
width: 27px;
height: 27px;
background: #ff69b4;
border-radius: 0 50%;
border: 2px #f18ac3 solid;
}
.petal:nth-child(1) {
transform: rotate(0deg) translate(30px);
}
.petal:nth-child(2) {
transform: rotate(45deg) translate(30px);
}
.petal:nth-child(3) {
transform: rotate(90deg) translate(30px);
}
.petal:nth-child(4) {
transform: rotate(135deg) translate(30px);
}
.petal:nth-child(5) {
transform: rotate(180deg) translate(30px);
}
.petal:nth-child(6) {
transform: rotate(225deg) translate(30px);
}
.petal:nth-child(7) {
transform: rotate(270deg) translate(30px);
}
.petal:nth-child(8) {
transform: rotate(315deg) translate(30px);
}
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 37px;
height: 37px;
background: #ffea00;
border-radius: 50%;
}
</style>
</head>
<body>
<div class="container">
<!-- 左边的脸 -->
<div class="face l_face">
<!-- 眼睛 -->
<!-- <div class="eye1"> -->
<div class="eye1 l_eye1"></div>
<div class="eye1 r_eye1"></div>
<!-- </div> -->
<!-- 腮红 -->
<div class="blush1 l_blush1"></div>
<div class="blush1 r_blush1"></div>
<!-- 嘴巴 -->
<div class="mouth l_mouth"></div>
</div>
<!-- 右边的脸 -->
<div class="face r_face">
<!-- 眼睛 -->
<div class="eye">
<div class="eye2 l_eye2"></div>
<div class="eye2 r_eye2"></div>
</div>
<!-- 腮红 -->
<div class="blush2 l_blush2"><i>| | |</i></div>
<div class="blush2 r_blush2"><i>| | |</i></div>
<!-- 嘴巴 -->
<div class="mouth r_mouth"></div>
</div>
<!-- 花朵头饰 -->
<div class="flower">
<div class="petal"></div>
<div class="petal"></div>
<div class="petal"></div>
<div class="petal"></div>
<div class="petal"></div>
<div class="petal"></div>
<div class="petal"></div>
<div class="petal"></div>
<div class="center"></div>
</div>
</div>
</div>
</body>
</html>
四、总结
通过以上的学习,我们不仅掌握了如何使用 HTML 和 CSS 构建一个浪漫的网页,还深入了解了 HTML 结构搭建、CSS 样式设置和定位的相关知识点。这些知识点是前端开发的基础,希望大家在今后的学习和实践中能够灵活运用,创造出更多精彩的页面效果。
快来动手试试吧,用代码传递属于你的浪漫!