11_CSS元素定位

124 阅读5分钟

CSS元素定位

float 属性可以指定一个元素应沿其容器左侧或右侧放置,允许文本和内联元素环绕它

float 属性最初只用于在一段文本内浮动图像, 实现文字环绕的效果,也就是实现图文环绕效果

但是早期的CSS标准中并没有提供好的左右布局方案, 因此在一段时间里面它成为网页多列布局的最常用工具

但如今出现flex布局和grid布局后,已经很少再去使用浮动进行布局和定位

绝对定位、浮动都会让元素脱离标准流,以达到灵活布局的效果

可以通过float属性让元素产生浮动效果

说明
none不浮动,默认值
left向左浮动
right向右浮动

浮动规则

  1. 元素一旦浮动后, 脱离标准流

    • 朝着向左或向右方向移动,直到自己的边界紧贴着包含块(一般是父元素)或者其他浮动元素的边界为止
    • 如果元素是向左(右)浮动,浮动元素的左(右)边界不能超出包含块的左(右)边界
    • 定位元素会层叠在浮动元素上面

Snipaste_2022-10-21_22-04-39.png

Snipaste_2022-10-21_22-05-57.png

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      margin: 0;
      overflow: 0;
    }

    .box {
      width: 200px;
      height: 200px;
      background-color: orange;
      margin: 0 auto;
      padding: 10px;
    }

    .item1, .item2 {
      background-color: #f00;
    }

    .item1 {
      /* 定位脱离标准流 */
      /* position: fixed;
      left: 0;
      top: 10px; */

      /* 脱离标准流 */
      float: left;
      background-color: #0f0;
    }

    .item2 {
      float: right;
    }
  </style>
</head>
<body>
  
  <div class="box">
    <div class="item1">1</div>
    <div class="item2">2</div>
  </div>

</body>
</html>


  1. 浮动元素之间不能层叠

    • 如果一个元素浮动,另一个浮动元素已经在那个位置了,后浮动的元素将紧贴着前一个浮动元素
    • 如果水平方向剩余的空间不够显示浮动元素,浮动元素将向下移动,直到有充足的空间为止
  2. 浮动元素不能与行内级内容层叠,行内级内容将会被浮动元素推出

    • 这里指代的行内级元素除了行内级元素、inline-block元素,还包括块级元素的文字内容
    • 我们可以利用这个特性来实现图文环绕效果
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>

    .container {
      width: 500px;
      height: 500px;
      background-color: orange;
    }

    .item {
      background-color: #f00;
      width: 100px;
      height: 100px;

      /* 三个全部向左浮动: 都会脱离标准流 */
      /* float: left; */
    } 

    .box1 {
      float: left;
      background-color: #0f0;
      margin-left: 20px;
    }

    .box2 {
      float: left;
    }

    .box3 {
      float: left;
    }

    .box4 {
      width: 200px;
      height: 100px;
      background-color: purple;

      float: left;
    }
  </style>
</head>
<body>
  
  <!-- 浮动元素之间不能层叠 -->
  <div class="container">
    <div class="item box1">1</div>
    <div class="item box2">2</div>
    <div class="item box3">3</div>

    <div class="item box4">4</div>
  </div>

</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      width: 1000px;
      height: 400px;
      background-color: orange;
    }

    .box strong {
      float: left;
      /* position: fixed;
      left: 0; */
    }
  </style>
</head>
<body>
  
  <div class="box">
    <span>我是span元素</span>
    <strong>我是strong元素</strong>
    <i>我也是i元素</i>
    <div>我是普通的内容</div>
  </div>

</body>
</html>
  1. 行内级元素、inline-block元素浮动后,其顶部将与所在行的顶部对齐

    • 也就是说浮动只能进行左浮动和右浮动
    • 无法实现上浮动和下浮动
    • 对于位于同一行的多个浮动元素而言,他们之间的对齐方式是顶部对齐
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      width: 500px;
      background: orange;
    }

    .box img {
      width: 300px;
      float: left;
    }
  </style>
</head>
<body>

  <div class="box">
    <img src="../images/kobe01.jpg" alt="">
    马俊宝从小热爱摄影,人生中第一部照相机是1978年买的海鸥相机,当时花了他将近半年的积蓄。从拿着相机的那一刻起,他就有一个梦想:把新疆最美的风景记录下来,让更多人看到。这个梦想在他年过半百的时候终于实现了。他的作品经常有爆款,不少视频有上亿观看量。留言里很多人赞叹新疆太美了,也有人不相信这些湖泊草原在新疆。马俊宝很开心:“我想做新疆美景的展示者,把新疆最美的一面展现给大家。”
    为了拍美食,张振新几乎跑遍了全疆,短视频的题材有大家熟悉的,也有粉丝留言推荐的,还有在网上搜索看到的。他会为了拍一种美食,乘飞机转汽车,辗转上千公里。从北疆的糖洋芋、土鸡焖饼子,再到南疆的鸽子汤、烤鱼、烤鸽子,每到一地,张振新都会和当地人聊天,听听当地人会去哪家老字号。他拍的店大多虽不起眼,但都是味道正宗、历久弥新的“宝藏店”。
  </div>

</body>
</html>

我们可以使用浮动来解决行内级元素、inline-block元素的水平间隙问题


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      /* font-size: 0; */
      /* display: flex; */
    }

    span {
      background-color: orange;
      /* font-size: 16px; */

      /* float: left;
      margin-right: 5px; */
    }
  </style>
</head>
<body>
  <!-- 
    将多个行内级元素中间的空格(间隙)去除的方法
      1. 删除换行符(不推荐)
      2. 将父级元素的font-size设置为0, 但是需要子元素设置回来
      3. 通过子元素(span)统一向一个方向浮动即可
      4. flex布局(还没有学习)
   -->
  
  <div class="box">
    <span>aaa</span>
    <span>bbb</span>
    <span>ccc</span>
  </div>

</body>
</html>
解决方法说明备注
去除空格和换行不利于代码的可维护性和可读性不推荐
将父元素的font-size设置为0font-size是个继承属性 这就意味着在子元素中,需要将font-size的值进行重置 否则所有元素的font-size皆会为0,页面什么都不显示不推荐
将元素按照相同的方向进行浮动浮动元素之间没有间隙,且各个浮动元素之间不会覆盖
为元素开启定位通过调整元素的定位来移除元素间的空格
使用margin的负值通过margin的负值
设置父元素的display为flex开启BFC推荐

浮动结合margin负值模拟nth-child的效果

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    span, strong {
      float: left;
    }

    span {
      background-color: #f00;
    }

    strong {
      background-color: #0f0;
      margin-left: -10px;
    }
  </style>
</head>
<body>
  
  <span>我是span元素</span>
  <strong>我是strong元素</strong>

</body>
</html>

基本案例

清除浮动

浮动元素由于脱离了标准流,变成了脱标元素,所以不再向父元素汇报高度

所以父元素计算总高度时,就不会计算浮动子元素的高度,导致了高度坍塌的问题

解决父元素高度坍塌问题的过程,一般叫做清浮动(清理浮动、清除浮动)

也就是让父元素计算总高度的时候,把浮动子元素的高度算进去

clear

我们清除浮动最常见的方式是使用clear属性

clear 属性可以指定一个元素是否必须移动(清除浮动后)到在它之前的浮动元素下面

说明
none默认值,无特殊要求
left要求元素的顶部低于之前生成的所有左浮动元素的底部 --- 清除左浮动
right要求元素的顶部低于之前生成的所有右浮动元素的底部 --- 清除右浮动
both要求元素的顶部低于之前生成的所有浮动元素的底部 --- 清除左浮动和右浮动
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .content {
      width: 1190px;
      margin: 0 auto;
      background: #f00;
    }

    .wrapper {
      margin-right: -10px;
    }

    .item {
      width: 290px;
      background-color: purple;
      margin-bottom: 10px;

      float: left;
      margin-right: 10px;
    }

    .item.left {
      height: 370px;
    }

    .item.right {
      height: 180px;
    }

    /* 其他的内容 */
    .other {
      height: 100px;
      background: #0f0;
    }

    .line {
      /* height: 10px; */
      /* background: blue; */
      clear: both;
    }

    /* 最终的解决方案 */
    .clear_fix::after {
      content: "";
      clear: both;
      /*
        默认伪元素是行内级非替换元素
        默认的宽度为内容的宽高
      	所以默认是0px * 0px 并无法起到占位清除浮动的作用
      	所以需要设置display: block; 
      	或 display: inline-block; + width: 100%;
      */
      display: block;

      /* 浏览器兼容 */
      visibility: hidden;
      height: 0;
    }

    .clear_fix {
      /* IE6/7 */
      *zoom: 1;
    }
  </style>
</head>
<body>
  
  <!-- 因为所有的后代item元素都是浮动的, 脱离标准流 -->
  <!-- 不会向父元素汇报高度, 那么content元素压根就没有高度 -->
  <div class="content">
    <div class="wrapper clear_fix">
      <div class="item left"></div>
      <div class="item left"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>

      <!-- <div class="line"></div> -->
    </div>
  </div>
  
  <div class="content">
    <div class="wrapper clear_fix">
      <div class="item left"></div>
      <div class="item left"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>
      <div class="item right"></div>

      <!-- <div class="line"></div> -->
    </div>
  </div>

  <!-- 我认为content没有高度, 那么我们就会直接在上面显示 -->
  <div class="other"></div>

</body>
</html>

布局方案总结

Snipaste_2022-10-21_22-21-46.png