• CSS – Position


    前言

    定位是 CSS 里蛮重要的一课.

    图片黑影 (overlay), back to top button, header, footer 紧贴在屏幕上下方等效果都是靠 position 完成的.

    参考:

    Youtube – #CSS 認識 Position 粤语

    阮一峰 – CSS 定位详解

    Static

    position 一共有 5 种, 默认是 static.

    假设有 5 个 box

    <div class="container">
      <div class="box1">box1</div>
      <div class="box2">box2</div>
      <div class="box3">box3</div>
      <div class="box4">box4</div>
      <div class="box5">box5</div>
    </div>

    它的效果就是一个一个往下放. 彼此是不重叠的.

    fixed

    fixed 的使用场景是在 scrolling 的时候, 我们想让某个元素一直保持在一个位置上. 比如 back to top button.

    .box3 {
      position: fixed;
    }

    效果

    当设置 fixed 以后, box3 发生了几个变化.

    1.飘起来了

    即便没有 scroll, 一开始 box3 就和 box4 重叠了. 这是因为 box3 飘起来了. 

    这个过程类似把 box3 从布局中抽走, 整个布局变成 box1, 2, 4, 5.

    2. top, right, bottom, left, inset

    通常 fixed 一定是搭配 offset 属性一起用的. 它的玩法是这样:

    有 2 个对象

    第 1 个是外面的 offset 对标框 (fixed 对标框就是 viewport 屏幕框)

    第 2 个是里面的定位元素咯

    白色区域就是整个 viewport (屏幕框)

    inset 是 top, right, bottom, left 的 shorthand, 和 padding, margin 用法完全一样.

    inset: 0 相等于 4 边都是 0, inset 10px 20px 则是 top,bottom: 10px, left, right: 20px

    3. offset 的默认值

    当 box3 没有设置 top 偏移时, 游览器的默认行为是把它定位到它原本的位置上, 所以效果就是和 box4 发生了重叠.

    如果设置 top: 60px 的话

     box3 不在和 box4 重叠, 而是和 box1,2 重叠.

    注: 很少会用默认的, 而且默认的 "原地" 是依赖排版方式的, 如果是用 margin 来布局, 或者 Flex, 游览器很有可能无法正确的计算到 "原地".

       

    absolute

    offset parent

    absolute 和 fixed 很像. 只有 2 个点不同, 第一是它们的 offset 对标框不同.

    fixed 的 offset 对标框是 viewport. 而 absolute 的 offset 对标框是不固定的. 

    它有个术语叫 offset parent. 

    通过 JS 可以拿到哦 (注: chrome position fixed offsetParent will be null. 不清楚为什么 chrome 那么特别...哈哈)

    document.querySelector(".box3").offsetParent;

    从 absolute element 往 parent 走, 第一个 position 不是 static 的 element 就是它的 offset parent.

    虽然红框是第一个 parent 但它是 static, 所以继续往上找, 蓝框才是第一个不是 static 的 element, 所以它成为了 offset parent.

    所有 offset 位置都基于它来计算.

    fixed 则是不管什么 parent, 它就对着 viewport

    absolute 不被 scroll 影响

    第二个不同是 absolute 不会被 scroll 影响. fixed 对标的是 viewport 所以才会随着 scroll 而改变.

    box3 是 absolute; top: 0; rigth: 0; 如果要它随着 scroll 改变, 可以用 stikcy (下面会讲到)

    border 不算在内

    还有一个点是, top, right, bottom, left 是从 padding 算起的, border 不算在内.

    top left: 50px

    黑线不算哦

    冷知识 – Position absolute 导致 parent overflow

    冷知识 – 当 position: absolute 遇上 grid container

    relative

    relation 和 ablsolute 就有差别了. 

    第 1 它没有被抽出布局的概念.

    .box3 {
      position: relative;
      top: -50px;
    }

    效果

    先不管 top: -50px 的逻辑. 当 box3 relation 以后, box2, box4 并没有连在一起. 中间依然空了一个 box3 的距离.

    这就类似灵魂出窍一样. 

    第 2 它的 offset 计算不是对着 offset parent 也不是对着 viewport.

    而是对着元素原本的位置.

    过程类似, 在元素原本的位置画一个虚拟框作为它的 offset parent. 然后依据框做偏移. 

    上面例子中 top: -50px 

    红框就是元素本来的位置, -50px 往上偏移, 所以最终 box3 和 box2 重叠了.

    小总结:

    static: 默认 position

    fixed: 会飘起来, 抽离原先的布局. 会导致原本的布局不一样. 始终和 viewport 保持固定的偏移.

    absolute: 会飘起来, 抽离原先的布局. 会导致原本的布局不一样, 始终和 offset parent (第一个不是 static 的 parent) 保持固定的偏移.

    最常用的手法就是给 parent position: relation 让它变成 offset parent. 因为 relation 不会对原本的布局有影响. 同时它又不是 static, 就可以成为 offset parent 了.

    relation: 会飘起来, 但是不会抽离原先布局, 对原本的布局没有影响. 原地偏移. 

    sticky

    以前写过 Angular 学习笔记 (Material table sticky 原理)

    重要概念:

    1. sticky scroll container

    sticky element 会找到第一个 overflow auto 的 parent 作为它的 sticky scroll container (不管是 vertical 还是 horizontal, 只要能 scroll 就是 sticky scroll container).

    2. sticky max area container 

    sticky 的第一个 parent 就是 max area container, 没有任何要求, 第一个 parent 就是了, sticky 的可移动空间就看这个 max area container.

    3. sticky top, right, bottom, left

    position sticky 一定要要配上 offset 这些会 start working.

    它的计算和 absolute 是不同的. absolute 不 cover padding, 但是 sticky cover.

    scroll container 的 border 和 padding 会保留, sticky element 会在 padding 下面.

    absolution 的话 element 是会盖掉 padding 的.

    什么时候会 stick ?

    中间长方形是 viewport, 当 scroll 的时候,红色的 sticky top 会不会触发, 取决于红色 element 是否在 viewport 的前面.

    蓝色的 sticky bottom 会不会触发取决于它是否在 viewport 的下面.

    比如黄色在中间, 那么它是没有任何 sticky 的. 上下都不粘.

    它并不完美

    上面说的 1, 2 条件 sticky scroll container 和 sticky max area container 大大限制了使用的场景.

    sticky 的 first overflow 很有可能是 horizontal 但是需求是更上一层的 vertical 才是 scroll container. 这就不能用了.

    first parent 是 max area 更恐怖. 比如需求要做一个 animation, 你 wrap 它起来就 gg.com 了.

    它适合的场景是, first parent 刚好是 max area container 同时也是 scroll container. 这样才比较顺.

    可以通过 JS 实现突破这些局限. 以前没有 position: sticky 的时候大家都是这样干的. 确保性能 ok 就可以了. 它的基本原理就是做计算, 然后配上 relative or absolute 都可以 (只要定位就可以了, 其它的就是计算偏移量问题而已). 

    细节看这篇: CSS & JS Effect – Simulation Position Sticky

    当 absolute / fixed 遇上 width / height auto

    参考

    MDN – position

    stackoverflow – auto and fixed position

    有时候当我们修改 div 的 position 之后会发现它变小了. 

    div block element auto 相等于 100% 对标 parent. 但是经过 position absolute 以后变成了 hug content. 

    在 MDN 有一段就是声明这个的.

    如果希望保留原本的效果可以设置 left:0; right:0. 或者不要使用 auto 改成 100%.

    常见的 overlay 写法

      

    3个写法是等价的, 通常会写第 3 种. 因为它最短嘛.

  • 相关阅读:
    深入protoBuf
    Golang数据库操纵对IN语句的支持
    golang几种常用配置文件使用方法总结(yaml、toml、json、xml、ini)
    golang实现rabbitmq消息队列失败尝试
    Trie性能分析之敏感词过滤golang
    Go语言cookie的基本操作
    微信二维码添加logo
    gin框架中间件
    gin入门-1
    2017-06-28(passwd 主要组与附属组 gpasswd newgrp groups)
  • 原文地址:https://www.cnblogs.com/keatkeat/p/15886108.html
Copyright © 2020-2023  润新知