CSS基础--overflow二

1、依赖overflow的样式表现
有一种效果就离不开overflow:hidden声明,即单行文字溢出点点点效果。效果的核心是textoverflow:ellipsis。效果实现必需的3个声明如下:

.ell {  
text-overflow: ellipsis;  
white-space: nowrap;  
overflow: hidden; 
}

目前,对-webkit-私有前缀支持良好的浏览器还可以实现多行文字打点效果,但是却无须依赖overflow:hidden。比方说,最多显示2行内容,再多就打点的核心CSS代码如下:

.ell-rows-2 {  
display: -webkit-box; 
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}

2、overflow与锚点定位
锚点,通俗点的解释就是可以让页面定位到某个位置的点。基于URL地址的锚链(如上面的#1,可以使用location.hash获取)实现锚点跳转的方法有两种,一种是标签以及name属性,还有一种就是使用标签的id属性。
百度百科里是这样表现得

<a href="#1">发展历程></a><!--这是初始点击位置-->
 <a name="1"></a> <!--这是目的位置-->

更推荐利用标签的id属性,因为HTML会显得更干净一些,也不存在任何兼容性问题:

<a href="#1">发展历程></a> 
<h2 id="1">发展历程</h2> 

2.1.锚点定位行为的触发条件
下面两种情况可以触发锚点定位行为的发生:
(1)URL地址中的锚链与锚点元素对应并有交互行为;
(2)可focus的锚点元素处于focus状态。
比方说,点击一个链接,改变地址栏的锚链值,或者新打开一个链接,后面带有一个锚链值,当然前提是这个锚链值可以找到页面中对应的元素,并且是非隐藏状态,否则不会有任何的定位行为发生。如果我们的锚链就是一个很简单的#,则定位行为发生的时候,页面是定位到顶部的,所以我们一般实现返回顶部效果都是使用这样的HTML:

<a href="#">返回顶部></a> 

然后配合JavaScript实现一些动效或者避免点击时候URL地址出现#,而很多人实现返回顶部效果的时候使用的是类似下面的HTML:

<a href="javascript:">返回顶部></a>

然后使用JavaScript实现定位或者加一些平滑动效之类。显然我是推荐上面那种做法的,因为锚点定位行为的发生是不需要依赖JavaScript的,所以即使页面JavaScript代码失效或者加载缓慢,也不会影响正常的功能体验,也就是用户无论在什么状态下都能准确地返回顶部
“focus锚点定位”指的是类似链接或者按钮、输入框等可以被focus的元素在被focus时发生的页面重定位现象。举个很简单的例子,在PC端,我们使用Tab快速定位可focus的元素的时候,如果我们的元素正好在屏幕之外,浏览器就会自动重定位,将这个屏幕之外的元素定位到屏幕之中。再举一个例子,一个可读写的输入框在屏幕之外,则执行类似下面的JavaScript代码的时候:

document.querySelector('input').focus();

这个输入框会自动定位在屏幕之中,这些就是“focus锚点定位”。
虽然都是锚点定位,但是这两种定位方法的行为表现还是有差异的,“URL地址锚链定位”是让元素定位在浏览器窗体的上边缘,而“focus锚点定位”是让元素在浏览器窗体范围内显示即可,不一定是在上边缘。
2.2 锚点定位作用的本质
锚点定位行为的发生,本质上是通过改变容器滚动高度或者宽度来实现的。这里说的是容器的滚动高度,而不是浏览器的滚动高度。
锚点定位也可以发生在普通的容器元素上。而且定位行为的发生是由内而外的。如:我们的页面上有一个

元素设置了overflow:auto,且子元素高度超出其自身高度限制,代码示意CSS和HTML如下:

.box {  
height: 120px; 
 border: 1px solid #bbb; 
 overflow: auto; 
 } 
 .content {  
 height: 200px;  
 background-color: #eee; 
 } 
 <div class="box">  
 <div class="content"></div>  
 <h4 id="title">底部标题</h4> 
 </div> 
 <p><a href="#title">点击测试</a></p> 

由于.content元素高度超过.box容器,因此

元素必然不可见,然后,我们点击下面的“点击测试”链接,则滚动条位置变化(实际上改变了scrollTop值),“底部标题”自动出现了。
在这里插入图片描述

“由内而外”指的是,普通元素和窗体同时可滚动的时候,会由内而外触发所有可滚动窗体的锚点定位行为。继续上面的例子,假设我们的浏览器窗体也是可滚动的,则点击“点击测试”链接后,“底部标题”先触发.box容器的锚点定位,也就是滚动到底部,然后再触发窗体的锚点定位,“底部标题”和浏览器窗口的上边缘对齐,如图:
在这里插入图片描述
其次就是设置了overflow:hidden的元素也是可滚动的,这也是本小节的核心。说得更干脆点儿就是:overflow:hidden跟overflow:auto和overflow:scroll的差别就在于有没有那个滚动条。元素设置了overflow:hidden声明,里面内容高度溢出的时候,滚动依然存在,仅仅滚动条不存在!
即虽然设置overflow:hidden显示鼠标滚动无法滚动,但是发生锚点定位,你就会发现滚动发生了

.box {  
height: 120px;   
border: 1px solid #bbb;  
overflow: hidden; 
}

锚点定位本质上是改变了scrollTop或scrollLeft值,因此,上面的定位效果等同于执行了下面的JavaScript代码: document.querySelector(’.box’).scrollTop = 200; // 随便一个足够大的值即可。
基于URL地址的锚链触发锚点定位实现的选项卡切换效果。
HTML和核心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 href="#one">1</a>  
<a href="#two">2</a>  
<a href="#three">3</a>  
<a href="#four">4</a> 
</div> 
.box {  
height: 10em;  
border: 1px solid #ddd;  
overflow: hidden; 
} 
.list {  
line-height: 10em;  
background: #ddd; 
} 

此效果乍一看很酷,但却有不少不足之处:其一,容器高度需要固定;其二,也是最麻烦的,就是“由内而外”的锚点定位会触发窗体的重定位,也就是说,如果页面也是可以滚动的,则点击选项卡按钮后页面会发生跳动,这种体验显然是非常不好的。有,还记不记得前面提过有两种方法可以触发锚点定位,其中有一种方法就是“focus锚点定位”,只要定位的元素在浏览器窗体中,就不会触发窗体的滚动,也就是选项卡切换的时候页面不会发生跳动
可以发现,就算页面窗体就有滚动条,绝大多数情况下,也都不会发生跳动现象,HTML和核心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> 
.box {  
height: 10em;  
border: 1px solid #ddd;  
overflow: hidden; 
} 
.list {  
height: 100%;  
background: #ddd;  
position: relative; 
} 
.list > input {  
position: absolute; 
top:0;  
height: 100%; 
width: 1px;  
border:0; 
padding: 0; 
margin: 0;  
clip: rect(0 0 0 0); 
} 

原理其实很简单,就是在每个列表里塞入一个肉眼看不见的输入框,然后选项卡按钮变成

$('label.click').removeAttr('for').on('click', function() {  $('.box').scrollTop(xxx); 'xxx'表示滚动数值 }); 

知道overflow:hidden元素依然可以滚动,除了可以帮助我们实现无JavaScript的选项卡效果外,还可以帮助我们理解一些现象发生的原因。例如,我之前提到过的使用marginbottom负值加padding-bottom正值以及父元素overflow:hidden配合实现的等高布局,在大多数情况下,这种布局使用是没有任何问题的,但是如果使用dom.scrollIntoView()或者触发窗体视区范围之外的内部元素的锚点定位行为,布局就会飞掉,没错,布局就像长了翅膀一样飞掉了。因为,此时容器的scrollHeight(视区高度+可滚动高度)要远远大于clientHeight(视区高度),而锚点定位的本质就是改变容器的滚动高度,因此,容器的滚动高度不是0,发生了与上面无JavaScript的选项卡类似的效果,产生布局问题。
实现自定义的滚动条效果,因为Windows系统下浏览器的滚动条会占据宽度,而且长得不好看,所以就存在实现自定义滚动条的需求,也就是类似移动端的悬浮式滚动条。传统实现都是父容器设置overflow:hidden,然后子元素使用一个大的

包起来,设置绝对定位,然后通过改变top值,或者使用transform进行偏移。
最推荐的实现还是基于父容器自身的scrollTop值改变来实现自定义滚动条效果,其好处有如下这些。
(1)实现简单,无须做边界判断。因为就算scrollTop设为-999,浏览器依然按照0来渲染,要想滚动到底部,直接一个很大的scrollTop值就可以了,无须任何计算。例如: container.scrollTop = 99999; 列表滚动了多少直接就是scrollTop值,实时获取,天然存储。传统实现要变量以及边界更新,很啰嗦。
(2)可与原生的scroll事件天然集成,无缝对接。例如,我们的滚动延迟加载图片效果就可以直接应用,因为图片位置的计算往往都是和scrollTop值相关联的,所以传统实现scrollTop值一直是0,很可能导致这类组件出现异常。
(3)无须改变子元素的结构。传统实现为了定位方便,会给所有的列表元素外面包一层独立的
元素,这可能会导致某些选择器(类似于.container > .list{})失效,但是,基于父容器本身的scrollTop滚动实现则无此问题,即使子元素全是兄弟元素也是可以的。
当然,没有哪种技术是万能的,基于改变overflow:hidden父容器的scrollTop实现自定义滚动条效果也有几点不足:一是无法添加类似Bounce回弹这种动效;二是渲染要比一般的渲染慢一些,但大多数场景下用户都是无感知的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值