如何不使用 overflow: hidden 实现 overflow: hidden?

一个颇有意思的题目。如何不使用 overflow: hidden 实现 overflow: hiddencss

CSS 中 overflow 定义当一个元素的内容太大而没法适应块级格式化上下文时候该作什么。而 overflow: hidden 则会将超出容器范围内的内容剪裁。前端

控制 overflow: hidden 的方向

这源自一个实际的需求,在某个需求当中,要求容器内的内容,在竖直方向上超出容器会被裁剪,而在水平方向上超出容器,则不会被裁剪。相似这样:git

1 上午10.26.03.gif

有意思,第一个想到的解法固然是在上述黄色背景元素自己以外再套用一层父元素,而后父元素才是实际设置 overflow: hidden 的元素,父元素的范围就是实际才是控制是否裁剪的范围。相似这样:github

2 上午10.26.03.gif

实际的父元素才是设置了 overflow: hidden 的元素。web

固然,若是实际状况就是这么简单,也没什么问题。浏览器

可是若是元素处于一个复杂的布局流内,那么可能就没有那么多的空间,让咱们再去包裹一层父容器了:布局

3 上午10.26.03.png

相似上图的状况,仍是中间黄色元素,要求只有竖直方向超出裁剪。此时,包裹父元素再也不那么容易施展。因此,咱们须要另辟蹊径。网站

利用 clip-path 进行裁剪

好的,这会能够进入正文了。CSS 中,除了 overflow: hidden,仍是有其它属性也能够实现超出容器区域进行裁剪的。clip-path 即是其中翘楚。google

使用 clip-path,咱们能够方便的控制任意方向上的裁剪。上述的需求则能够这样解决:spa

<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 支持负坐标的特色,将裁剪的起点定到远离坐标能画成一个大矩形的形状。示意图:

4 上午10.26.03.png

这样,咱们可以在正常布局流中,当前容器大小范围内,画出任意但愿 overflow: hidden 的范围。

你能够点进 Demo 里面尝试下:

CodePen -- Clip-path overflow

再举两个例子:

{
    // 裁剪出左右两边都 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 的裁剪方式

那么。经过上面的一个小例子,咱们知道了 overflowclip-path 能够裁剪区域。那么除了这两个,CSS 中还有没有能够进行区域裁剪的元素呢?

有,还有一个有意思的元素,就是 -- contain

contain 属性容许咱们指定特定的 DOM 元素和它的子元素,让它们可以独立于整个 DOM 树结构以外。目的是可以让浏览器有能力只对部分元素进行重绘、重排,而没必要每次都针对整个页面。

这里不具体去介绍它的每一个属性,感兴趣的能够翻看下这篇文章 -- CSS新特性contain,控制页面的重绘与重排

contain: paint 进行内容裁剪

详细说说 contain: paint,设定了 contain: paint 的元素便是开启了布局限制,也就是说,此元素的子元素不会在此元素的边界以外被展现。

contain: paint 属性产生的目的,便是为加快页面的渲染,在非必要区域,不渲染元素。所以,若是元素不在屏幕上或以其余方式设定为不可见,则其后代不可见不被渲染。
.g-container {
    contain: paint;
}

看看示例:

5 上午10.26.03.gif

CodePen Demo -- contain: paint Demo

contain: paint 的反作用

contain: paint 的本意是用于提高页面的渲染,裁剪到容器以外的元素不进行渲染。可是使用它会产生一些反作用:

  1. 它会生成一个本身的新的堆叠上下文(It becomes a stacking context),也就是说,它会改变它的子元素的 absolute 定位和 fixed 定位的基准;
  2. 它会成为新的格式化上下文(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

固然,它们之间仍是有一些差别:

  1. overflow: hiddencontain: paint 会建立一个 BFC,而clip-path不会,它只是单纯的裁剪
  2. 兼容性间的差别

因此也就是说,CSS 不只仅只有 overflow: hidden 实现 overflow: hidden,不少状况,能够灵活使用。

牛刀小试

再来个有意思的环节,在 一行 CSS 代码的魅力 中,提到了 CSS Battle

这个网站是核心玩法就是:官方给出一张图形,在给定的 400 x 300 的画布上,可以用越短的代码实现它,分数就越高

上次讲了一题经过一行 CSS 代码实现,今天,咱们再来看看第二题

6 上午10.26.03.png

怎么用最短的代码实现它呢?想一想今天说的 clip-path

首先,咱们利用这一一段代码,生成这样一个图形:

<style>
body {
    margin: 0 50px;
    background: #62374e;
    border: 50px dashed #fdc57b;
}

7 上午10.26.03.png

而后,利用 clip-path,把上下两部分裁掉便可。

<style>
body {
    margin: 0 50px;
    background: #62374e;
    border: 50px dashed #fdc57b;
  + clip-path: polygon(0 50px, 100% 50px, 100% 250px, 0 250px);
}

6 上午10.26.03.png

这样就完美实现啦。固然,如今字符数有点多,有 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 切割掉多余部分

最后

好了,本文到此结束,但愿对你有帮助 :),想 Get 到最有意思的 CSS 资讯,千万不要错过个人公众号 -- iCSS前端趣闻 😄

qrcode.png

更多精彩 CSS 技术文章汇总在个人 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

若是还有什么疑问或者建议,能够多多交流,原创文章,文笔有限,才疏学浅,文中如有不正之处,万望告知。

相关文章
相关标签/搜索