引子:一场HTML与CSS的爱情故事
各位看官,今天我们要讲一个关于网页世界的浪漫故事。主角是两个可爱的小球——左球和右球(别笑,这名字可是他们自己选的)。他们的爱情故事,将用最优雅的HTML和CSS语言来讲述。在此过程中顺带给大家介绍一下重要考点(哈哈哈其实这才是主角)
第一幕:初遇 - HTML结构搭建
让我们先认识一下两位主角:
<!-- 包裹两个小球的大盒子 -->
<div class="container">
<!-- 左球 -->
<div id="l-ball" class="ball">
<!-- 左球脸 -->
<div class="face face-l">
<!-- 眼睛,嘴巴 -->
<div class="eye eye-l"></div>
<div class="eye eye-r"></div>
<div class="mouth"></div>
</div>
</div>
<!-- 右球 -->
<div id="r-ball" class="ball">
<!-- 右球脸 -->
<div class="face face-r">
<!-- 眼睛,嘴巴 -->
<div class="eye eye-l eye-r-p"></div>
<div class="eye eye-r eye-r-p"></div>
<div class="mouth mouth-r"></div>
</div>
</div>
</div>
这段代码里藏着不少秘密:
- div.container 是我们为这场爱情故事搭建的舞台
- #l-ball 和 #r-ball 分别是左球和右球的ID(就像他们的身份证)
- .ball 是他们共同的名字,说明他们有着相同的特征
这个写法用到了Emmet语法,是不是很像魔法咒语?.container>#l-ball.ball+#r-ball.ball,念完就变出了一个完美的舞台!(再按照类型的操作,生成小球里面的小盒子)
第二幕:妆容 - CSS基础样式
每个浪漫的故事都需要美丽的装扮:
<style>
/* 给小球添加一个浪漫的粉色背景舞台 */
body {
background-color: pink;
margin: 0;
}
/* 给大盒子添加属性 */
.container {
position: absolute;
top: 50%;
left: 50%;
width: 238px;
/*被内容撑高就好*/
/* height: 238px; */
/*背景颜色大法*/
/* background-color: blue; */
/* 与top 50%,left %50 共同完成了是其达到舞台中央 */
transform: translate(-50%, -50%);
}
.ball {
width: 100px;
height: 100px;
border: 8px solid black;
/*将盒子改成圆形*/
border-radius: 50%;
display: inline-block;
background-color: white;
/*行内块元素贴于舞台顶部*/
vertical-align: top;
/* 相对定位,子元素相对它定位 */
position: relative;
}
.face {
width: 70px;
height: 30px;
position: absolute;
right: 0;
top: 30px;
border-top-right-radius: 15px;
/* background-color: green; */
}
.eye {
width: 15px;
height: 15px;
border-radius: 50%;
border-bottom: 5px solid black;
position: absolute;
}
.eye-l {
position: absolute;
left: 10px;
}
.eye-r {
position: absolute;
right: 5px;
}
.mouth {
width: 30px;
height: 14px;
border-radius: 50%;
border-bottom: 5px solid black;
position: absolute;
bottom: -5px;
transform: translate(3px);
left: 0;
right: 0;
margin: auto;
}
.eye-r-p {
border-top: 5px solid black;
border-bottom: none;
}
</style>
是不是太多了,没事,接下来给大家解释一下重点
第三幕:约会 - 定位的艺术
为了让两颗心更靠近,我们需要懂点定位技巧:
.container {
position: absolute;
top: 50%;
left: 50%;
width: 238px;
/*被内容撑高就好*/
/* height: 238px; */
/*背景颜色大法*/
/* background-color: blue; */
/* 与top 50%,left %50 共同完成了是其达到舞台中央 */
transform: translate(-50%, -50%);
}
这里面可有不少门道:
- position: absolute 让我们的舞台可以自由移动
- top: 50%; left: 50% 把舞台中心移到屏幕正中(是盒子的左上角移至页面中心点,top从上往下,left是从左往右)
- transform: translate(-50%, -50%) 这个有点难理解,但记住它是居中的终极武器(意思是盒子往左移50%的盒子宽度,往上移%50的盒子高度,与top: 50%; left: 50%组合一起就能实现盒子再“舞台的居中”)
- margin-left 让右球害羞地往旁边挪了挪
为了更好的理解居中,我来画个图
什么是定位
我们来讲一下相对定位,和绝对定位
绝对定位
absolute 绝对定位 相对于最近的定位父元素 absolute 找到离它(管着它的)最近的position 不为static 的属性定位 直到body为止
简单来说就是参考的是距离最近的有定位的祖先元素,如果所有的祖先元素都没有设置定位,则参考body。
参考以下代码
<style>
*{
margin: 0;
padding: 0;
}
.box1{
width: 400px;
height: 400px;
border: 5px solid red;
margin: 100px auto;
position: relative;
}
.box2{
width: 300px;
height: 300px;
border: 5px solid green;
position: absolute;
left: 50px;
top: 50px;
}
.box3{
width: 200px;
height: 200px;
border: 5px solid blue;
position: absolute;
left: 50px;
top: 50px;
}
p{
width: 50px;
height: 50px;
background-color: gold;
position: absolute;
left: 50px;
top: 50px;
}
</style>
</head>
<body>
<div class="box1">
<div class="box2">
<div class="box3">
<p></p>
</div>
</div>
</div>
</body>
都是参考离最近的祖先元素的position,p参考.box3;.box3参考.box2;.box2参考.box1,假设.box3和.box2都没有不为static的position,p就会参考.box1
当把所有的position注释掉,只保留p的相对定位,就会参考整个body页面
相对定位
- 子元素相对它定位
其实就是绝对定位,去寻找祖先元素的定位
- 相对于自身的位置定位
参考自身原位置,所移动,定位
<style>
*{
margin: 0;
padding: 0;
}
div{
width: 300px;
margin: 100px auto;
}
p{
width: 100px;
height: 100px;
background-color: cyan;
margin: 5px;
}
p.current{
background-color: green;
position: relative;
left: 100px;
bottom: 100px;
}
</style>
</head>
<body>
<div>
<p></p>
<p class="current"></p>
<p></p>
</div>
</body>
相对于原来的位置所移动
第四章:让我们相遇
两个小球的div盒子标签,都是块级标签,那么我们如何使其在一行显示呢,介绍这个之前,我们先来简单的了解一下行内元素和块级元素
行内元素 span,i a inline 行内元素 不独占一行 不可以设置宽高
块级元素div p独占一行 可以设置宽高
这就需要通过我们的display属性了
display:相遇之法
display 切换行内块的格式化上下文能力 简单来说就是可以把块级元素设置为行内元素,行内元素设置为块级元素,还有两者兼具的行内块元素
- inline 行内 不可以设置宽高
<style>
div{
width: 200px;
height: 200px;
margin: 20px;
background-color: green;
display: inline;
}
</style>
</head>
<body>
<div>我是div1标签</div>
<div>我是div2标签</div>
可以看到我们的块级元素变成了行内块元素
- block 块级 独占一行 可以设置宽高
<style>
span {
background-color: pink;
padding: 20px;
display: block;
height: 100px;
width: 100px;
}
</style>
</head>
<body>
<span>文字1</span>
<span>文字2</span>
</body>
行内块元素变成了块级元素可以设置宽高行高
- inline-block 行内块元素 在一行 可以设置宽高
<style>
div{
width: 200px;
height: 200px;
margin: 20px;
background-color: green;
display: inline-block;
}
</style>
</head>
<body>
<div>我是div1标签</div>
<div>我是div2标签</div>
</body>
既可以设置宽高,又可以在一行内显示
第五章:樱桃小嘴,卡姿兰大眼
.eye {
width: 15px;
height: 15px;
border-radius: 50%;
border-bottom: 5px solid black;
position: absolute;
}
.mouth {
width: 30px;
height: 14px;
border-radius: 50%;
border-bottom: 5px solid black;
position: absolute;
bottom: -5px;
transform: translate(3px);
left: 0;
right: 0;
margin: auto;
}
border-radius: 50%; 把盒子改成圆形,由于我们并没有添加颜色背景,看不出来眼睛,这个时候我们来border-bottom: 5px solid black;添加了一个底边框,我们就能看到下边部分的圆弧形,相当于“卡姿兰大眼”,需要向上弯曲就设置为border-top5px solid black;
嘴巴也是同理
transform: translate(3px);
是一个 CSS 变换属性的应用,用于在网页上移动元素。不过,这里有一个小点需要注意:通常 translate 函数需要两个参数来分别指定在X轴(水平方向)和Y轴(垂直方向)上的位移值。当只提供一个参数时,这个值默认应用于X轴,而Y轴的位移则为0。
所以,当你写 transform: translate(3px);,实际上它等同于 transform: translate(3px, 0);,这意味着元素将仅沿水平方向向右移动3个像素,垂直位置不变。
尾声:写给前端开发者的启示
亲爱的开发者们,这个简单的故事背后蕴含着深刻的道理:
- 选择器就是缘分:ID和class的选择,就像人生中遇到的各种人,有些注定是过客,有些则是命中注定
- 定位是成长的过程:relative让我们看到自己的价值,absolute教会我们如何找到归宿
所以,下次当你写下一行CSS代码时,不妨想象这是一个正在发生的故事。毕竟,在这个数字时代,还有什么比创造美更浪漫的事呢?
祝所有代码都能成功运行,所有爱情都能圆满结局!