CSS学习笔记(二): overflow

  • 李雨
  • CSS

overflow 基本概念

overflow在内容超出自身尺寸时,决定内容将如何显示。

  • visible (默认)
  • hidden 隐藏超出部分
  • scroll 始终出现滚动条
  • auto 浏览器决定
  • inherit (IE8+) 继承

overflow-x 和 overflow-y (IE8+)

取值和overflow一致,并分别作用于x轴和y轴。

注意:如果overflow-x和overflow-y的值不同,其中一个visible,另外一个为非visible,则visible会被重置为auto。

前提条件

容器需要满足以下条件,overflow才能起作用

  • 非display: inline;
  • 对应方位的尺寸限制。width/height/max-width/man-height/absolute拉伸
  • 对于单元格td等。还需要table属性为table-layout: fixed;

viewport, html 和 body 的overflow

当我们通过检查元素查看最外层的滚动条时,会发现它既不会被包含在body内部也不会被包含在html元素内。这是因为这个滚动条是viewport提供给我们的,而且渲染的机制也不单纯。看规范

UAs must apply the ‘overflow’ property set on the root element to the viewport. When the root element is an HTML “HTML” element or an XHTML “html” element, and that element has an HTML “BODY” element or an XHTML “body” element as a child, user agents must instead apply the ‘overflow’ property from the first such child element to the viewport, if the value on the root element is ‘visible’. The ‘visible’ value when used for the viewport must be interpreted as ‘auto’. The element from which the value is propagated must have a used value for ‘overflow’ of ‘visible’.

看着有点费解,大体可以理解为四点:

  1. 直接将根元素(通常为html)的overflow属性应用到viewport上;
  2. 如果根元素是html,body是html子元素,并且html元素overflow为visible,则会将第一个body元素的overflow属性应用到viewport上;
  3. viewport上overflow: visible会被当做auto;
  4. 如果触发了第二条,body元素的overflow值将使用 visible渲染。

overflow 与滚动条

当overflow值为auto/scroll,并且内容尺寸超过容器尺寸限制时会出现滚动条。

滚动条的样式在各个浏览器中有一定的差异。

获取滚动条的宽度:宽度 - 可视区域宽度(clientWidth)
结果:IE11/Chrome/Firefox(win10):17px;Edge:16px

注意:滚动条出现之后容器大小会发生变化,可能会导致另外一个方向也出现滚动条。

自定义滚动条

webkit

属性 含义
::-webkit-scrollbar 整体部分
::-webkit-scrollbar-button 两端按钮
::-webkit-scrollbar-track 外层轨道
::-webkit-scrollbar-track-piece 内层轨道
::-webkit-scrollbar-thumb 滚动滑块
::-webkit-scrollbar-corner 边角
::-webkit-resizer 右下角拖动块

IE

IE下只能修改滚动条的颜色。

属性 含义
scrollbar-arrow-color: color; 三角箭头的颜色
scrollbar-face-color: color; 立体滚动条的颜色(包括箭头部分的背景色)
scrollbar-3dlight-color: color; 立体滚动条亮边的颜色
scrollbar-highlight-color: color; 滚动条的高亮颜色
scrollbar-shadow-color: color; 立体滚动条阴影的颜色
scrollbar-darkshadow-color: color; 立体滚动条外阴影的颜色
scrollbar-track-color: color; 立体滚动条背景颜色
scrollbar-base-color:color; 滚动条的基色

iOS原生滚动bounce效果: -webkit-overflow-scrolling: touch

javascript 控制滚动

1
2
3
4
5
6
7
8
9
10
11
12
// 获取滚动条位置
// 标准模式
var top = document.documentElement.scrollTop;
var left = document.documentElement.scrollLeft;
// 怪异模式
var top = document..scrollTop;
var left = document.body.scrollLeft;

// 设置滚动条位置
document.documentElement.scrollTop = 100;
document.body.scrollTop = 100;
window.scrollTo(100, 0);

注意: 即使设置了值为hidden,也可以通过js使内容滚动。

竖直滚动条导致固定宽度水平居中跳动的问题

两中方式可以避免这种问题:

  1. 始终出现滚动条
    html { overflow-y: scroll }
  2. 居中元素的父元素设置margin或padding
    padding-left: calc(100vw - 100%);
    margin-left: calc(100vw - 100%);
    100vw: 浏览器宽度;
    100%: 可用内容宽度

查看demo


overflow 与 BFC

值为 auto, scrollhidden 可以触发 BFC,visible 不可以。一般常见的有以下三种应用场景:

  • 清除浮动
  • 避免margin穿透问题
  • 两栏自适应布局

清除浮动

1
.clearfix { overflow: hidden; _zoom: 1 }

以上写法有弊端,会隐藏超出容器的元素,一般这样写:

1
2
.clearfix { *zoom: 1 }
.clearfix:after { content: ''; display: table; clear: both; }

避免 margin 穿透

任何触发BFC的行为都可以避免margin穿透。

两栏自适应布局

利用BFC的特性实现两栏自适应布局。

html代码

1
2
3
4
5
6
<div class="wrap">
<div class="left">
</div>
<div class="right">
</div>
</div>

css代码

1
2
3
4
5
6
7
8
9
10
11
.left {
float: left;
width: 200px;
height: 100%;
}
.right {
height: 100%;
padding-left: 10px;
overflow: hidden;
background: #eee;
}

查看demo

overflow 与 absolute 绝对定位

当overflow元素处于absolute元素和absolute元素的包含块之间时,会导致overflow元素剪裁或滚动失效。HTML基本结构如下:

1
2
3
4
5
<body>        <!-- absolute元素的包含块 -->
<div> <!-- overflow元素 -->
<img/> <!-- absolute元素 -->
</div>
</body>

  • 剪裁失效

  • 滚动失效

    可以利用这样的特性来实现在scroll元素内部固定定位(类似于fixed)的效果。

overflow 其他小技巧和问题

overflow不仅仅可以控制是否出现滚动条,还有其他意想不到的效果。

  • IE6下,固定按钮padding
    IE6浏览器下,文字越多,按钮两侧padding留白就越大,设置visible后padding就不会变大了。

  • overflow的padding-bottom缺失现象
    非Chrome浏览器中,如果容器出现竖直滚动条并且有padding-bottom,会被忽略。
    html代码

    1
    2
    3
     <div class="wrap">
    <div class="content"></div>
    </div>

    css代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     .wrap {
    width: 400px;
    height: 200px;
    padding-bottom: 50px;
    overflow: auto;
    border: 1px solid gray;
    }

    .content {
    width: 100px;
    height: 300px;
    background-color:cornflowerblue;
    }

    结果: