CSS进阶(11)—— overflow属性详解,利用CSS实现锚点定位

3,759 阅读10分钟

本章延续上一章BFC的内容深入探索BFC的最佳结界——overflow在其本职工作上的表现。

1.overflow的裁剪界线——border-box

overflow属性用于指定块容器元素的内容溢出时的表现方式——滚动,裁剪,自适应。“BFC的最佳结界”只是其衍生出来的特性,“裁剪”才是其本职工作。在使用overflow做裁剪工作的时候需要注意裁剪的边界时border box的内边缘,来看下面的例子。

<div style="width: 200px;height: 200px;overflow: hidden;border: 10px solid #ccc;padding: 20px">
    <img src="../小和尚.jpg">
</div>

裁切部分的留白似乎不是很符合我们的预期,如果想要实现元素裁切同时四周留白的话,可以利用透明边框,此时padding属性时无能为力的!

2.overflow与滚动条

HTML中有两个标签是默认可以产生滚动条的,一个是跟元素html,还有一个是文本标签textarea,只有这两个标签的默认overflow是auto属性,其他都是visible。关于浏览器的滚动条,有以下两个结论:

(1)在PC端,无论什么浏览器,默认滚动条均来自html,而不是body,这点可以由浏览器下body的默认margin不为零,但当内容高度超过100%的时候,滚动条离浏览器不会有间隙(body的默认margin)可以得出结论。上述结论只针对PC端有效!

(2)在PC端,滚动条出现就一定会占用容器的可用宽度/高度,也就是你本来布局非常准确的200像素宽度,在加入右侧滚动条后,可能会导致子元素的像素计算出现偏差,由于父容器的右侧挤入了一个不速之客——滚动条。因此在考虑PC端带滚动条布局的时候,可以减少子元素的实际可用宽度,通常情况下,浏览器滚动条所占的宽度是17px(并不是绝对的),因此可以考虑子元素在右侧留白>17px。注意本条定律也仅针对PC端有效,由于移动端的屏幕分辨率本来就低,因此滚动条一般以悬浮的方式出现,并不会占用实际宽度。

(3)既然滚动条在CSS布局中有如此重要的地位,因此其样式也是可以自定义的,在chrome浏览器中的属性如下:

  • 整体部分,::-webkit-scrollbar;

  • 两端按钮,::-webkit-scrollbar-button;

  • 外层轨道,::-webkit-scrollbar-track;

  • 内层轨道,::-webkit-scrollbar-track-piece;

  • 滚动滑块,::-webkit-scrollbar-thumb;

  • 边角部分,::-webkit-scrollbar-corner;

overflow除了和滚动条是PY关系,还有一些衍生属性也要依赖overflow,如单行文字超出部分省略号显示,就需要用到overflow:hidden的声明。代码如下

<style>
.overText{
    white-space:nowrap;
    text-overflow:ellipsis;
    overflow:hidden;
}
</style>

3.overflow与锚点定位

什么是锚点定位?通俗点的解释就是让页面定位到某个位置的点。在高度较高的页面中,通常我们会通过侧边导航栏定位到文章的某一段内容中去,如bilibili的侧边导航栏即可实现这个功能。要实现锚点定位,很多人都知道可以通过Js通过调整scrollTop实现,但新手很少会知道CSS本身就已经提供了这个功能(包括我)。这跟网上教程中很少涉及"CSS锚点定位"功能实现有关,通常情况下,我们看到的都是"JS锚点定位"功能的讲解。下面来看看如何用CSS实现锚点定位。CSS规定触发锚点定位行为发生的条件有两种:

(1)URL地址中的锚链与锚点元素对应并有交互行为

(2)可focus的锚点元素处于focus状态

URL的触发条件比较容易,最常用的a标签即可帮助我们实现锚点定位功能。如下代码:

<a href="#1">我要定位到和1绑定的元素</a>
<div id="1">我是要被定位的元素</div>

此时我们点击a标签,便会触发URL的哈希值改变,然后页面会根据实际情况让id为1的div元素定位在浏览器窗体的上边缘(如果需要的话,div元素本身就在页面的第一行就没必要定位了)

可focus的锚点元素处于focus状态不是本章要讨论的重点,这里只举一个简单的链子,在PC端,我们使用Tab键可以快速定位可focus的元素,如果下一个focus元素位于屏幕外,那么浏览器就会自动重新定位,将这个屏幕外的元素定位到屏幕之中。

虽然两者都是锚点定位,但是这两种方式的表现行为还是有差异的,"URL锚点定位"实让元素定位在浏览器窗体的上边缘,而"focus锚点定位"是让元素在浏览器窗体范围显示即可,不一定是在上边缘(这个你自己一试便知,如CSDN的编辑器就有许多focus元素,把滚动条拖到最上方,按下Tab键就可以看到效果了~)

锚点定位行为发生的本质是通过改变容器滚动高度/宽度来实现的,除了html,锚点定位功能还可以在任何overflow不为visible的元素中实现,这句话中可以拆分成两个条件。

条件(1):锚点定位行为可以在任何元素中发生,不只是html,还可以是普通的div元素

条件(2):只要是overflow不为visible的元素都可以锚点定位,包括overflow:hidden!

第二个条件说明,锚点定位功能和有没有滚动条时也能实现,后面我们会借助这个条件用CSS实现一个选项卡功能。干巴巴的说了许多,还没确认过功能,下面我们就来简单验证一下CSS自带的锚点定位功能。

<!-- CSS锚点定位 -->
<a href="#1">1</a>
<a href="#2">2</a>
<a href="#3">3</a>
<a href="#4">4</a>
<a href="#5">5</a>
<a href="#6">6</a>
<a href="#7">7</a>
<a href="#8">8</a>
<a href="#9">9</a>
<a href="#10">10</a>
<a href="#">回到顶部</a>
 
<div style="overflow:auto;height: 300px; width: 300px;">
    <div id="1" class="li">1</div>
    <div id="2" class="li">2</div>
    <div id="3" class="li">3</div>
    <div id="4" class="li">4</div>
    <div id="5" class="li">5</div>
    <div id="6" class="li">6</div>
    <div id="7" class="li">7</div>
    <div id="8" class="li">8</div>
    <div id="9" class="li">9</div>
    <div id="10" class="li">10</div>
</div>
 
<style type="text/css">
.li{
    width: 200px;
    height: 200px;
    margin-bottom: 20px;
    background: yellow;
    display: inline-block;
}
</style>

上面的例子证明了锚点定位也可以发生在普通元素中,同时我们还需要知道一个概念,就是锚点定位是可以同时发生在嵌套元素中的,且发生的顺序是“由内而外的”,如普通元素和窗体可以同时滚动的时候,就会由内而外触发所有可以滚动的窗体的锚点定位功能。

上面只是锚点定位功能的简单测试,同时他也符合“锚点定位功能是滚动条的表现形式”的正常预期。然而本小节的核心内容是:overflow:hidden的元素也是可以实现锚点定位的,当元素声明了overflow后,里面内容高度溢出的时候,滚动永远存在,滚动条可有可无,下面我们就将上面例子中的overflow:auto改为overflow:hidden,看看是否符合这个理论。

结果跟理论相同,overflow:hidden的元素也可以实现锚点定位功能。(关于CSS的锚点定位,我个人求证了掘金右侧的导航栏也是用的CSS锚点定位功能,感兴趣的小伙伴可以自己看一下掘金自带的锚点定位功能)

4.利用CSS实现选项卡效果

理论需要被用在实践中才能发挥他的作用,下面我们就用overflow:hidden的锚点定位功能实现一个CSS选项卡效果。

<!-- CSS实现选项卡功能 -->
<div class="box">
    <div class="list" id="one">1</div>
    <div class="list" id="two">2</div>
    <div class="list" id="three">3</div>
    <div class="list" id="four">4</div>
</div>
<div class="link">
    <a class="click" href="#one">1</a>
    <a class="click" href="#two">2</a>
    <a class="click" href="#three">3</a>
    <a class="click" href="#four">4</a>
</div>
<style type="text/css">
.box {
    width: 20em;
    height: 10em;
    border: 1px solid #ddd;
    overflow: hidden;
}
.list {
    line-height: 10em;
    background: #ddd;
    text-align: center;
}
</style>

由于markdown编辑器支持标签语言,因此我们可以直接预览最终效果如下(小提示:你可以直接点击1,2,3,4看到效果,建议copy代码到本地查看效果)

1
2
3
4
1 2 3 4

当然这个方法也有其缺点,就是需要固定高度,当然这只是一个小缺点,他还有个更麻烦的地方就是,锚点功能“由内而外”的特性会使其触发窗体外的重定位,也就是说如果页面也是可以滚动,那么点击选项卡后页面会发生跳动,这种体验显然是“bug”级别的存在,因此这里只是介绍这种方法,在实际场景中,我更推荐使用第二种方法去实现CSS锚点定位功能。

还记得刚才提到的focus元素也可以触发锚点定位的功能嘛?而且focus的特性就是只要元素在浏览器内,就不会触发浏览器窗口的重新定位,这个属性用在选项卡这儿,简直是太棒了。那么如何触发元素的focus呢?原生的标签也可以触发这个属性,就是已经快被我们遗忘的label标签可以完美触发input的focus,知道了这些理论后我们就可以实现一个完美的CSS选项卡功能了。

<!-- CSS实现选项卡功能 -->
<div class="box">
    <div class="list"><input id="one">1</div>
    <div class="list"><input id="two">2</div>
    <div class="list"><input id="three">3</div>
    <div class="list"><input id="four">4</div>
</div>
<div class="link">
    <label class="click" for="one">1</label>
    <label class="click" for="two">2</label>
    <label class="click" for="three">3</label>
    <label class="click" for="four">4</label>
</div>
<style type="text/css">
.box {
    width: 20em;
    height: 10em;
    border: 1px solid #ddd;
    overflow: hidden;
}
.list {
    height: 100%;
    background: #ddd;
    text-align: center;
    position: relative;
}
.list > input { 
  position: absolute; top:0; 
  height: 100%; width: 1px;
  border:0; padding: 0; margin: 0;
  clip: rect(0 0 0 0);
}
</style>

overflow的讲解到此就结束了,下一章我们继续来探讨CSS世界的流破坏与流保护,之前讲了float,下一章float的好PY position:absolute相关的内容,感兴趣的关注一下吧~

不忘初心,方得始终

喜欢博主的童鞋可以扫描二维码加博主好友~ 也可以扫中间二维码入驻博主的粉丝群(708637831)~当然你也可以扫描二维码打赏并直接包养帅气的博主一枚。