首页 > 其他分享 >使用 CSS columns 布局来实现自动分组布局

使用 CSS columns 布局来实现自动分组布局

时间:2024-05-06 09:55:53浏览次数:23  
标签:滚动 column 布局 分组 CSS columns

最近在项目中碰到这样一个布局,有一个列表,先按照 4 * 2 的正常顺序排列,当超过 8 个后,会横向重新开始 4 * 2 的布局,有点像一个个独立的分组,然后水平排列,如下

图中序号是 dom 序列,所以其实这这样的一个顺序

很多同学可能会想到给子元素分组(通过 JS将原数组拆分组合成一个二维数组),每 8 个套一层容器,然后水平排列就行了

是不是有点麻烦呢?

其实,无需单独嵌套容器也能实现类似分组的效果,这就需要借助本文要介绍的 column 布局了,一起看看吧\~

一、简单介绍一下 columns

平时接触较多的都是flex或者grid,但还有一个columns布局往往被忽视了。

https://developer.mozilla.org/zh-CN/docs/Web/CSS/columns

columns布局,又称“多列”布局(或者“分栏”布局),这是一个使用场景比较有限,但是几乎无法被替代的一种布局。

使用非常简单,直接看一个例子,假设有这样一段文本

p{
  width: 500px;
}
<p>欢迎关注前端侦探,这里有一些有趣的、你可能不知道的HTML、CSS、JS小技巧技巧,比如这篇文章,如何使用 CSS columns 布局来实现自动分组布局,一起看看吧</p>

默认是这样的

下面我们将段文本分成3列

p{
  columns: 3;
}

看,自动就分成了3列

并且阅读顺序是从左到右,从下到下,直到整列阅读完成,非常类似以前的报刊读物阅读习惯。

除了指定列数,还可以根据指定宽度自动去计算列数,比如

p{
  columns: 100px;
}

效果如下

这个表示按照最小100px去分段,看最多可以分成多少列,并不是说每列就一定是 100,应该是大于等于 100,直到剩余空间可以再放下一列。

那为啥设置的是100,总宽度是500,却只分成了4列?原因是有默认列间距,如果去除这个间距

p{
  column-gap: 0px;
}

这样就刚好被分成了5

看不清楚?加个分割线试试

p{
    column-rule: 1px solid red;
}

是不是刚好分成了 5 列?(注意,这里的分割线是不占空间的)

简单了解columns多列布局后,下面来看另外的用途

二、columns 实现横向分组布局

可能你已经发现了,上面的文本分列布局和我们文章开头所需要的效果非常类似,都是一列一列的,因此我们可以尝试用columns布局来实现这样的效果

假设html是这样的

<div class="wrap">
  <div class="list">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
    <div class="item">10</div>
    <div class="item">11</div>
    <div class="item">12</div>
    <div class="item">13</div>
    <div class="item">14</div>
  </div>
</div>

这里多了一层wrap是用来做滚动容器的,简单修饰一下

.wrap{
  display: flex;
  width: 400px;
  overflow: auto;
  outline: 1px dashed #9747FF;
}
.item{
  display: inline-flex;
  width: 80px;
  margin: 10px;
  aspect-ratio: 1/1;
  background: #FFE8A3;
  color: #333;
  font-size: 30px;
  border-radius: 10px;
  align-items: center;
  justify-content: center;
}

效果如下,很正常的一个布局

现在,我们希望纵向高度是固定的,然后横向滚动,先加一个高度试试

.list{
  height: 200px;
}

这样就变成了纵向滚动的布局了

那么,如何让它横向分栏并且滚动呢?其实非常简单,只需要添加一行

.list{
  height: 200px;
  column-width: 400px;
}

设置分栏宽度为滚动容器宽度之后,就自动将整个列表分成多组了,相当于每个滚动屏幕作为一组,从左到右排列,由于空间不足,所以可以横向滚动

是不是非常神奇?仅需一个属性就实现了纵向滚动到横向滚动的切换

三、借助 scroll-snap 实现轮播效果

通常碰到这种横向滚动的效果,你可能会想到一个swiper组件,也就是那种一屏一屏切换的效果,没错,我们这里也可以借助scroll-snap轻易实现。

关于scroll-snap,网上教程非常多,MDN 官网也有非常清晰的 demo,如果不熟悉的可以先去了解一下:https://developer.mozilla.org/zh-CN/docs/Web/CSS/scroll-snap-type

这里就不详细介绍了。

回到这里,由于整个列表下面只有一层子元素,好像并没有办法区分每一屏的临界点。其实不然,可以想一下,这里每一屏有 8 个元素,也就是第1917...个分别是每一屏的第一个元素,是不是可以以这些元素为标识(吸附对象)呢?

首先要在滚动容器下定义一下

.wrap{
  scroll-snap-type: x mandatory;
}

