CSS基础(2)
容器
盒模型
在网页布局中,其实都是通过一个一个盒子搭建而成的。
基础
盒子通过margin
外边距、padding
内边距、border
边框、context
元素内容组成。
margin
外边距是元素和元素之间的距离padding
内边距是边框和元素内容之间的距离border
是环绕元素一周的边框context
也就是内容如文本、图像等
效果图:
浏览器默认
盒子的最终高度等于top border + top padding + height + bottom padding + bottom border
盒子的最终宽度等于left border + left padding + width + right padding + right border
练习
下面实现了一个简单盒模型的代码:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>盒模型</title>
<style>
.box {
width: 200px;
height: 200px;
padding: 10px;
border: 1px solid #000;
margin: 20px;
background-color: aquamarine;
}
</style>
</head>
<body>
<div class="box">我是盒模型</div>
</body>
</html>
打开浏览器,使用f12
打开开发工具,使用选择案例选择元素,浏览器可以看见该元素经过计算后的样式。
效果图:
效果图:
可以看到该div
元素的最终width
、height
等于211px
,同时可以发现背景颜色占据了盒模型的高度和宽度(背景图片也是)
设置一张背景图片:
css
.box {
width: 200px;
height: 200px;
padding: 10px;
border: 1px solid #000;
margin: 20px;
background-image: url("../img/test1.jpeg");
background-position: center;
background-size: cover;
}
内边距与外边距
padding 内边距
padding
内边距是内容跟边框之间的距离,属性名padding
或padding-方位名词
css
padding: 10px; // 表示该盒子的四个方向内边距都为10px
padding-top: 10px; // 表示盒子的上内边距为10px
padding-bottom: 20px;
padding-right: 10px;
padding-left: 10px;
示例给一个盒子添加内边距:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>内边距padding</title>
<style>
.container {
width: 300px;
height: 300px;
background-color: rebeccapurple;
}
.box {
width: 100px;
height: 100px;
padding-top: 10px;
padding-bottom: 10px;
padding-left: 20px;
padding-right: 20px;
background-color: green;
}
</style>
</head>
<body>
<div class="container">
<div class="box"></div>
</div>
</body>
效果图:
属性值简写
可以通过简写方式减少CSS代码量
示例 | 含义 |
---|---|
padding: 10px; |
四个方向内边距均为10px |
padding: 10px 20px 30px 40px; |
上右下左(顺时针) |
padding: 10px 20px 30px; |
上10px、左右20px、下30px |
padding: 10px 20px; |
上下10px、左右20px |
使用简写的方式对上面代码进行更改
css
.box {
width: 100px;
height: 100px;
/* 上下10px 左右20px */
padding: 10px 20px;
background-color: green;
}
练习
设置一个小按钮
思路:给1个button
元素,添加内边距,设置文字垂直居中。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>按钮</title>
<style>
.btn {
background-color: blueviolet;
padding: 10px 20px;
color: white;
border: none; /*去除边框线*/
font-size: 20px;
line-height: 20px; /*垂直居中单行文字*/
}
</style>
</head>
<body>
<button class="btn">点击我</button>
</body>
</html>
效果图:
margin 外边距
margin
设置元素与其他元素之间的距离(两个盒子之间的距离),语法跟padding
一致。
auto值
不过margin
可以设置一个auto
值,让浏览器自己选择一个合适的外边距,在某些情况下实现元素居中。
实现元素水平居中margin: 0px auto;
css
.box {
width: 100px;
height: 100px;
margin: 0px auto;
/* 上下10px 左右20px */
padding: 10px 20px;
background-color: green;
}
效果图:
margin
不能设置元素垂直居中,因为在块级元素和文档流中,块级元素默认是占父容器的整个宽度,高度是由内容来确定的,没有剩余内容分配margin
,因此只能设置水平居中。
清除默认样式
box-sizing
box-sizing
设置计算一个元素的高度和宽度,在之前知道盒模型的总宽度和总高度的计算方式,其实就是box-sizing: context-box;
,设置一个元素高度宽度需要减去padding
和border
导致需要手动计算。
box-sizing: border-box;
改变默认方式,使得总宽度=width
,总高度=height
,也就是说padding
、border
包含在width
或height
中。
效果图:
清除默认边距
有些元素会自带默认的边距,且各个浏览器可能默认的设置不同,因此需要清除默认来达到效果统一。
css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
由图可见元素的大小100*100
且包含了内边距的大小。
效果图:
相关问题
元素溢出
当盒子的大小不够元素展示时会发生溢出,控制元素溢出的显示方式由overflow
属性控制,也可也设置x轴overflow-x
,y轴overflow-y
。
hidden
溢出隐藏scorll
溢出滚动(无论是否溢出,都显示滚动条位置)auto
溢出滚动(溢出才显示滚动条位置)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>溢出</title>
<style>
.box {
width: 200px;
height: 200px;
background-color: darkcyan;
}
</style>
</head>
<body>
<div class="box">...省略</div>
</body>
</html>
效果图:
当元素内容超过父容器大小时产生溢出,设置overflow: hidden;
外边距合并
垂直排列的两个元素的上下外边距会发生合并,以最大值为最终元素距离。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>外边距合并</title>
<style>
.container {
background-color: aqua;
width: 200px;
padding: 20px;
}
.container > div {
width: 200px;
height: 200px;
background-color: brown;
}
.top {
margin-bottom: 50px;
}
.bottom {
margin-top: 30px;
}
</style>
</head>
<body>
<div class="container">
<div class="top"></div>
<div class="bottom"></div>
</div>
</body>
</html>
这里在父元素中有两个盒子,其中top
盒子的下外边距为50px
,bottom
盒子的下外边距为30px
,最终页面两元素的距离以50px
为准。
效果图:
外边距塌陷
父子级元素,子元素设置了上、下外边距,父元素没有设置边框、内边距分隔,导致父子元素的外边距发生合并,从而导致父元素整体平移,且没有达到子元素与父元素原本想象的距离。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>外边距塌陷问题</title>
<style>
body {
background-color: darkgray;
}
.father {
width: 300px;
height: 300px;
background-color: aqua;
}
.son {
width: 200px;
height: 200px;
/* 设置上外边距 */
margin-top: 50px;
background-color: brown;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
</html>
效果图:
解决办法:
- 给父容器添加
padding
用来设置子与父的距离,取消子元素的margin
- 父容器设置
border
来分隔 - 使用
overflow:hidden
创建一个格式化上下文BFC
(待解释) - 使用
伪类选择器
给父容器添加一个空的子元素并设置样式(这个方法就是回到了相邻元素的外边距,不太建议使用)
设置父元素的padding-top
,去掉子元素的margin
来解决:
元素类型
块级元素
块级元素默认独占一行(拥有父元素100%
宽度),在垂直方向一个接一个摆放,盒模型完全适应块级元素。
块级元素有:
css
body,main,header,footer,section,nav,aside,div,h1-h6
p,ul,ol,li等
css属性 display: block
行内元素
行内元素只占本身内容空间,一行可以拥有多个行内元素,不能设置高度盒宽度,只能设置水平方向的内和外边距(垂直方向不起作用,垂直内边距只有视觉效果并没有创造新的空间)
行内元素有:
css
a,img,strong,em,input,span等
css属性 dispaly: inline
行内块元素
行内块元素看起来像行内元素,但拥有块级元素的盒模型特性(设置内外边距、高宽度)
常用样式
边框
border
属性设置元素的边框,语法border: 宽度 风格 颜色;
,如果只想设置某一方向跟padding
一样添加方位即可如border-bottom
。
css
border: 5px solid red;
效果图:
圆角
border-radius
设置元素的外边框圆角,属性值数字值px / %比
代表圆角半径,可以像padding
一样属性值简写。
圆形效果
给正方形盒子设置圆角等于宽度的一半 / 50%
。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>边框圆角</title>
<style>
.box {
width: 200px;
height: 200px;
background-image: url("../img/test1.jpeg");
background-position: center;
background-size: cover;
border-radius: 50%;
border: 2px solid red;
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
效果图:
胶囊效果
给长方形盒子设置圆角等于盒子高度的一半。
效果图:
阴影
box-shadow
给元素添加阴影效果,属性值x轴偏移量 y轴偏移量 模糊半径 扩散半径 颜色 内外阴影
,默认是外阴影(内阴影 inset
)
卡片效果
遇到问题:多个行内元素的时候可能之间会有空格;解决方法:设置父元素font-size:0
再设置子元素的字号大小
下面代码:图片自带圆角(截图),所以没有给图片容器设置圆角
代码:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>盒子阴影</title>
<style>
.box {
box-sizing: border-box;
width: 320px;
padding: 20px;
margin: 30px auto;
/* border: 2px solid brown; */
box-shadow: 0px 0px 10px 0 rgb(0, 0, 0, 0.2);
}
.box__img {
width: 280px;
height: 158px;
}
.box__img > img {
width: 100%;
height: 100%;
}
.header-four {
margin: 10px 0;
font-size: 16px;
color: #333;
}
.box__desc > span {
font-size: 12px;
color: #999;
display: inline-block;
margin: 0 5px 0 0;
}
.focus {
/* !imortant提升优先级 */
color: white !important;
padding: 2px 4px;
background-color: orange;
border-radius: 2px;
}
</style>
</head>
<body>
<div class="box">
<div class="box__img">
<img src="../img/msk.jpg" alt="" />
</div>
<h5 class="header-four">全程高能! SpaceX星舰第三次综合试飞发射全过程</h5>
<div class="box__desc">
<span class="focus">已关注</span>
<span>柚子字幕组</span>
<span>10小时前</span>
</div>
</div>
</body>
</html>
效果图:
布局
BFC
BFC
格式化上下文,是盒子按照一定的规则进行排布和定位;
BFC 特性
- 内部的盒子会在垂直方向一个接一个地放置
- 属于同一个BFC的两个相邻盒子的垂直边距会重叠,以边距的最大值作为两者的距离
- BFC 区域不会于与浮动元素重叠
- BFC 可以包含浮动的元素,浮动元素参与计算高度,同时也可也达到清除浮动的效果
- BFC 是一个独立的布局单元,内部的元素不会影响外部元素
创建 BFC 的方式
- 根元素或包含根元素的元素。
- 浮动元素(
float
属性不为none
)。 - 绝对定位元素(
position
为absolute
或fixed
)。 display
属性值为inline-block
、table-cell
、table-caption
、flex
、inline-flex
等的元素。overflow
属性值不为visible
的元素。
float 浮动
float
float
CSS 属性指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。该元素从网页的正常流动(文档流)中移除;
具有以下特点:
- 类似不存在网页中,围绕的元素任然在之前的位置上
- 其容器不会自动根据元素调整高度,会产生高度崩塌
案例
可以通过下面代码,发现许多有意思的点:
- float-box 和 normal-box 发生重叠并覆盖展示,normal-box 的文字依然环绕在 float-box 周围;这是因为
float
会从文档流中移除(类似不存在),normal-box按正常的文档流展示; - 当删除 normal-box 元素时,container 的容器高度不会被撑开(崩塌);
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>BFC Example</title>
<style>
.container {
width: 300px;
border: 1px solid black;
}
.float-box {
float: left;
width: 100px;
height: 100px;
background-color: lightblue;
margin-right: 10px;
}
.normal-box {
width: 180px;
height: 100px;
background-color: lightgreen;
}
</style>
</head>
<body>
<div class="container">
<div class="float-box">Float Box</div>
<div class="normal-box">Normal Box</div>
</div>
<p>
This text is outside the container and should not be affected by the
floating box inside the container.
</p>
</body>
</html>
效果图:
清除浮动
clear
属性指定一个元素是否必须移动 (清除浮动后) 到在它之前的浮动元素下面,clear
属性适用于浮动和非浮动元素。
在父元素的最后一个子元素添加clear:both;
清除浮动;
可以发现:
- Normal Box 换到下一行进行展示了
- 父容器的高度计算了 Float Box 的高度
css
.normal-box {
width: 180px;
height: 100px;
background-color: lightgreen;
clear: both;
}
效果图:
给父元素添加一个.clearfix::after
清除浮动伪元素,可以发现清除浮动后父元素高度可以被撑开;
清除浮动方法
- 1、给父元素添加清除浮动
- 2、给父元素添加
overflow:hidden
css
<style>
.container {
width: 300px;
border: 1px solid black;
}
.float-box {
float: left;
width: 100px;
height: 100px;
background-color: lightblue;
}
/*暂时将正常盒子的css效果删除,目的是为了体现清除浮动后父元素高度可以被撑开*/
/* .normal-box {
width: 180px;
height: 100px;
background-color: lightgreen;
clear: both;
} */
.clearfix::after {
content: "";
display: block;
clear: both;
}
</style>
效果图:
案例练习
小米商城产品列表练习 float 布局
卡片代码
HTML 代码
html
<div class="card">
<a class="card__link">
<img
class="card__img"
src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/f2a277341a09a63bbb7bba12d154c4e6.png?thumb=1&w=200&h=200&f=webp&q=90"
alt=""
/>
<h3 class="heading-thrid">Xiaomi 14 Ultra</h3>
<p class="card__desc">
徕卡全明星四摄 | 双向卫星通信 | 小米澎湃OS 晓龙999旗舰芯片
</p>
<p class="card__price">6499起</p>
</a>
</div>
CSS 代码
css
.card {
width: 234px;
height: 300px;
margin: 30px auto 0;
background-color: white;
}
.card__link {
display: block;
padding: 20px 0;
}
.card__img {
width: 160px;
height: 160px;
display: block;
margin: 0 auto 18px;
}
.heading-thrid {
font-size: 14px;
font-weight: 400;
margin-bottom: 10px;
}
.card__desc {
font-size: 12px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
margin: 0 10px 10px;
}
.card__price {
color: rgb(209, 85, 13);
font-size: 14px;
margin: 0 10px 10px;
}
float 布局代码
HTML 代码
html
<div class="container">
<div class="left">
<img src="../img/小米商城.jpg" alt="" />
</div>
<div class="right">
<ul>
li*8...
</ul>
</div>
</div>
CSS 代码
css
.container {
width: 1226px;
height: 628px;
margin: 50px auto;
}
.left {
float: left;
margin-right: 14px;
width: 234px;
height: 628px;
}
.left > img {
width: 100%;
height: 100%;
}
.right {
/* overflow: hidden; */
float: right;
width: 978px;
height: 628px;
}
.card {
/* 设置浮动 */
float: left;
margin-right: 14px;
margin-bottom: 14px;
width: 234px;
height: 300px;
background-color: white;
}
.card:nth-child(4n) {
margin-right: 0;
}
效果图:
易错点
- right 容器不写宽度、高度,导致手机产品在第二行,这是因为不设置div的大小默认为父容器的宽度,可以使用
overlow: hidden
来达到效果,因为它可以计算宽度和高度;
定位
CSS position
属性用于指定一个元素在文档中的定位方式。top、bottom、right、left
属性则决定了该元素的最终位置;
定位元素的显示层级比普通元素高,无论什么定位,显示层级都是一样的;
规则:
- 定位元素会盖在普通元素之上
- 都发生定位的两个元素,后写的元素会盖在先写的元素之上
- 可以通过
z-index
属性设置定位元素的层级,改变默认的显示规则
相对定位
position: relative
元素相对于自己原来的位置,不会脱离文档流,元素位置的变换只是视觉效果上的变换,不会对其他元素产生任何影响;
案例
可以发现.two
只是视觉效果上发生变换,文档流位置并未发生改变;
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>定位</title>
<style>
div {
width: 200px;
height: 200px;
}
.one {
background-color: green;
}
.two {
background-color: red;
position: relative;
top: 50px;
}
.three {
background-color: blue;
}
</style>
</head>
<body>
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</body>
</html>
效果图:
绝对定位
position: absolute
元素会被移除正常文档流,并不为元素预留空间,元素相对于最近的非 static 定位祖先元素进行定位;绝对定位的元素可以设置外边距,但不会与其他边距合并;
绝对定位通常用于在特别的位置展示元素,还可以实现元素的水平垂直居中;
给.two
添加一个子元素,并设置绝对定位,让子元素相对父元素水平垂直居中;
css
.son {
position: absolute;
left: 50%;
top: 50%;
/* 也可也使用负margin,但是一般不推荐 */
/* margin-left: -50px;
margin-top: -50px; */
transform: translate(-50%, -50%);
width: 100px;
height: 100px;
background-color: gray;
}
效果图:
固定定位
position: fixed
元素会被移除正常的文档流,并不会为元素预留空间,而是通过指定元素相对于屏幕视口的位置来指定元素位置,元素的位置在屏幕滚动时不会改变;
通常用于固定导航栏、回到顶部按钮、侧边广告栏;
效果图:
举例小米官网
实现一个普通的固定导航栏 HTML:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Fixed Navigation Bar</title>
<style>
body {
margin: 0;
}
.navbar {
position: fixed;
top: 0;
width: 100%;
background: #333;
color: white;
padding: 10px;
text-align: center;
z-index: 99;
background-color: rgba(0, 0, 0, 0.85);
}
.content {
/* 留出导航栏的空间 */
/* margin-top: 60px; */
height: 2000px; /* 模拟大量内容 */
background: #f5f5f5;
}
</style>
</head>
<body>
<div class="navbar">Fixed Navbar</div>
<div class="content">Content goes here...</div>
</body>
</html>
效果图:
粘性定位
元素根据正常文档流进行定位,然后相对它的最近滚动祖先进行定位;
粘性定位可以被认为是相对定位和固定定位的混合。元素在跨越特定阈值前为相对定位,之后为固定定位。
通常用于固定导航栏、侧边广告栏、表格头部
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sticky Navigation Bar</title>
<style>
body {
margin: 0;
}
.navbar {
position: sticky;
top: 0px;
background: #333;
color: white;
padding: 10px;
text-align: center;
}
.content {
height: 2000px; /* 模拟大量内容 */
background: #f5f5f5;
}
</style>
</head>
<body>
<div class="navbar">Sticky Navbar</div>
<div class="content">Content goes here...</div>
</body>
</html>
实现小米官网导航栏
目标效果
效果图:
分析
可以分为3块区域,左边logo
、中间导航区、右侧登陆区,可以使用 float 布局实现效果;
要点:
- float 三栏布局,midden 要放最后,设置一个 BFC 或者 设置左右外边距
- 实现垂直居中,行内元素 行高 line-height 等于 容器高度即可垂直居中
- 实现水平居中,行内元素使用 text-align
- 绝对定位实现块级元素的垂直水平居中
代码实现
代码:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>小米导航栏</title>
<style>
/* 清除默认样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-size: 14px;
font-family: sans-serif;
font-weight: 500;
color: #fff;
}
ul,
li {
list-style: none;
}
a {
text-decoration: none;
color: inherit;
cursor: pointer;
}
/* 布局及内容 */
.container {
width: 1044px;
height: 65px;
background-color: black;
margin: 20px auto;
text-align: center;
/* line-height=height实现文字垂直居中 */
line-height: 65px;
}
.left {
float: left;
width: 100px;
}
.left a {
/* 设置为块级元素,并设置高度,因为不会被绝对元素撑开 */
display: block;
height: 65px;
position: relative;
}
.left img {
/* 垂直居中 */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.right {
float: right;
width: 200px;
}
.right span {
display: inline-block;
margin: 0 20px;
}
.middle {
/* 形成一个BFC */
overflow: hidden;
/*也可以这样 margin-left: 100px; margin-right: 200px; */
/* 或者设置float设置宽度也行 */
}
.middle li {
/* 可以设置为inline-block 这样受text-align:center影响 */
display: inline-block;
margin-right: 15px;
}
.middle li:last-child {
margin-right: 0;
}
</style>
</head>
<body>
<div class="container">
<div class="left">
<a href="#">
<img src="../img//logo.jpg" alt="" />
</a>
</div>
<div class="right">
<a href="#">登陆</a>
<span>|</span>
<a href="#">注册</a>
</div>
<div class="middle">
<ul>
<li><a href="#">小米官网</a></li>
<li><a href="#">小米商城</a></li>
<li><a href="#">小米澎拜OS</a></li>
<li><a href="#">小米汽车</a></li>
<li><a href="#">小米影像</a></li>
<li><a href="#">云服务</a></li>
<li><a href="#">IoT</a></li>
<li><a href="#">有品</a></li>
<li><a href="#">小爱开发平台</a></li>
<li><a href="#">Location</a></li>
</ul>
</div>
</div>
</body>
</html>
效果图: