css响应式网格布局生成器_如何使用网格布局模块使用纯CSS创建响应表

css响应式网格布局生成器

TL; DR (TL;DR)

The most popular way to display a collection of similar data is to use tables, but HTML tables have the drawback of being difficult to make responsive.

显示相似数据集合的最流行方法是使用表,但是HTML表具有难以响应的缺点。

In this article, I use CSS Grid Layout Module and CSS Properties (and no Javascript) to layout tables that wrap columns depending on screen width, which further changes to a card based on layout for small screens.

在本文中,我将使用CSS网格布局模块和CSS属性(而不是Javascript)来布局表,这些表根据屏幕宽度来包装列,而这些表格会根据小屏幕的布局进一步更改为卡片。

For the impatient, look at the following pen for a prototypical implementation.

对于不耐烦的人,请看下面的笔以作为原型实现。

响应式HTML表的一点历史 (A Little History of Responsive HTML Tables)

Responsive tables aren’t a new topic, and there are many solutions that have already been proposed. “Responsive Table Data Roundup” first published in 2012 by Chris Coyier, has things summarized very neatly (including a 2018 update).

响应表并不是一个新话题,已经提出了许多解决方案。 克里斯·科耶尔(Chris Coyier)于2012年首次发布了“响应表数据综述” ,内容总结得非常整洁(包括2018年更新)。

“Really Responsive Tables using CSS3 Flexbox” by Vasan Subramanian shows an idea of wrapping columns, implemented with Flexbox.

Vasan Subramanian的“使用CSS3 Flexbox的真正响应表”展示了使用Flexbox实现的包装列的想法。

Even though many interesting ideas have been proposed, libraries like bootstrap opt for horizontal scrolling for small screens.

即使已经提出了许多有趣的想法,诸如引导程序之类的库仍选择对小屏幕进行水平滚动。

As we now have CSS Grid, I think we could have a better common alternative to horizontal scrolling.

现在我们有了CSS Grid,我认为我们可以有一个更好的通用替代方法来进行水平滚动。

HTML表格 (HTML Tables)

Starting with the basics, a table in HTML is a layout format for displaying collections of items through a matrix of rows and columns. Items are laid out in rows, with the same data attributes in the same columns, with the rows often sorted with one or more sortable attributes. The format gives you a birds-eye view to quickly grasp and examine large quantities of data.

从基础开始,HTML表格是一种布局格式,用于通过行和列的矩阵显示项目的集合。 项目按行排列,在同一列中具有相同的数据属性,并且这些行通常使用一个或多个可排序的属性进行排序。 该格式使您可以鸟瞰,以快速掌握和检查大量数据。

For example, here’s a hypothetical table of purchase order details, that you may see in a purchasing application.

例如,这是假设的采购订单详细信息表,您可能会在采购应用程序中看到该表。

An item, in this case, is a purchase order detail, that has attributes such as part number, part description, etc.

在这种情况下,物料是采购订单明细,具有零件编号,零件描述等属性。

When using HTML tables, the layout of the data is hardcoded as rows and columns (e.g. <tr> and <td>). This may be sufficient for usage by a screen that fits the whole table width, but in reality, this does not apply for the myriad of devices that exist today. In terms of hacks, you can alter the display property of tables and use any layout you can do with CSS in general, but that doesn’t seem semantically correct.

使用HTML表时,数据的布局被硬编码为行和列(例如<tr><td> )。 对于适合整个桌子宽度的屏幕来说,这可能就足够了,但实际上,这不适用于当今存在的众多设备。 就黑客而言,您可以更改表的显示属性,并使用通常可以使用CSS进行的任何布局,但这在语义上似乎并不正确。

重新定义表(=项目集合) (Tables Redefined (= Collection of Items))

Let’s start by redefining how table data should be expressed in HTML.

让我们重新定义表数据应如何以HTML表示。

As stated earlier, since table data is essentially an ordered collection of items, it seems natural to use ordered lists. Also, since tables are often used to supplement textual descriptions, it seems natural to enclose this in a section, but this would depend on the context of how the table data is being used.

如前所述,由于表数据本质上是项目的有序集合,因此使用有序列表似乎很自然。 另外,由于经常使用表格来补充文字说明,因此将其括在一节中似乎很自然,但这取决于表格数据的使用方式。

<section>
 <ol>
  <!-- The first list item is the header of the table -->
  <li>
   <div>#</div>
   <!-- Enclose semantically similar attributes as a div hierarchy -->
   <div>
    <div>Part Number</div>
    <div>Part Description</div>
   </div>
   ...
  </li>
  <!-- The rest of the items in the list are the actual data -->
  <li>
   <div>1</div>
   <!-- Group part related information-->
   <div>
    <div>100-10001</div>
    <div>Description of part</div>
   </div>
  ...
  </li>
 ...
 </ol>
</section>

