CSS 定位

之前讨论的盒模型, 其作用就是为了控制元素的尺寸的. 接着我们便是要来了解元素的位置, 即左右布局.

在早期的时候, 为了实现盒子的左右布局, 会用到浮动, float: left/right, 当元素浮动时, 会脱离文档流, 根据 float 左或者右移, 直到它的边界碰到父元素内边界或者另一浮动元素的边界为止.

浮动的出现是为了当时实现 文字环绕 的效果, 只是后来大家误用来做布局. 用它会带来很多的副作用, 如高度塌陷, 后面处理上都要进行清除浮动处理. 自 flex 即弹性布局出现以后, float 就可以被替代了, 因此也不再多讲.

定位 position

在 css 中, position 属性用于指定一个元素在文档中的定位方式, 其中 top, right, bottom, left 属性则决定元素的最终位置.

  • static: 不加任何定位的默认样式
  • relative: 相对定位, 不脱离文档流, 相对与自身进行偏移, 原点坐标在盒子左上角
  • absolute: 绝对定位, 要脱离文档流, 相对祖先元素进行偏移,若祖先非 static, 则对应视口, 滚动条影响
  • fixed: 固定定位, 要脱离文档流, 类似绝对定位, 但会固定在可视区中, 滚动条不影响
  • sticky: 粘性定位

相对定位 relative

  • 相对定位元素, 是在文档中的正常位置, 偏移给定的值
  • 不影响其他的布局
  • 相对于自身进行偏移
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>relative</title>
  <style>
    .box1 {
      width: 100px;
      height: 100px;
      background-color: pink;
    }

    .box2 {
      width: 100px;
      height: 100px;
      background-color: skyblue;
      position: relative;
      /* 以左上角为原点, 向右移动 100px */
      left: 100px;
      /* 仍以左上角为原点, 向下移动 100px */
      top: 100px;
      
    }

    .box3 {
      width: 100px;
      height: 100px;
      background-color: gold;
    }
  </style>
</head>
<body>
  <div class="box1">1</div>
  <div class="box2">2</div>
  <div class="box3">3</div>
</body>
</html>

绝对定位 absolute

  • 绝对定位元素会脱离文档流, 并不占据空间

  • 具备内联盒子特性, 宽度由内容决定

  • 具备块级盒子特性, 支持所有样式

  • 相对于最近的非 static 祖先元素定位, 当祖先不存在, 则相对于可视区定位

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>absolute</title>
  <style>
    body {
      height: 2000px;
      position: relative;
    }
    .box1 {
      width: 500px;
      height: 500px;
      border: 1px solid #000;
      margin: 200px;
      /* 当祖先元素定位是非 static时, 则对应安排, 优先参考最近的  */
      position: relative;
    }

    .box2 {
      width: 100px;
      height: 100px;
      background-color: pink;
      position: absolute;
      /* 若祖先无别的定位布局, 则默认可视区, 即浏览器左上角 */
      top: 0;
      right: 0;
    }
  </style>
</head>
<body>
  <div class="box1">
    <div class="box2"></div>
  </div>
</body>
</html>

这里就产生一个高频常用的定位技巧: 子绝父相. 即给父元素进行相对定位, 然后子元素进行绝对定位, 这样通过对子元素的 top, left, right, bottom 的控制就是相对于父元素来说的啦.

    .box1 {
      width: 500px;
      height: 500px;
      border: 1px solid #000;
      margin: 200px;
      /* 父元素: 相对定位, 啥也不写  */
      position: relative;
    }

    .box2 {
      width: 100px;
      height: 100px;
      background-color: pink;
      position: absolute;
      /* 子元素: 绝对定位, 其top,left ... 都是参考父元素来的哈 */
      top: 50px;
      left: 20px;
    }

<body>
  <div class="box1">
    <div class="box2"></div>
  </div>

固定定位 fixed

  • 固定定位类似绝对定位, 会脱离文档流, 但会固定在可视区中, 不受滚动条影响
  • 具备内联盒子特性, 宽度由内容决定
  • 具备块级盒子特性, 支持所有样式
  • 固定定位不受祖先元素影响, 就固定在浏览器用户可视区
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>fixed</title>
  <style>
    body {
      height: 2000px;
      position: relative;
    }
    .box1 {
      width: 500px;
      height: 500px;
      border: 1px solid #000;
      margin: 200px;
      position: relative;
    }

    .box2 {
      width: 100px;
      height: 100px;
      background-color: pink;
      position: fixed;
      /* 固定定位, 相对于用户可视区来说的, 不管祖先元素是否有其他定位 */
      top: 0;
      left: 0;
    }
  </style>
</head>
<body>
  <div class="box1">
    <div class="box2"></div>
  </div>
</body>
</html>

粘性定位 sticky

  • sticky 约等于 relative + fixed 的混合, 元素跨定阈值前是相对定位, 超过则为固定定位
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>fixed</title>
  <style>
    body {
      /* 给 body 设置高就会出现滚动条 */
      height: 2000px;
      width: 200px;
      position: relative;
      
    }
    div {
      background-color: pink;
      position: sticky;
      /* 网上滚动, 一开始是相对定位, 一定距离可视区 50px时, 它就固定住啦 */
      top: 50px;
    }
  </style>
</head>
<body>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
  <div>这是一个粘性盒子</div>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
  <p>pppppppppppppppppppp</p>
</body>
</html>

最常用的场景是固定网页导航栏, 或者说表格固定首行首列等.

display 属性

在 css 中, display 属性表示 "显示框类型", 即不同的盒模型.

  • display-outside
    • block, 将元素转为块级盒子
    • inline, 将元素转为内联盒子
    • inline-block, 对外表现内联, 对内表现块级
  • display-inside
    • flex, 子元素弹性布局
    • grid, 子元素网格布局
    • table, 子元素表格布局的块盒子
    • ...
  • disply-listitem
    • list-item, 生成一个容纳内容和单独列表内元素的块级盒子
  • disply-internal -- 不咋用
  • display-box -- 不咋用
  • dispaly-legacy
    • inline-block, 对外表现内联, 对内表现块级
    • inline-flex, 对外表现内联, 对子元素表现弹性
    • inline-grid, 对外表现内联, 对子元素表现网格
  • display-global -- 不咋用

值得关注的一种现象是 inline-block, 既具备内联盒子特性-横向排列, 同时又支持宽高.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>fixed</title>
  <style>
    .box {
      display: inline-block;
      width: 100px;
      height: 100px;
      background-color: pink;
    }
  </style>
</head>
<body>
  <div class="box">块01</div>
  <div class="box">块02</div>
  <div class="box">内联01</div>
  <div class="box">内联02</div>
</body>
</html>

当然后面这种横向布局可以梭哈flex 即可, 包括 BFC 等隔离的独立容器实现.

小结

  • CSS 盒模型, 标准 / 奇异 box-sizing: border-box, 宽高包含内边距和边框, 内容往里缩
  • 定位相关: position: relative / absolute / fixed / sticky , "子绝父相" 用得很多
  • diplay 的内外属性, BFC, 默认样式清除, flex 局部引入等

基本就这些, 搞懂之后, 外加一手 flex 布局这块就基本差不多啦.

posted @ 2024-05-12 23:57  致于数据科学家的小陈  阅读(7)  评论(0编辑  收藏  举报