如何不使用 overflow: hidden 实现 overflow: hidden
一个很有意思的题目。如何不使用 overflow: hidden
实现 overflow: hidden
?
CSS 中 overflow
定义当一个元素的内容太大而无法适应块级格式化上下文时候该做什么。而 overflow: hidden
则会将超出容器范围内的内容剪裁。
控制 overflow: hidden
的方向
这源自一个实际的需求,在某个需求当中,要求容器内的内容,在竖直方向上超出容器会被裁剪,而在水平方向上超出容器,则不会被裁剪。类似这样:
有意思,第一个想到的解法当然是在上述黄色背景元素本身之外再套用一层父元素,然后父元素才是实际设置 overflow: hidden
的元素,父元素的范围就是实际才是控制是否裁剪的范围。类似这样:
实际的父元素才是设置了 overflow: hidden
的元素。
当然,如果实际情况就是这么简单,也没什么问题。
但是如果元素处于一个复杂的布局流内,那么可能就没有那么多的空间,让我们再去包裹一层父容器了:
类似上图的情况,还是中间黄色元素,要求只有竖直方向超出裁剪。此时,包裹父元素不再那么容易施展。所以,我们需要另辟蹊径。
利用 clip-path
进行裁剪
好的,这会可以进入正文了。CSS 中,除了 overflow: hidden
,还是有其它属性也可以实现超出容器区域进行裁剪的。clip-path
便是其中翘楚。
使用 clip-path
,我们可以方便的控制任意方向上的裁剪。上述的需求则可以这样解决:
<div class="g-container">
<div class="sub"></div>
</div>
关键的 CSS 代码如下:
.g-container {
width: 200px;
height: 200px;
clip-path: polygon(-1000% 0, 1000% 0, 1000% 100%, -1000% 100%);
}
这里利用了 clip-path: polygon()
来裁剪一个矩形区域,而利用了 clip-path
支持负坐标的特点,将裁剪的起点定到远离坐标能画成一个大矩形的形状。示意图:
这样,我们能够在正常布局流中,当前容器大小范围内,画出任意希望 overflow: hidden
的范围。
你可以点进 Demo 里面尝试下:
再举两个例子:
{
// 裁剪出左右两边都 overflow:hidden,上下不 overflow:hidden 的区域
clip-path: polygon(0 -1000% ,100% -1000%, 100% 1100%,0 1100%); // 裁剪出左边、上边、右边都 overflow:hidden,下边不 overflow: hidden 的区域
clip-path: polygon(100% 0,100% 1000%, 0 1000%, 0 0);
}
当然,上述代码中的 1000%
是非常灵活的,自己控制,够用就行。
非 overflow、clip-path 的裁剪方式
那么。通过上面的一个小例子,我们知道了 overflow
,clip-path
可以裁剪区域。那么除了这两个,CSS 中还有没有可以进行区域裁剪的元素呢?
有,还有一个有意思的元素,就是 -- contain
。
contain
属性允许我们指定特定的 DOM 元素和它的子元素,让它们能够独立于整个 DOM 树结构之外。目的是能够让浏览器有能力只对部分元素进行重绘、重排,而不必每次都针对整个页面。
这里不具体去介绍它的每个属性,感兴趣的可以翻看下这篇文章 -- CSS新特性contain,控制页面的重绘与重排
contain: paint
进行内容裁剪
详细说说 contain: paint
,设定了 contain: paint
的元素即是开启了布局限制,也就是说,此元素的子元素不会在此元素的边界之外被展示。
contain: paint
属性产生的目的,即是为加快页面的渲染,在非必要区域,不渲染元素。因此,如果元素不在屏幕上或以其他方式设定为不可见,则其后代不可见不被渲染。
.g-container {
contain: paint;
}
看看示例:
CodePen Demo -- contain: paint Demo
contain: paint
的副作用
contain: paint
的本意是用于提升页面的渲染,裁剪到容器之外的元素不进行渲染。但是使用它会产生一些副作用:
- 它会生成一个自己的新的堆叠上下文(It becomes a stacking context),也就是说,它会改变它的子元素的 absolute 定位和 fixed 定位的基准;
- 它会成为新的格式化上下文(It becomes a new formatting context),也就是说,这意味着元素外部的布局不会再影响它的子元素;
更具体的,可以看看这篇文章 -- CSS Containment in Chrome 52
我们解释下第一点,非常的有意思,它会生成一个自己的新的堆叠上下文,也就是说,它将改变 position: fixed
元素的基准,它会使得设置了 position: fixed
的元素不再相对于视口进行定位,而是相对于该元素进行定位。也就是退化成了 position: absolute
。
当然,这个不是本文的重点,我提供了一个 Demo -- contain: paint create a stacking context,这里就不继续展开。
总结一下
到此,本文提供了 3 种可以实现超出容器范围裁剪的方法:
overflow: hidden
clip-path
绘制裁切区域contain: paint
不绘制元素范围外的内容
这里再提供下 3 个示例的 Demo:CodePen Demo -- Overflow Hidden In CSS
当然,它们之间还是有一些差异:
overflow: hidden
和contain: paint
会创建一个 BFC,而clip-path
不会,它只是单纯的裁剪- 兼容性间的差异
所以也就是说,CSS 不仅仅只有 overflow: hidden
实现 overflow: hidden
,很多情况,可以灵活使用。
牛刀小试
再来个有意思的环节,在 一行 CSS 代码的魅力 中,提到了 CSS Battle 。
这个网站是核心玩法就是:官方给出一张图形,在给定的 400 x 300 的画布上,能够用越短的代码实现它,分数就越高。
上次讲了一题通过一行 CSS 代码实现,今天,我们再来看看第二题:
怎么用最短的代码实现它呢?想想今天说的 clip-path
。
首先,我们利用这一一段代码,生成这样一个图形:
<style>
body {
margin: 0 50px;
background: #62374e;
border: 50px dashed #fdc57b;
}
然后,利用 clip-path
,把上下两部分裁掉即可。
<style>
body {
margin: 0 50px;
background: #62374e;
border: 50px dashed #fdc57b;
+ clip-path: polygon(0 50px, 100% 50px, 100% 250px, 0 250px);
}
这样就完美实现啦。当然,现在字符数有点多,有 158 个字符这么多。其实对于裁剪矩形区域,clip-path
有更便捷的语法,上述 clip-path:polygon(0 50px, 100% 50px, 100% 250px, 0 250px)
可以替换成 clip-path:inset(50px 0)
,减少了 20 个字符。
当然,再暴力一点,我们也可以一行实现:
<body bgcolor=62374e style=margin:0+50;border:dashed+50px#fdc57b;clip-path:inset(50px+0>
当然,这里可能用了一些这个网站才允许的语法,不过核心实现还是在于用
clip-path
切割掉多余部分
最后
好了,本文到此结束,希望对你有帮助 :)
更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。
如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
如何不使用 overflow: hidden 实现 overflow: hidden的更多相关文章
- 解决页面使用overflow: scroll,overflow-y:hidden在iOS上滑动卡顿的问题
解决页面使用overflow: scroll,overflow-y:hidden在iOS上滑动卡顿的问题 div{ width: 100%; overflow-y: hidden; -webkit-o ...
- 整理display:none;和visibility:hidden;和overflow:hidden;的区别
1.display:none; 这个属性隐藏元素,不占网页任何空间,彻底隐藏,消失 2.visibility:hidden; 占据空间,但是无法点击.隐藏了这个层,看不到,却能摸得着 3.over ...
- IE6,IE7上设置body{overflow:hidden;}失效Bug
IE6,IE7下设置body{overflow:hidden;}失效Bug 最近做项目发现在IE7下设置body{overflow:hidden;}后还是会出现纵向滚动条,所以上网查查了,在这里记录一 ...
- 清除浮动2-父元素设置overflow:hidden
<!doctype html><html> <head> <meta charset="UTF-8"> <meta name= ...
- IE下设置body{overflow:hidden;}失效Bug
问题重现: <p>There are no scrollbars on this page in sane browsers</p> html, body, p { margi ...
- CSS学习:overflow:hidden解决溢出,坍塌,清除浮动
overflow:hidden是overflow属性的一个神奇用法,它可以帮助我们隐藏溢出的元素,清除浮动和解除坍塌. CSS样式: .container{ background-color: bla ...
- 为什么overflow:hidden能达到清除浮动的目的?
1. 什么是浮动 <精通CSS>(第3版)关于浮动的描述: 浮动盒子可以向左或向右移动,直到其外边沿接触包含块的外边沿,或接触另一个浮动盒子的外边沿. 浮动盒子也会脱离常规文档流,因此常规 ...
- css & auto height & overflow: hidden;
css & auto height & overflow: hidden; {overflow: hidden; height: 100%;} is the panacea! {溢出: ...
- CSS深入理解之overflow
CSS深入理解之overflow 前言 这是跟着张鑫旭重学CSS的overflow篇 基本属性 overflow有以下五个基本属性: 1.visible : 默认值,具体表现为,应用此属性后,子元素超 ...
随机推荐
- 深入浅出让你理解什么是LLVM
什么是LLVM 转载自https://www.jianshu.com/p/1367dad95445 LLVM项目是模块化.可重用的编译器以及工具链技术的集合. 美国计算机协会 (ACM) 将其2012 ...
- 手把手教你写DI_0_DI是什么?
DI是什么? Dependency Injection 常常简称为:DI. 它是实现控制反转(Inversion of Control – IoC)的一个模式. fowler 大大大神 "几 ...
- 题解-SHOI2005 树的双中心
SHOI2005 树的双中心 给树 \(T=(V,E)(|V|=n)\),树高为 \(h\),\(w_u(u\in V)\).求 \(x\in V,y\in V:\left(\sum_{u\in V} ...
- redis学习之——在分布式数据库中CAP原理CAP+BASE
分布式系统 分布式系统(distributed system) 由多台计算机和通信的软件组件通过计算机网络连接(本地网络或广域网)组成.分布式系统是建立在网络之上的软件系统.正是因为软件的特性,所以分 ...
- STM32系统时钟RCC(基于HAL库)
基础认识 为什么要有时钟: 时钟就是单片机的心脏,其每跳动一次,整个单片机的电路就会同步动作一次.时钟的速率决定了两次动作的间隔时间.速率越快,单片机在单位时间内所执行的动作将越多.时钟是单片机运行的 ...
- SpringBoot使用Mybatis-plus及分页功能的细节部分
pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...
- STL——容器(deque) 元素的存取&迭代器
1. deque 的数据存取 这个部分和 vector 几乎一样 第一 使用下标操作 dequeName[0] = 100; //小心越界 第二 使用at 方法 如: dequeName.at(2 ...
- Java 设计模式 —— 组合模式
在现实生活中,存在很多"部分-整体"的关系,例如,大学中的部门与学院.总公司中的部门与分公司.学习用品中的书与书包.生活用品中的衣服与衣柜.以及厨房中的锅碗瓢盆等.在软件开发中也是 ...
- MySQL01-数据库概述
1.概述 1.1 什么是数据库? 用于存储和管理数据的仓库. 1.2 数据库的特点: 1. 持久化存储数据的.其实数据库就是一个文件系统 2. 方便存储和管理数据 3. 使用了统一的方式操作数据库 - ...
- C#知识结构
C#知识结构 对于一个工作多年的程序员而言,接口.反射.索引器.事件.委托这些耳熟能详的词汇,提起来别说多简单了,但是让老司机坐在那一个人拿起一支笔,把脑海中对C#知识结构进行梳理一下,大抵是写不了多 ...