WebGL Tutorial
and more

Split.js Tutorial

撰写时间:2023-05-12

修订时间:2023-05-15

在标准HTML标签中,没有现成的分割条。开源软件Split.js可解决此问题。

Split.js分为Split, Split Grid, React Split, 以及React Split Grid共4种。本文介绍了前面两种的使用方法。

Split

Split应用于不使用CSS Grid的场合。

使用Split的CDN为:

<script src="https://unpkg.com/split.js/dist/split.min.js"></script>

Split水平分割

第1步:编写HTML代码。

(Some long texts...)

(Some long texts...)

(Some long texts...)

第2步:设置基本的CSS样式。

两个子元素都是div,是块状元素,默认情况下在网页中是上下排列。因此我们需要设置其CSS样式来水平排列。并且,对于水平排列的元素,如果内容太少,就无法显示水平分割条,因此,需要为它们的父容器指定一个初始高度值。

对于子元素,设置适当的值。

第3步:应用Split.js。

<script type="module"> Split(['#first', '#second'], { sizes: [25, 75] }); </script>

id分别为firstsecond的这两个元素添加一个水平滚动条,左右两个div的宽度分别设置为25%75%

现在运行网页。查看网页的DOM树:

abc
abc

Split.js使用width: calc(25%-5px)的样式来设置左边区块的宽度。25%是我们上面指定的宽度,默认水平滚动条的宽度值为10px,取一半为5px,用25%减去5px即得到左边区块的实际宽度。同样,用75%减去5px即得到右边区块的实际宽度。

第3行是Split.js自动添加的代码,其class属性值为gutter gutter-horizontal,其宽度为默认的10px

网页的DOM中已自动生成了元素,但在运行的网页中却看不到滚动条在哪,因此,需为其设置CSS样式。

第4步:显示滚动条。

.gutter { background-color: transparent; background-repeat: no-repeat; background-position: 50%; } .gutter.gutter-horizontal { cursor: col-resize; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg=='); }

再次运行网页。现在,滚动条已经显示出来。左右拉动滚动条,观察DOM中左右两个div的宽度如何变化。

Split垂直分割

基本实现

垂直分割条的HTML的代码与上一节完全一致。

(Some long texts...)

(Some long texts...)

(Some long texts...)

CSS部分:

在父容器仍需指定一个特定的高度。此外,滚动条把手的选择器变为.gutter.gutter-vertical,且背影图像内容不一样。

JavaScript脚本:

<script type="module"> Split(['#first', '#second'], { direction: "vertical", sizes: [25, 75] }); </script>

JavaScript初始化选项中多了一个direction: "vertical",用以指定上下的垂直分割。

运行网页。查看网页的DOM树:

abc
abc

上一节水平滚动条自动计算子元素的宽度,而垂直滚动条自动计算子元素的高度。

CSS盒模型的问题

从上面可以看出,Split.js将各元素的widthheight的属性值乘以特定的百分比以确定具体的宽度及高度。根据CSS盒模型的的特点,默认情况下,一旦各元素使用了padding属性或border属性后,将最终导致widthheight的变化。因此上一节的代码实际上是有些小问题的,但由于该代码的子元素没有设置borderpadding,因此问题没有暴露出来而已。

修改上一节的CSS部分,为父容器及子元素分别加入border属性:

div.split-container { height: 60vh; border: 1px solid red; } div.split-child { border: 1px solid var(--dark-border-color); overflow-y: auto; border: 1px solid yellow; }

父容器的边框为红色,子元素的边框为黄色。运行网页。红色与黄色边框较好地贴合在一起,似乎没问题。

现在,为子元素添加一个padding属性:

div.split-child { border: 1px solid var(--dark-border-color); overflow-y: auto; border: 1px solid yellow; padding: 0.5em; }

再次运行网页。发现子元素的黄色边框超出了父容器的红色边框。当我们往下手动滚动条时,子元素的内容则会在父容器的红色边框之外溢出。

解决此问题很简单,只需在子元素中设置box-sizing: border-box即可:

div.split-child { border: 1px solid var(--dark-border-color); padding: 0.5em; overflow-y: auto; border: 1px solid yellow; box-sizing: border-box; }

加入box-sizing: border-box的设置后,padding属性及border属性均自动包含在widthheight属性之内。这样,无论我们如何设置padding属性及border属性,均不会影响到最终的widthheight。运行网页,问题得以解决。

由此可见,在使用Split.js时,为子元素设置box-sizing: border-box这一点很重要!应牢牢记住这一点。

垂直滚动条最终版本

将相应的设置边框代码去掉,下面是垂直滚动条最后的版本:

<script type="module"> Split(['#first', '#second'], { direction: "vertical", sizes: [25, 75] }); </script>

运行网页。确保不出现任何问题。

Split同时进行水平与垂直分割

HTML代码:

Outline
Editor
Output

CSS代码:

div.split-vertical-container { width: 100%; height: 60vh; } div.split-horizontal-container { display: flex; flex-direction: row; width: 100%; } div.split-child { border: 1px solid var(--dark-border-color); padding: 0.5em; overflow-y: auto; box-sizing: border-box; } .gutter { background-color: transparent; background-repeat: no-repeat; background-position: 50%; } .gutter.gutter-horizontal { cursor: col-resize; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg=='); } .gutter.gutter-vertical { cursor: row-resize; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFAQMAAABo7865AAAABlBMVEVHcEzMzMzyAv2sAAAAAXRSTlMAQObYZgAAABBJREFUeF5jOAMEEAIEEFwAn3kMwcB6I2AAAAAASUVORK5CYII='); }

