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

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代码到本地查看效果)

当然这个方法也有其缺点,就是需要固定高度,当然这只是一个小缺点,他还有个更麻烦的地方就是,锚点功能“由内而外”的特性会使其触发窗体外的重定位,也就是说如果页面也是可以滚动,那么点击选项卡后页面会发生跳动,这种体验显然是“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相关的内容,感兴趣的关注一下吧~

7ced86fae6cd7b89ad3345ee022442a7d8330e6e.jpg

最后,给大家推荐一个前端学习进阶内推交流群685910553前端资料分享),不管你在地球哪个方位,
不管你参加工作几年都欢迎你的入驻!(群内会定期免费提供一些群主收藏的免费学习书籍资料以及整理好的面试题和答案文档!)

如果您对这个文章有任何异议,那么请在文章评论处写上你的评论。

如果您觉得这个文章有意思,那么请分享并转发,或者也可以关注一下表示您对我们文章的认可与鼓励。

愿大家都能在编程这条路,越走越远。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,727评论 1 92
  • 第一回 overflow基本属性 overflow基本属性 visibel hidden scroll ...
    seepDown阅读 687评论 0 2
  • float float 属性指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。该元素从网页的正常流...
    Promise_4483阅读 326评论 0 0
  • day01­_起源和结构 结构:Xhtml xml 表现:CSS 行为:DOM ECMAScript 以上都属于W...
    Sakura_明妃阅读 1,160评论 0 1
  • 每每被问到“你在教学中最困扰的问题是什么?”时,我的第一反应总是:如何与学生高效沟通。在过去一年的教学生...
    曾_ZJM阅读 2,611评论 0 6