Vanilla <div>'s are used to express item attributes since HTML5 does not define an appropriate tag for this. The key here is to express semantically similar attributes as a hierarchy of <div>'s. This structure will be used when defining how the data should be laid out. I will come back to this in the next section on the topic of styling.

Vanilla <div>用于表示项目属性,因为HTML5并未为此定义适当的标签。 此处的关键是将语义上相似的属性表示为<div>的层次结构。 在定义数据布局方式时将使用此结构。 我将在下一节有关样式的主题中再次谈到这一点。

As for the actual data inside the <div> element, the first item in the list is the header, and the rest of the items are the actual data.

至于<div>元素中的实际数据,列表中的第一项是标题,其余项是实际数据。

Now, it’s time to start talking about styling the items with CSS Grid.

现在,该开始讨论使用CSS Grid设置样式的时间了。

样式项集合 (Styling Item Collections)

The basic idea here is to display all attributes of the item as a normal table, display width permitting. This layout has the luxury of being able to see as many items (rows) as possible.

这里的基本思想是在宽度允许的情况下,将项目的所有属性显示为普通表。 这种布局的奢华之处在于可以看到尽可能多的项目(行)。

When the width of the display becomes narrower, some attributes are stacked vertically, in order to save horizontal space. The choice of stacking attributes should be based on:

当显示器的宽度变窄时,一些属性会垂直堆叠,以节省水平空间。 堆叠属性的选择应基于:

  1. Do the attributes make sense when stacked vertically? and,

    垂直堆叠时这些属性有意义吗? 和,
  2. When stacked vertically, does it save horizontal space?

    垂直堆叠时,是否节省水平空间?

When the width further shrinks to the size of a mobile device, each item is displayed as a card. This layout has redundancy because the attribute names are repeatedly displayed on each card, and has the least glanceability, but does not compromise usability (e.g. horizontal scrolling, super small text, etc).

当宽度进一步缩小到移动设备的大小时,每个项目都显示为卡。 这种布局具有冗余性,因为属性名称重复显示在每张卡上,扫视性最低,但不会损害可用性(例如,水平滚动,超小文本等)。

Now let’s dive into the details.

现在让我们深入研究细节。

样式步骤1:完整表格 (Styling Step 1: Full Table)

Here’s a visual summary of how things will be implemented with CSS Grid.

这是有关如何使用CSS Grid实现事物的直观总结。

In order to make columns wrap, multiple grid containers are defined as a hierarchy. The red box is a grid container for each row, and the blue box is a container for each column group that wraps.

为了使列换行,将多个网格容器定义为一个层次结构。 红色框是每一行的网格容器,蓝色框是每个要包装的列组的容器。

Let’ s start by setting the list as a grid container by defining a class called .item-container and applying it to the <li>(the red box).

首先,通过定义一个名为.item-container的类并将其应用于<li> (红色框),将列表设置为网格容器。

.item-container {
    display: grid;
    grid-template-columns: 2em 2em 10fr 2fr 2fr 2fr 2fr 5em 5em;
}

The number of explicit columns specified with grid-template-columns is nine, which is the number of top-level <div>'s, directly  under <li>.

grid-template-columns columns指定的显式列的数目为9,这是直接在<li>下的顶级<div>的数目。

The column’s width is defined in relative length to make the columns wrap. The actual fraction has to be fine-tuned, based on the content.

列的宽度以相对长度定义,以使列自动换行。 实际分数必须根据内容进行微调。

The columns that don’t wrap are defined in absolute length to maximize width usage for the wrapping columns. In the purchase order details example, the second column is a two-digit Id, so I set the width to double that size of 2 m’s.

不换行的列以绝对长度定义,以最大程度地利用换行列的宽度。 在采购订单详细信息示例中,第二列是两位数的ID,因此我将宽度设置为2 m的两倍。

Next, we define another grid container called .attribute-container and apply it on all intermediate <div>’s under the list (the blue box).

接下来,我们定义另一个名为.attribute-container网格容器,并将其应用于列表下方的所有中间<div> (蓝色框)。

.attribute-container {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(var(--column-width-min), 1fr));
    }

The minimum column width for all grid items under .attribute-container is specified with a CSS variable called --column-width-min(more on this later) using the minmax function, with the maximum set to take the rest of the space (e.g. one fraction). Since grid-template-columns are repeated, available horizontal space will be split into the maximum number of columns that could take at least --column-width-min, and the rest of the columns would go to the next line. The column’s width will be stretched if there is excess horizontal space because the repeat is auto-fited.

.attribute-container下所有网格项目的最小列宽是使用minmax函数通过名为--column-width-minCSS变量指定的(稍后会详细介绍),最大值设置为占用其余空间(例如一小部分)。 由于repeat grid-template-columns ,因此可用的水平空间将被划分为最多可占用--column-width-min的最大列数,其余列将进入下一行。 如果有多余的水平空间,则列的宽度将被拉伸,因为repeatauto-fit

造型步骤2:包装桌 (Styling Step 2: Wrapping Table)

Next, --column-width-min needs to be specified independently for each column in order to wrap. Just to be clear, the variables need to be specified in order for the full table to render properly as well. To do this, a class is set for each .attribute-container, and a different --column-width-min is specified for each class scope.

接下来,需要为每列分别指定--column-width-min以便进行包装。 为了清楚起见,还需要指定变量,以便完整表也能正确呈现。 为此,为每个.attribute-container设置一个类,并为每个类范围指定不同的--column-width-min

Let’s take a look at the HTML where .part-id is applied,

让我们看一下应用了.part-idHTML,

<div class="attribute-container part-id">
    <div>Part Number</div>
    <div>Part Description</div>
</div>

and the CSS:

和CSS:

.part-id {
    --column-width-min: 10em;
}

This specific grid container will have two columns, as long as the available width is wider than 10em for each grid item (e.g. the grid container is wider than 20em). Once the grid container’s width becomes narrower than 20em, the second grid item will go to the next row.

只要每个网格项的可用宽度大于10em(例如,网格容器的宽度大于20em),则此特定的网格容器将具有两列。 一旦网格容器的宽度变得小于20em,第二个网格项将转到下一行。

When we combine CSS properties like this, we need only one grid container .attribute-container, with the details changing where the class is applied.

当我们像这样组合CSS属性时,我们只需要一个网格容器.attribute-container ,详细信息就会更改应用类的位置。

We can further nest .attribute-containers, to have multiple levels of wrapping with different widths, as in the following exert.

我们可以进一步嵌套.attribute-container ,以具有不同宽度的多层包装,如下文所述。

<div class="attribute-container part-information">
    <div class="attribute-container part-id">
        <div class="attribute" data-name="Part Number">Part Number</div>
        <div class="attribute" data-name="Part Description">Part Description
    </div>
    </div>
    <div class="attribute-container vendor-information">
        <div class="attribute">Vendor Number</div>
        <div class="attribute">Vendor Name</div>
    </div>
</div>
.part-information {
    --column-width-min: 10em;
}
.part-id {
    --column-width-min: 10em;
}
.vendor-information {
    --column-width-min: 8em;
}

All of the above is enclosed in the following media query. The actual breakpoint should be selected based on the width necessary when your table is wrapped to the extreme.

以上所有内容都包含在以下媒体查询中。 实际断点应根据将表包装到最末端时所需的宽度来选择。

@media screen and (min-width: 737px) {
...
}
样式三:卡片布局 (Styling Step Three: Card Layout)

The card layout will look like a typical form with attribute names in the first column and attribute values in the second column.

卡片布局看起来像是一种典型的形式,第一列具有属性名称,第二列具有属性值。

To do this, a class called .attribute is defined and applied to all leaf <div> tags under the <li>.

为此,定义了一个名为.attribute的类,并将其应用于<li>下的所有叶子<div>标记。

.attribute {
    display: grid;
    grid-template-columns: minmax(9em, 30%) 1fr;
}

The attribute names are taken from a custom attribute of the leaf  <div> called data-name, for example <div class=”attribute” data-name="Part Number">, and a pseudo-element is created. The pseudo-element will be subject to the grid container’s layout.

属性名称取自名为<div> data-name <div> data-name的叶子<div>的自定义属性,例如<div class=”attribute” data-name="Part Number"> ,并创建了一个伪元素。 伪元素将服从网格容器的布局。

.attribute::before {
    content: attr(data-name);
}

The first item in the list is the header and does not need to be displayed.

列表中的第一项是标题,不需要显示。

/* Don't display the first item, since it is used to display the header for tabular layouts*/
.collection-container>li:first-child {
    display: none;
}

And finally, the cards are laid out in one column for mobile devices, but two for screens with a little bit more width, but not enough for displaying a table.

最后,这些卡在移动设备的一列中布局,但在宽度稍大一点的屏幕上却布局了两列,但不足以显示一张桌子。

/* 2 Column Card Layout */
@media screen and (max-width: 736px) {
    .collection-container {
        display: grid;
        grid-template-columns: 1fr 1fr;
        grid-gap: 20px;
    }
...
}
/* 1 Column Card Layout */
@media screen and (max-width:580px) {
    .collection-container {
        display: grid;
        grid-template-columns: 1fr;
    }
}

整理笔记 (Finishing Notes)

Accessibility is an area that wasn’t considered at all and may have some space for improvement.

可访问性是一个根本没有考虑的领域,可能还有一些改进的空间。

If you have any ideas or second thoughts, please feel free to comment!

如果您有任何想法或第二想法,请随时发表评论!

And of course, thanks for reading.

当然,感谢您的阅读。

翻译自: https://www.freecodecamp.org/news/https-medium-com-nakayama-shingo-creating-responsive-tables-with-pure-css-using-the-grid-layout-module-8e0ea8f03e83/

css响应式网格布局生成器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值