然后给第1917...个元素添加吸附对象,这里可以用nth-child选择器

.item:nth-child(8n+1){
  scroll-snap-align: start;
}

效果如下(为了区分,把每一屏的第一个元素背景做了高亮)

四、CSS 实现的优势和总结

相对于传统的 JS实现来说,有哪些好处呢?

  1. 少了一层嵌套容器,业务逻辑会更加干净
  2. 自适应强,可以根据需求选择固定列数或者固定宽度,JS往往只能根据数量去分组
  3. 不会报错,想想看,JS中的数组经常会出现xxx.slice is not function这样的错误,轻则警告,总则整个页面白屏
  4. 布局足够灵活,想横向滚动就横向滚动,想纵向滚动就纵向滚动,而JS方式往往还需要改变数组形态

有这么多好处还不赶紧用起来?下面再来回顾一下columns布局

  1. columns布局,又称“多列”布局(或者“分栏”布局),可以将默认的文本流轻易分成多栏,非常类似以前的报刊读物排版
  2. column可以通过宽度(column-width)去自动分割,或者通过指定数量(column-count)将布局分成多少栏
  3. column-gap可以设置分栏之间的空隙,默认是有间隔的
  4. column-rule可以设置分隔线,这种分割线是不占据空间的
  5. columns布局使用场景比较有限,但是几乎无法被替代

标签:滚动,column,布局,分组,CSS,columns
From: https://www.cnblogs.com/moranjl/p/18103147

相关文章

  • CSS 盒模型
    在css中,所有元素都被一个个的"box"包围着,理解这些盒子的基本原理,是实现用css实现精准布局,处理元素排列的关键.标准盒模型盒子模型的组成元素:content:内容区padding:内天成border:边框margin:外边距在标准盒模型中,盒的width/height指......
  • 网页布局------轮播图效果实现
    纯css实现轮播图可以看这里:纯css实现轮播图(自动轮播和手动轮播)效果_☆*往事随風*☆的博客_css轮播图-CSDN博客代码来源:html+css+jquery实现轮播图自动切换、左右切换、点击切换_jquery图片轮播幻灯片效果实现左右滚动图片切换代码-CSDN博客JS实现轮播图的三种简单方法。_js轮播......
  • solid在css中什么意思
    solid在CSS中的含义在CSS中,solid是一个用于定义边框样式的关键词。作用solid用于创建一个具有实线边框的元素。实线边框是一种连续且不间断的线条,将其应用于元素周围可强调或定义其边界。语法该关键词用于border-style属性,它用于设置元素边框的样式。该属性的语法如......
  • 2024-05-04 css实现鼠标移动至盒子,盒子在约定时间内进行放大缩小
    放大缩小css@keyframesscaleAnimation{0%{transform:scale(1);}50%{transform:scale(1.2);}100%{transform:scale(1);}}完整代码:<!DOCTYPEhtml><htmllang="en"><head><metacharset=&q......
  • CSS & JS Effect – 用 wheel 模拟 scroll
    前言在用JavaScript实现positionsticky 文章中,我提到了用wheel来模拟scroll效果。这篇来说说具体怎么实现,挺简单的哦。 Preparationtable.html<divclass="container"><table><thead><tr><th>FirstName</th>&l......
  • flex 布局
    基本使用:  父容器的设置:  display:flex,默认主轴为row(横轴),父容器内的子元素会横向排列。  flex-direction:row|row-reverse。改变主轴方向使用属性。  justify-content:center,子元素主轴方向居中。  align-item:center,子元素在交叉轴方向居中。    该属性下其......
  • css-布局-calc()
    <divstyle="display:flex;"><div><menu_left/></div><divstyle="flex-grow:1;"><tables:table_title="table_title":table_content="table_content"@type......
  • CSS Custom Highlight API
    CSSCustomHighlightAPICSSCustomHighlightAPIJavaScript创建范围并使用CSS定义样式来设置文档中任意文本范围的样式该API允许开发者通过CSS自定义属性来设置文本的样式,并将其应用到文档中的任意文本范围。本质就是查找所有文本节点,收集匹配内容的Range,最后......
  • CSS Counter Styles
    CSSCounterStyles允许您自动对HTML文档中的元素进行编号或标记。我们定义一个具有特定名称和起始值的counter,然后根据CSS规则递增或递减该计数器。使用counter-reset属性定义计数器,设置其起始值,然后使用counter-increment属性根据需要递增或递减计数器。还可以使......
  • css中内容content部分垂直居中的方法
     1、vertical-align属性让文字居中  vertical-align值有很多,常用的就是middle,bottom,text-bottom等,然而真实使用的时候,我们会发现这个属性“时灵时不灵”,有些情况下我们加了这个属性之后仍然不见img或者text有任何的变化。那是因为vertical-align只作用在inline-block或者inl......