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:
當顯示器的寬度變窄時,一些屬性會垂直堆疊,以節省水平空間。 堆疊屬性的選擇應基于:
- Do the attributes make sense when stacked vertically? and, 垂直堆疊時這些屬性有意義嗎? 和,
- 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 repeat
ed, 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-fit
ed.
.attribute-container
下所有網格項目的最小列寬是使用minmax
函數通過名為--column-width-min
CSS變量指定的(稍后會詳細介紹),最大值設置為占用其余空間(例如一小部分)。 由于repeat
grid-template-columns
,因此可用的水平空間將被劃分為最多可占用--column-width-min
的最大列數,其余列將進入下一行。 如果有多余的水平空間,則列的寬度將被拉伸,因為repeat
是auto-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-id
HTML,
<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-container
s, 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響應式網格布局生成器