CSS的存在主要是在HTML已经搭建好网页基础结构的基础上,对网页的布局、样式进行设计。
如果把网页的各个区域看做一个个大的方块,布局的作用就是把这些方块分别摆放到合适的位置。也只有在大的布局结构设计好之后,我们才方便修改细节的样式。
标准流
标准流是网页布局最基本的方式。我们知道,HTML元素中有块级和行内不同元素,而标准流就是标签按照这些规定好的默认方式排列。
-
块级元素
div p h1-h6 ul ol dl ...- 特征:元素独占一行,从上到下的顺序排列
-
行内元素
span a i em ...- 特征:在一行中从左到右顺序排列,碰到父元素边缘则自动换行
总体来看,标准流在只能从左到右、从上到下排列,难以解决更复杂的布局需求。
浮动
语法
选择器 { float:属性值; }
| 属性值 | |
|---|---|
| none | 元素不浮动(即默认值) |
| left | 元素向左浮动 |
| right | 元素向右浮动 |
- 浮动元素会脱离标准流,不保留原来的位置。
- 浮动元素和行内块元素性质相似
主要应用场景
浮动布局主要可以用作多列布局,文字环绕等。随着Flex布局和Grid布局的出现,float在多列布局中的作用逐渐被替代,但是文字环绕仍然是最经典的应用场景。
<img src="https://via.placeholder.com/300x50" alt="示例图片" />
<p>
这是一些示例文本。文字将环绕在图片的右侧。当内容超过图片宽度时,文字会继续向下流动。你可以加入更多内容来观察效果。继续添加一些文本内容以展示文字环绕的效果。文字会自动环绕图片,直到内容结束或图片的宽度被填满......
</p>
body {
padding: 0 100px;
}
img {
float: right;
width: 300px;
height: 50px;
}
p {
margin: 10px;
background-color: #e0eff9;
}
通过这个示例,可以看出,浮动元素虽然脱离标准流,会压住标准流的盒子,但并不会压住标准流盒子里面的文字,可以以此性质实现文字环绕效果。但是定位 会压住下面标准流所有的内容。
定位
如果说浮动是在横向上让盒子进行更自由的排列,那么定位主要是调整元素到相对于别的元素的一个确定的位置,它提供了更多元、更灵活的解决方案。
定位模式
选择器 { position:属性值; }
| 属性值 | |
|---|---|
| static | 元素的默认定位方式,即无定位 |
| relative | 相对定位 |
| absolute | 绝对定位 |
| fixed | 固定定位 |
| sticky | 粘性定位 |
相对定位
应用场景:当你需要基于元素原本的位置进行微调时使用。
它移动位置时的参照点是自己原来的位置,并且还继续占有原来标准流的位置。
示例:
<div class="box1">相对定位 box</div>
<div class="box2">普通 box</div>
<div class="box2">普通 box</div>
.box1 {
height: 100px;
width: 300px;
position: relative;
top: 50px;
left: 30px;
background-color: #e0eff9;
}
.box2 {
margin-bottom:20px;
height: 100px;
width: 300px;
background-color: #e66e8e;
}
这里,relative使元素相对于其原始位置向下移动了50px、向右移动了30px。
绝对定位
应用场景:当你需要让元素相对于最近的已定位祖先元素进行定位(而非整个页面)时使用。常用于弹出层、浮动菜单等。
- 如果无祖先元素或者祖先元素没有定位,则会以浏览器为定位。
- 绝对定位不会占有原先的位置。
**示例:**制作一个浮动的提示框。
<div class="container">
<div class="box">点击我</div>
<div class="popup">我是一个弹出框</div>
</div>
.container {
position: relative; /* 设置容器为定位上下文 */
}
.popup {
position: absolute;
top: 50px;
left: 100px;
background-color: lightcoral;
padding: 20px;
display: none;
}
.box:hover + .popup {
display: block;
}
只有当鼠标悬停在.box上时,.popup会根据容器.container进行定位并显示。
固定定位
场景:当你需要让元素固定在浏览器窗口的某个位置,不随滚动条移动时使用。主要用于制作固定的导航栏或浮动按钮。
**示例:**固定页面顶部的导航栏。
<nav class="navbar">
<ul>
<li><a href="#">首页</a></li>
<li><a href="#">关于</a></li>
<li><a href="#">服务</a></li>
</ul>
</nav>
body {
height: 1800px;
background: linear-gradient(120deg, #e0c3fc 0%, #8ec5fc 100%);
}
.navbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
background-color: #333;
color: white;
padding: 10px 0;
text-align: center;
}
.navbar ul {
list-style: none;
padding: 0;
}
.navbar ul li {
display: inline;
margin: 0 15px;
}
.navbar ul li a {
color: white;
text-decoration: none;
}
可以看到,随着页面的滚动,背景颜色发生改变,而导航栏仍固定在页面顶部。
粘性定位
场景:当你希望元素在滚动时保持固定,直到达到父元素的边界时停止。适合用于制作固定在视口顶部的标题或导航栏的功能,尤其是在长篇文章的页面中,可以方便地保持一些重要的元素可见。
**示例:**粘性标题在滚动时保持在顶部。
<div class="content">
<h2 class="sticky">这是一个粘性标题</h2>
<img src="https://via.placeholder.com/300x50" alt="示例图片" />
</div>
body {
height: 1800px;
}
.content {
background-color: #e0eff9;
}
.sticky {
position: sticky;
top: 0;
background-color: lightyellow;
padding: 0px;
font-size: 20px;
}
sticky使得标题在滚动页面时会固定在顶部,直到遇到父元素的底部时停止。
在这里,**top: 0; **设置了粘性元素的顶部距离视口顶部的距离。这意味着,当页面滚动时,h2元素会在距离页面顶部0像素的位置固定,直到父容器的底部到达它的位置。
Flex布局
Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。
- 当我们为父盒子设置flex布局以后,子元素的float、clear、vertical-align属性将失效。
语法
Flex容器(Flex container):采用Flex布局的元素
容器成员(Flex item):Flex容器的所有子元素
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis),项目默认沿主轴排列。
我们可以通过给父元素添加flex属性,来控制其子元素的位置和排列方式。
-
父元素常见属性
- flex-direction:决定主轴的方向
- justify-content:设置主轴上子元素如何排列
- flex-wrap:设置子元素是否换行
- align-items:设置侧轴上子元素排列方式(单行)
- align-content:设置侧轴上子元素排列方式(多行)
- flex-flow:
flex-direction和flex-wrap属性的复合属性
-
子项常见属性
-
flex:子项分配剩余空间所占的份数
-
order:定义项目的排列顺序。数值越小,排列越靠前,默认为0。(和z-index不同)
-
align-self:控制子项自己在侧轴的排列方式(允许单个项目与其他项目不一样的对齐方式,可以覆盖align-items属性)
-
flex-grow:容器有剩余空间时子项的伸展能力
-
flex-shrink:容器空间不够时子项的收缩能力
-
flex-basis:子项没有伸展或收缩时的基础长度
-
适用场景
弹性盒子布局能够让容器内的项目根据容器大小动态调整尺寸。它比传统的布局方法(如浮动或定位)更简单、更直观,特别适用于那些需要动态排列和对齐元素的场景。
响应式的多列布局,列数根据屏幕宽度动态调整
<div class="card-container">
<div class="card">
<img src="https://via.placeholder.com/200" alt="商品1">
<h3>商品 1</h3>
<p>这是商品 1 的描述。</p>
</div>
<div class="card">
<img src="https://via.placeholder.com/200" alt="商品2">
<h3>商品 2</h3>
<p>这是商品 2 的描述。</p>
</div>
<div class="card">
<img src="https://via.placeholder.com/200" alt="商品3">
<h3>商品 3</h3>
<p>这是商品 3 的描述。</p>
</div>
<div class="card">
<img src="https://via.placeholder.com/200" alt="商品4">
<h3>商品 4</h3>
<p>这是商品 4 的描述。</p>
</div>
</div>
.card-container {
display: flex;
flex-wrap: wrap;
gap: 10px;
color:#000;
}
.card {
flex: 1 1 calc(25% - 10px); /* 每个卡片占容器宽度的四分之一 */
background-color: #f7f7f7;
box-sizing:border-box;
padding: 20px;
border: 1px solid #ccc;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
text-align: center;
}
.card img {
width: 100%;
height: auto;
border-radius: 8px;
}
@media (max-width: 768px) {
.card {
flex: 1 1 calc(50% - 20px); /* 屏幕小于768px时变成两列 */
}
}
@media (max-width: 480px) {
.card {
flex: 1 1 100%; /* 屏幕小于480px时变成单列 */
}
}
效果图: