浏览器隐藏滚动条、绝对定位影响滚动条

Posted by CodingWithAlice on October 11, 2024

浏览器隐藏滚动条、绝对定位影响滚动条

总结

  • 关键计算公式
  • 滚动条不展示的两种方法
  • 绝对定位元素影响滚动条的解决办法

只要网页内容大于视窗,滚动条就会出现

  • 关键计算公式【浏览器决定是否显示滚动条的伪代码逻辑】

      const scrollWidth = Math.max(
        contentWidth, // 内容宽度
        absoluteChild.offsetLeft + absoluteChild.offsetWidth, // ← 关键点,绝对定位元素的 left 值 + 绝对定位元素的宽度
        fixedChild.offsetLeft + fixedChild.offsetWidth // 固定定位元素
      );
      const clientWidth = container.clientWidth; // 父容器宽度
      const showScrollbar = scrollWidth > clientWidth; // 滚动宽度 > 父容器宽度 => 展示滚动条
    

一、目标:没有滚动条影响美观,但仍旧可以滚动

方法1:在webkit内核的浏览器里可以定义滚动条样式,在CSS初始处定义
--Chrome--
body::-webkit-scrollbar{ display:none;}
--IE/Edge--
body{ -ms-overflow-style: none;}
--Firefox--
html {
    overflow: -moz-hidden-unscrollable; /*注意!若只打 hidden,chrome 的其它 hidden 会出问题*/
    height: 100%;
}
body {
    height: 100%;
    width: calc(100vw + 18px); /*浏览器滚动条的长度大约是 18px*/
    overflow: auto;
}
方法2:在div外面再套一个div,内层是有滚动条的,但是我们看不到了
  • 设置外层div的width小于内层div的width
<div class="outer">
    <div class="inner"></div>
</div>
.outer{ /* 外层 overflow: hidden */
	overflow: hidden;
    width:200px;
}
.inner{ /* 里层 overflow-y: scroll; overflow-x: hidden; */
    overflow-y:scroll;
    overflow-x:hidden;
    width:220px;
}

二、绝对定位元素(absolute/fixed)意外触发滚动条

滚动条经典问题

根本原因:绝对定位元素有”隐形扩张“效应,即使设置了绝对定位,在标准文档流中不占位,在浏览器计算滚动区域时,仍会考虑

  • 绝对定位元素若 超过父容器的包含块 仍会扩展滚动区域

解决方案:

  • 1、将绝对定位元素移出 父容器
  • 2、限制滚动计算范围 - 告知浏览器忽略绝对定位元素 contain: strict 或者 overflow: clip - 禁止所有滚动

具体案例:

问题描述:父盒子和子盒子高度一样,但是出现纵向滚动条

—> 在一个写死 24px 高度的盒子中,内容 24px + 1px border => 依旧会撑开最外层的 滚动条

<div class="father">
    <div class="child">
        <div class="grandChild">
            <div class="content"></div>
        </div>
    </div>
</div>
.father {
    position: absolute;
    background-color: blueviolet;
    border: 1px solid black;
    overflow: auto;
    width: 200px;
    height: 124px;
}
.child {
    height: 124px;
}
.grandChild {
    height: 124px;
    border: 1px solid red;
}
.content {
    height: 124px;
    display: block;
}