共计 3724 个字符,预计需要花费 10 分钟才能阅读完成。
欢送关注我的公众号:前端侦探
很多页面布局,特地是那种工具类的、比方编辑器、可视化平台等,为了充沛的利用屏幕空间,都会提供拖拽调节各个分栏尺寸的性能,比方像 vscode
形象开来,其实就是这样一个布局
你也能够先看实际效果:CSS 可拉伸分栏布局 2(codepen.io)
是不是非常灵活呢?其实纯 CSS 也是能够实现这样的成果的,一起看看吧
一、根本实现原理
实现这个成果须要借助 resize 个性,能够人造的实现元素拉伸个性。最常见的就是 textarea
,默认就是能够拉伸的
<textarea></textarea>
不过,咱们这里须要的不是 textarea
,而是一般的元素。一般的元素要实现这样的成果也很容易,只须要在overflow
不是 visible
的状况下,增加 resize
属性就行了
.resizable {
resize: both;
overflow: scroll;
}
原理就是这么简略,那么如何使用呢?
二、自定义右下角 resize
尽管看似能够拉伸,然而可拉伸范畴切实是太小了。该如何减少可拉伸范畴呢?这里有两种思路:
- 通过伪元素自定义
- 容器整体放大
先说第一种思路。要定义尺寸,首先须要搞明确 resize
指的是什么?通过简略的测试发现,在 chrome 中,resize
其实就是 横纵滚动条的交界处,比方间接设置滚动条的尺寸
::-webkit-scrollbar {
width: 20px;
height: 20px;
background-color: rosybrown;
}
当初将滚动条高度改大一点
::-webkit-scrollbar {
width: 20px;
height: 100px;
background-color: rosybrown;
}
能够看到 resize
也跟着变动了
当滚动条高度足够大时,右侧就变成整条都能够拉伸了
::-webkit-scrollbar {
width: 20px;
height: 100vh;
background-color: rosybrown;
}
而后,这个斜线条纹能够用伪元素 ::-webkit-resizer
来批改
div::-webkit-resizer{background-color: royalblue;}
不过遗憾的是,这种形式只适宜 -webkit-
浏览器,所以 firefox
就不行了。
上面来看第二种思路:整体放大。
这里说的整体放大,指的是将整个容器通过 transform
进行放大,这样一来,右下角的 resize
也会追随放大了,比方
div{
width: 300px;
height: 20px;
transform: scaleY(100);/* 足够大的放大倍数 */
overflow: scroll;
resize: horizontal;
}
这样也能达到整条侧边都能够拉伸的目标了。
上面来看理论利用吧
三、两栏拉伸布局
循序渐进,先实现两栏布局。比方这样
通常这类布局都有肯定的束缚,比方这里的 MAIN
是自适应空间的,SIDE
是固定尺寸,先疾速写出布局和款式
<div class="con">
<aside>
SIDE
</aside>
<main>
MAIN
</main>
</div>
要害款式如下
.con{display: flex;}
aside{width: 200px;}
main{flex: 1;}
那么,如何让右边侧边栏居右拖拽性能呢?很简略,将方才可拉伸的元素放入侧边栏,让宽度由外面的拉伸元素决定(flex 子元素人造反对该个性),内容着用相对定位笼罩来实现,实现如下
<aside>
<div class="resize"></div>
<div class="line"></div>
<section>SIDE</section>
</aside>
因为 firefox
的 resize
无奈自定义,所以这里独自一个标签来模仿拉伸轴
aside{
position: relative;
overflow: hidden;
}
.resize{
width: 200px;
height: 16px;
transform: scaleY(100);
overflow: scroll;
resize: horizontal;
opacity: 0;
}
.line{
position: absolute;
top: 0;
right: 0;
width: 4px;
bottom: 0;
background-color: royalblue;
opacity: 0;
transition: .3s;
pointer-events: none;
}
.resize:hover+.line,
.resize:active+.line{opacity: 1;}
这样就实现了右边侧边栏拉伸的性能
四、三栏拉伸布局
有时候会呈现两边侧边栏,两头局部是自适应的,如下
这种如何实现呢?首先依照两栏布局的思路
<div class="con">
<aside>
<div class="resize"></div>
<div class="line"></div>
<section>SIDE</section>
</aside>
<main>
MAIN
</main>
<aside class="right">
<div class="resize"></div>
<div class="line"></div>
<section>SIDE</section>
</aside>
</div>
不过这样会有一个很显著的问题,因为 resize
是在 右侧,如果放在左边侧边栏,那必定就相同了,具体表现就是,往右拉伸,右侧边栏反而增大,不合乎直觉
有没有什么方法让 resize
到右边来呢?
首先想到的是通过 翻转变换 ,程度方向上翻转能够scaleX(-1)
来实现,合并起来就是
.right .resize{transform: scale(-1, 100);
}
在 Chrome 下体现不错
然而,Firefox 就有点奇怪了
朝右边拖拽,右侧边栏宽度反而减少。究其原因,在 Firefox 上,transform
程度翻转仅仅扭转了视觉上的成果,并没有扭转交互行为,有没有方法能够真正扭转 resize
的地位呢?
还真有,不过仅能够扭转程度方向上的地位,通过 direction
属性。这是一个能够扭转文档方向流的属性,有些语言方向是从右往左的,所以设置后,resize
也从右侧变到了左侧。
所以实现就是
.right .resize{direction: rtl;}
这样下来,Chrome 和 Firefox 均失常了
残缺代码能够拜访:CSS 可拉伸分栏布局 (codepen.io)或者 CSS 可拉伸分栏布局 (juejin.cn)
五、其余组合分栏成果
组合分栏成果少不了垂直方向上的。
垂直方向的分栏和程度方向大同小异,只须要程度方向上缩放足够大就行了。
.resize-top{
width: 16px;
resize: vertical;
transform: scaleX(100);
}
当初能够尝试实现文章结尾布局成果
<div class="con">
<aside>
<div class="resize"></div>
<div class="line"></div>
<section>SIDE</section>
</aside>
<main>
<div class="main">
MAIN
</div>
<footer>
<div class="resize resize-top"></div>
<div class="line"></div>
<section>bottom</section>
</footer>
</main>
</div>
不过有个缺点就是,无奈通过 direction
或者其余伎俩,将 resize
真正地从下移到下面
只能通过 transform: scale(-1, 100);
实现了,这样就导致垂直方向上的拉伸在 Firefox 体验不佳。成果如下
Chrome 体现完满:
Firefox 体现差强人意:
残缺代码能够拜访:CSS 可拉伸分栏布局 2(codepen.io) 或者 CSS 可拉伸分栏布局 2(juejin.cn)
持续调整一下,还能够实现这样的布局成果
残缺代码能够拜访:CSS 可拉伸分栏布局 3(codepen.io) 或者 CSS 可拉伸分栏布局 3(juejin.cn)
六、总结一下
以上就通过纯 CSS 实现了 4 种常见的分栏拉伸成果,根本能满足常见的布局需要了,是不是十分实用呢?上面总结一些要点
- 实现原理是 CSS resize 属性
- resize 失效的条件是 overflow 不能是 visible
- resize 在 Chrome 下其实是横纵滚动条的交汇处,扭转滚动条尺寸能够扭转 resize 大小
- resize 还能够通过缩放整体容器来实现
- resize 默认是在右下角,能够通过程度翻转到左下角,Chrome 完满反对拉伸,Firefox 不行
- 还能够通过 direction 扭转文档流的形式,将 resize 从右下角变到左下角
- 垂直方向上 resize 只能通过 transform 翻转形式实现,因而 Firefox 体验较差
尽管 Firefox 在垂直方向上略有缺点,如果你对兼容性没太多需要,比方公司外部我的项目,Electron 利用等,那就放心大胆的应用吧,千万不要被兼容性解放了你的思维。最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤
欢送关注我的公众号:前端侦探