JavaScript代码:

<script type="module"> Split(['#vert-child-a', '#vert-child-b'], { direction: "vertical", sizes: [75, 25], gutterSize: 12 }); Split(['#outline', '#editor'], { direction: "horizontal", sizes: [25, 75] }); </script>

水平滚动条默认宽度为10,垂直滚动条默认高度也是10,但当同时使用水平与垂直滚动条时,默认值下的两个滚动条的比例看起来有点不一致。此时可用gutterSize予以微调。

运行网页

Split Grid

Split Grid可用于使用了CSS Grid的场合。

使用Split Grid的CDN为:

<script src="https://unpkg.com/split-grid/dist/split-grid.min.js"></script>

Split Grid水平分割

Split Grid的用法与Split稍微有所不同。Split Grid的gutter不会自动添加到DOM中,需要我们显式地在HTML中添加。

Column One
Column Two

并且在JavaScript代码中直接引用该gutter

<script type="module"> Split({ columnGutters: [{ track: 1, element: document.querySelector('#gutter') }] }); </script>

上面的track是Split Grid自定义的名称,与CSS Grid的track的含义不一样。track不能省略。上面取值规则是:将所有的子元素都视为索引值从0开始的track,上面idgutter的元素是第2个子元素,因此其索引值为1。

如果指定索引值错误,将不能拖动分割条,且在Console中报错。因此当出现不能拖动分割条的情况时,注意检查Console的输出,并及时予以修改。

设置CSS样式:

运行网页。在我们拖动分割条时,Split Grid会在CSS Grid的父容器中动态生成以下代码:

Column One
Column Two

可见,Split Grid将我们所设置的grid-template-columns: 1fr 10px 3fr;设置为父容器的内联CSS,并动态修改其值。

目前Split Grid支持在grid-template, grid-template-columns, grid-template-rows设置的值有:

  1. fr
  2. px
  3. %
  4. repeat

暂不支持的值有:

  1. auto
  2. 其他CSS值(em, vmin, cm, etc)

Split Grid动态代码不会修改gutter的代码,由于我们只为其class属性指定了gutter-horizontal的值,因此在设置CSS时,如上所示,需将gutter所有的设置值都包含进来:

Split Grid垂直分割

明白了上一节Solit Grid水平分割的原理,实现Split Grid垂直分割就相对容易了:

HTML代码:

Row One
Row Two

CSS代码:

JavaScript代码:

<script type="module"> Split({ rowGutters: [{ track: 1, element: document.querySelector('#gutter') }] }); </script>

运行网页

Split Grid水平与垂直分割

HTML代码:

Column One
Column Two
Row 2

CSS代码:

JavaScript代码:

<script type="module"> Split({ columnGutters: [{ track: 1, element: document.querySelector('#gutter-1') }], rowGutters: [{ track: 1, element: document.querySelector('#gutter-2') }] }); </script>

运行网页

参考资源

  1. Split.js
  2. MDN box-sizing