浅析使用css实现可拉伸调整尺寸的分栏布局:基本实现原理、自定义resize容器范围、实际应用

一、基本实现原理

  最常见的 textarea,默认是可以拉伸的。textarea 我们可以随便拉伸,那么要实现任意元素都有这个效果怎么办呢?

  需要借助 resize 特性,可以天然的实现元素拉伸特性。普通的元素要实现这样的效果也很容易,只需要在 overflow 不是 visible 的情况下,添加 resize 属性就行了

.resizable {
  resize: both;
  overflow: scroll;
}

  加上这个属性后,我们实现了随意拉伸。虽然可以拉伸,但是可拉伸范围实在是太小了。该如何增加可拉伸范围呢?

二、自定义 resize 范围

  这里有两种思路:(1)通过伪元素自定义(2)容器整体放大

1、伪元素自定义

  先说第一种思路。要定义尺寸,首先需要搞明白 resize 指的是什么?经过简单的测试发现,在 chrome 中,resize 其实就是横纵滚动条的交界处,比如直接设置滚动条的尺寸

::-webkit-scrollbar {
  width: 20px; 
  height: 20px;
  background-color: rosybrown;
}

  当滚动条高度足够大时,右侧就变成整条都可以拉伸了。

  然后,这个斜线条纹可以用伪元素 ::-webkit-resizer 来修改

div::-webkit-resizer{
  background-color: royalblue;
}

  不过遗憾的是,这种方式只适合 -webkit- 浏览器,所以火狐就不行了。

2、resize 容器整体放大

  这里说的整体放大,指的是将整个容器通过 transform 进行放大,这样一来,右下角 resize  也会跟随放大了,比如

div{
  width: 300px;
  height: 20px;
  transform: scaleY(100);/*足够大的放大倍数*/
  overflow: scroll;
  resize: horizontal;
}

  这样也能达到整条侧边都可以拉伸的目的了。

三、实际应用

  实现两栏布局,如这样:

1、两栏布局,其核心原理就是:看看结构就懂了

<body>
  <div class="flex">
    <aside>
      <div class="resize"></div>
      <div class="line"></div>
      <section>SIDE</section>
    </aside>
    <main>MAIN</main>
  </div>
</body>

  line 决定定位用于标识可拖动线条区域

  resize 用于标识 resize 容器,然后 scale(100) 扩大可改变尺寸区域,设置 opacity: 0 全透明,故不会遮盖 section 具体内容咯

  aside 相对定位所以其宽度会随 resize 的宽度自适应咯

2、三栏布局,一样看结构就懂了

<body>
  <div class="flex">
    <aside class="left">
      <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>
</body>

(1)但是有个问题:由于 resize 是在右侧,如果放在右边侧边栏,那肯定就相反了,具体表现就是,往右拉伸,右侧边栏反而增大,不符合直觉

  有没有什么办法让 resize 到左边来呢?

  首先想到的是通过翻转变换,水平方向上翻转 可以 scaleX(-1) 来实现,合并起来就是

    .left .resize{
      transform: scaleY(100);
    }
    .right .resize{
      transform: scale(-1, 100);
    }
    .right .line{
      left: 0;
    }

  注意上面我标的那个高度差就是 resize 容器设置的初始高度咯

(2)FF 兼容性问题:在 Chrome 下表现不错,但是,Firefox 就有点奇怪了,朝右边拖拽,右侧边栏宽度反而增加。

  究其原因,在 Firefox上,transform 水平翻转仅仅改变了视觉上的效果,并没有改变交互行为,有没有办法可以真正改变 resize 的位置呢?

  还真有,不过仅可以改变水平方向上的位置,通过 direction 属性。这是一个可以改变文档方向流的属性,有些语言方向是从右往左的,所以设置后,resize 也从右侧变到了左侧。

  所以实现就是:

    .right .resize{
      direction: rtl;
    }
    .right .line{
      left: 0;
    }

  上面那个 left 的写法都不需要了,挺方便的。这样下来,Chrome 和 Firefox 均正常了

3、其他分栏效果,按上述知识合理应用即可

  总结:

  1. 实现原理是 CSS resize 属性
  2. resize 生效的条件是 overflow 不能是 visible
  3. resize 在 Chrome 下其实是横纵滚动条的交汇处,改变滚动条尺寸可以改变 resize 大小
  4. resize 还可以通过缩放整体容器来实现
  5. resize 默认是在右下角,可以通过水平翻转到左下角,Chrome 完美支持拉伸,Firefox 不行
  6. 还可以通过 direction 改变文档流的方式,将 resize 从右下角变到左下角
  7. 垂直方向上 resize 只能通过 transform 翻转方式实现,因此 Firefox 体验较差

 

posted @ 2021-06-08 21:54  古兰精  阅读(872)  评论(0编辑  收藏  举报