整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

CSS Grid 网格布局入门

CSS Grid 网格布局入门

文:https://scotch.io/tutorials/getting-started-with-css-grid-layout

译文:http://www.css88.com/archives/8661

介绍

CSS Grid(网格) 布局使我们能够比以往任何时候都可以更灵活构建和控制自定义网格。 Grid(网格) 布局使我们能够将网页分成具有简单属性的行和列。它还能使我们在不改变任何HTML的情况下,使用 CSS 来定位和调整网格内的每个元素。它允许 HTML 纯粹作为内容的容器。HTML 结构不再受限于样式表现,比如不要为了实现某种布局而多次嵌套,现在这些都可以让 CSS 来完成。

定义一个网格

Grid(网格) 模块为 display 属性提供了一个新的值: grid 。当你将任何元素的 display 属性设置为 grid 时,那么这个元素就是一个 网格容器(grid container),它的所有直接子元素就成了 网格项(grid items)。

让我们创建创建一个 3×3 的布局,做一个 Tic-Tac-Toe (井字游戏) 棋盘。 首先,我们将写一些 HTML:

<div class="game-board"> <div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div></div>

如您所见, .game-board div 是网格容器,而 .box div 是网格项。现在我们将通过 Grid 布局来实现 3×3 布局。

.game-board { display: grid; grid-template-rows: 200px 200px 200px; grid-template-columns: 200px 200px 200px;
}

在这里,我还使用了其他两个属性。 grid-template-rows 属性允许我们指定网格中的行数及行的高度。那么你应该猜到另一个属性是干什么的了。

grid-template-columns 属性允许我们指定网格中的列数及列的宽度。您可以指定任何单位的尺寸大小,包括像素,百分比和其他单位 fr ,我们将在下一步学习。

web前端学习群:189394454,分享源码、最新知识点、精品教程、欢迎初学者和在进阶中的小伙伴。

fr 单位(等分)

fr 是为网格布局定义的一个新单位。它可以帮助你摆脱计算百分比,并将可用空间等分。

例如,如果在网格容器中设置这个规则: grid-template-rows: 2fr 3fr ,那么你的网格容器将首先被分成 2 行。然后将数字部分加在一起,这里总和为 5, 即 5 等分。

就是说,我们将有 2 行:第一排占据垂直空间的 2/5 。 第二排占垂直空间的 3/5 。

回到我们的 Tic-Tac-Toe 例子,我们使用 fr 代替 px 。我们想要的是,应该有3行3列。所以,我们只需要用 3 个 1fr 替换 3 个 200px 即可:

.game-board { display: grid; grid-template-rows: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr;
}

愚人码头注:

这里特别需要注意的是: fr 单位是等分可用空间,或者说剩余空间。看个例子

.game-board { grid-gap:2px; display: grid; width:300px; height:200px; 
 grid-template-rows: 100px 1fr 1fr; grid-template-columns: 1fr 50px 1fr;
}

布局效果如图:

你会看到 fr 单位是将 总的尺寸 减去 单元格明确尺寸后,在等分剩余空间。 grid-gap 是间隔。

repeat() 函数

在某些情况下,我们可能有很多的列和行。在 grid-template 属性中指定每一个值可能会很乏味。幸运的是,有一个 repeat 函数,就像任何一个循环重复多少次输出某个给定值。它有两个参数。第一个是迭代次数,第二个是要重复的值。我们用 repeat 函数重写上面的例子。

.game-board{ display: grid; grid-template-rows: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr);
}

等价于:

.game-board { display: grid; grid-template-rows: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr;
}

grid-template 属性

grid-template 属性是 grid-template-rows 和 grid-template-columns 的简写语法。 这是它的语法:

grid-template: ro ws / co lu mns;

我们上面的例子使用这个简写语法后,看起来非常整齐。

.game-board{ display: grid; grid-template: repeat(3, 1fr) / repeat(3, 1fr);
}

看,只需使用 2 行代码,就可以使用网格布局创建 3×3 网格。

我们在加一些背景和间隔后,上面的例子看起来像这样:

网格线编号,网格单元格,网格轨道

网格线是存在于列和行每一侧的线。一组垂直线将空间垂直划分成列,而另一组水平线将空间水平划分成行。这意味着在我们之前的例子中,有四条垂直线和四条水平线包含它们之间的行和列。

在将网格项从一个位置跨越到另一个位置时,网格线变得非常有用。

网格轨道是两条线之间的空间。 网格轨道可以是一行或一列。

网格单元格很像表格单元,是两条相邻垂直线和两条相邻水平线之间的空间。 这是网格中最小的单位。

定位网格项

我采取了前面的例子的网格,并用数字从1到9标记每个单元格,而不是X或O,下面是它的样子:

假设我想将第 6 个框移到第 2 个框的位置。没有CSS网格,不改变 HTML 的情况下,这几乎是一个不可能的任务,至少对我而言。(愚人码头注,如果单纯这样的效果图,用FlexBox布局实现问题不大)但是如果我们使用网格模块,改变网格中网格项的位置是一件轻而易举的事情。要将第6个框移到第2个框的位置,我们必须确切知道第2个框在哪里。通过网格线编号的帮助,我们可以很容易地找到这个位置。第二个方框位于第2条列网格线之后,第3条列网格线之前,第1条行网格线之下,第2条行网格线之上。现在我们可以使用以下属性将这些网格线编号分配到第6个框中:

  • grid-column-start

  • grid-column-end

  • grid-row-start

  • grid-row-end

前两个属性对应于垂直网格线,也就是列网格线的开始和结束。 最后两个属性是指水平网格线,也就是行网格线的开始和结束。 让我们分配正确的网格线编号来移动第 6 个框。

.box:nth-child(6){ grid-row-start: 1; grid-row-end: 2; grid-column-start: 2; grid-column-end: 3;
}

还有两个简写属性用于将行和列的开始网格线和结束网格线设置在一起。

.box:nth-child(6){ grid-row: 1 / 2; grid-column: 2 / 3;
}

此外,还有一个 grid-area 属性是所有四个上述属性的简写属性。 它按以下顺序取值:

grid-area: <row-start> / <column-start> / <row-end> / <column-end>;

现在我们的例子可以写成这样

.box:nth-child(6){ grid-area: 1 / 2 / 2 / 3;
}

上面的代码行也可以进一步减少。正如您所看到的,这个框只占用一行和一个列,所以我们只需要指定行和列的起始线,而无需结束线的值。

.box:nth-child(6){ grid-area: 1 / 2;
}

如果我们想要第6个框跨越两个框的区域呢? 这很容易通过将 column-end 值加 1 的办法来完成。

.box:nth-child(6){ grid-area: 1 / 2 / 2 / 4;
}

您也可以使用 span 关键字和占据的 轨道数量,来代替指定 grid-row-end 和 grid-column-end 的结束网格线编号。 在这种情况下,第6个框是跨越 2 列和 1 行。

.box:nth-child(6){ grid-area: 1 / 2 / 2 / span 2;
}

网格区域命名

grid-area 属性也可以用来命名网格的某一个部分,然后我们可以用 grid-template-areas 属性来定位。让我们创建一个简单的 bread-and-butter 布局,顶部有一个 top, nav,中间有 main 和 aside,下面是 footer。这是所需的HTML:

<div class="container"> <header></header>
<nav></nav>
<main></main>
<aside></aside>
<footer></footer></div>

我们需要使用 grid-area 属性来命名每个区域:

header{ grid-area: header; background-color: #9b59b6;
}nav{ grid-area: nav; background-color: #3498db;
}main{ grid-area: main; background-color: #2ecc71;
}aside{ grid-area: aside; background-color: #f1c40f;
}footer{ grid-area: footer; background-color: #1abc9c;
}

现在我们将使用 grid-template-areas 属性来指定每个网格区域所占据的行和列。 以下是我们如何做到的:

.container{ display: grid; grid-template-rows: 1fr 5fr 1fr; 
 grid-template-columns: 2fr 5fr 3fr; grid-template-areas: "header header header"
"nav main aside"
"footer footer footer"; grid-gap: .75em;
}

请注意,header 和 footer 单词重复三次。 这表明,header 和 footer 横跨 3 列的宽度。 你可以把它全部写在一行中,但是把每一行写在一个单独的行上很好,很干净。 你可以看到我在这里使用了一个新的属性 grid-gap 。 它所做的只是在两个网格区域之间添加一个间距。 你也可以使用 grid-row-gap 和 grid-column-gap 来为行和列指定不同的间距值。

web前端学习群:189394454,分享源码、最新知识点、精品教程、欢迎初学者和在进阶中的小伙伴。

CodePen上的这个例子:

浏览器支持

在写这篇文章的时候,CSS Grid 布局很多浏览器已经原生支持。根据 caniuse.com 的统计,所有主流浏览器都支持CSS Grid 布局,Internet Explorer 11 部分支持 -ms- 前缀, Opera Mini 根本不支持。

结论

CSS网格布局允许我们更快地布局,并且更容易控制。在本教程中,我们学习了如何用CSS网格来定义布局, fr 单位,repeat 函数和一些网格系统中特定的术语。我们还学习了如何使用网格线和网格命名区域在网格容器内定位网格项目。但这只是一个开始。 在下一个教程中,我们将深入到CSS网格。

星 Galaxy Fold 和 Surface Duo 以及华为mate X等系列折叠屏手机问世至今已有三年多的时间。此后,三星 Galaxy Z Fold 3 和 Galaxy Z Flip 3、华为mate X2S、荣耀magic V系列等手机均已上市。可折叠设备可供购买,目前正在被消费者使用,随之而来的是我们作为开发人员可以开始探索这种新型设备和响应式设计的下一个发展的机会。

这些 Web 平台功能与现有概念(例如视口和媒体查询)集成,因此开发人员和设计人员可以花更多时间思考如何利用两个显示器来创建增强体验,而不是学习一组新代码来构建它们。

使用新的 CSS 媒体功能检测可折叠设备

双屏和可折叠设备只是响应式设计的下一步,因此它们被视为另一个响应式设计目标,我们可以使用媒体功能为其设计样式。我们今天已经使用媒体功能和查询来定位台式机、平板电脑和手机,现在我们拥有 CSS Viewport Segments 媒体功能来定位我们的可折叠和双屏设备。

horizontal-viewport-segments

视口分段媒体查询可以有两个值。第一个是horizontal-viewport-segments,这表示设备铰链垂直且视口被硬件铰链拆分或折叠成列时的设备状态。

horizonal-viewport-segment铰链处于垂直折叠姿势时,目标是设备。

为了专门为这种方向的可折叠设备提供样式,我们将编写以下内容:

@media (horizontal-viewport-segments: 2) {
// Styles specific to the device in this orientation
}

整数表示设备方向中存在的视口数量。当设备像一本书一样处于垂直折叠姿势时,我们在水平方向有两个不同的视口,在垂直方向只有一个视口。

我们还可以结合我们的媒体查询来定位双屏设备和某些视口宽度,以提供特定的样式:

@media (horizontal-viewport-segments: 2) and (min-width: 540px) {
   body {
       background: yellow;
  }
}

vertical-viewport-segments

我们的视口分段媒体功能的第二个值是vertical-viewport-segments,这是设备铰链水平时设备的状态,并且硬件铰链将我们的视口分成行。

vertical-viewport-segments目标设备处于水平折叠姿势。

要定位在这个方向旋转的设备,我们将使用以下代码:

@media (vertical-viewport-segments: 2) {
  // Styles specific to the device in this orientation
}

使用 JavaScript 检测可折叠设备

在某些情况下,您可能无法或不想使用 CSS 媒体查询来检测您的用户是否在可折叠设备上,这就是 JavaScript API 的用武之地。最初,提出了一个名为 Windows Segments Enumeration 的全新 API ,但在开发者社区通过原始试验获得反馈后,在现有的Visual Viewport API 草案规范的基础上构建更有意义。

视口段属性

视口段表示位于彼此相邻的单独显示器上的窗口区域。要检测双屏设备,您可以使用以下代码查询 segments 属性:

const segments=window.visualViewport.segments;

此查询返回的值将是一个数组DOMRects,指示有多少视口。如果只有一个视口段,则查询将返回null,并以这种方式实现以防止将来出现兼容性问题,以免开发人员开始使用visualViewport.segments[0]针对单屏设备。

在双屏设备上,查询将返回 2 DOMRects,表示当浏览器窗口跨越折叠时可用的 2 个视口。

我们存储在segments常量中的这个值是查询属性时设备状态的不可变快照,如果浏览器窗口调整大小或设备旋转,之前检索到的视口段不再有效,需要查询再次通过调整大小或方向事件(或两者)。

如果您调整浏览器窗口的大小以仅跨越一个显示区域,我们将触发调整大小事件。

如果您旋转设备,这将触发调整大小和方向事件,您可以使用这些事件再次查询属性以获取浏览器显示区域的当前状态。

window.addEventListener("resize", function() {
   const segments=window.visualViewport.segments;
   console.log(segments.length); *// 1*
});

何时使用 JAVASCRIPT API 与 CSS 媒体功能来检测 设备

CSS 媒体功能和 JavaScript 段属性都将检测双屏设备,但 JavaScript 属性最好在没有使用 CSS 时使用,当您在 Canvas2D 和 WebGL 中处理对象时可能会发生这种情况。例如,您正在开发的游戏可以同时利用两个屏幕。

使用 CSSenv()变量

除了 CSS 媒体功能之外,还引入了六个新的 CSS 环境变量,以帮助开发人员计算显示区域的几何形状,计算铰链区域在被 Surface Duo 等物理硬件功能遮挡时的几何形状,以及它们还可用于帮助将内容放置在每个显示区域的边界内。

六个新的环境变量如下:

  • env(viewport-segment-width <x> <y>);
  • env(viewport-segment-height <x> <y>);
  • env(viewport-segment-top <x> <y>);
  • env(viewport-segment-left <x> <y>);
  • env(viewport-segment-bottom <x> <y>);
  • env(viewport-segment-right <x> <y>);

x和位置表示由分隔每个视口段的硬件功能创建的y二维网格,坐标0,0从左上段开始。

当您的设备处于垂直折叠姿势且视口并排时,左侧的视口段将由 表示env(viewport-segment-width 0 0),而右侧的视口段将由 表示env(viewport-segment-width 1 0)。如果您将设备转换为水平折叠姿势,视口堆叠,顶部将由 表示env(viewport-segment-height 0 0),底部视口由表示env(viewport-segment-height 0 1)

使用env(viewport-segment-width)andenv(viewport-segment-width)时,除了索引之外,我们还可以设置一个后备值,如下所示:

env(viewport-segment-width 0 0, 100%);

但是这个额外的后备值是可选的,由作者自行决定,如果他们想包含它。

计算铰链宽度

当您的设备的铰链被硬件功能遮挡时,您可以使用提供的环境变量来计算它。

我们可以使用环境变量计算设备铰链。

在我们的示例中,我们有一个处于垂直姿势的设备,并且想要找到铰链宽度,这样就不会遮挡任何内容。我们将从左显示器的右视口段中减去右显示器的左视口段:

calc(env(viewport-segment-left 1 0) - env(viewport-segment-right 0 0));

使用 CSSenv()变量 放置内容

我们可以使用 CSS 环境变量在显示区域边界内放置内容,如果您想将内容直接放置在铰链或折叠处,这些特别有用。

在下面的示例中,我们将在左侧第一个显示区域的铰链上直接放置图像。该区域是视口的右侧部分,因此我们将使用viewport-segment-right以下代码放置它:

img {
  max-width: 400px;
}

@media (horizontal-viewport-segments: 2) {
  img {
      position: absolute;
      left: env(viewport-segment-right 0 0);
  }
}

如果我们在 Surface Duo 模式下在 Edge 开发人员工具中模拟我们的屏幕,我们将获得以下布局:

最初使用环境变量将图像放置在我们的布局中会将其放置在错误的显示区域中。

这不是我们想要的。图像应位于左侧的显示区域中。

因为图像是使用属性绝对定位的left,所以图像的左边缘最终与viewport-segment-right显示区域对齐。

然后,我们需要从环境变量中减去图像的宽度,以使图像与正确的铰链边缘对齐:

img {
   max-width: 400px;
}

@media (horizontal-viewport-segments: 2) {
   img {
       position: absolute;
       left: calc(env(viewport-segment-right 0 0) - 400px);
  }
}

从视口段中减去图像宽度会将其沿左侧显示中的铰链放置。

现在我们将图像放置在我们想要的位置。有关如何沿铰链对齐项目的其他示例,您可以查看这个简单的盒子演示。打开Edge Developer Tools>Device Emulation然后选择Surface Duo并确保您Duo emulation处于校正方向姿势。

把它们放在一起:让我们构建一个适应双屏设备的食谱页面

作为一个在做饭时经常使用手机的人,当我在我的双屏设备上时会适应的食谱网站会非常有帮助。让我们来看看如何考虑为它调整一个单独的食谱页面。

我想考虑我将如何分块我的主要内容。通常情况下,我至少会看到食谱标题、制作的份量、烹饪需要多长时间、一张或多张图片、配料以及制作菜肴的步骤。

当我画出我的线框时,我得到以下信息:

桌面上食谱页面的标准布局

我希望我的标题和食谱详细信息在最顶部,然后是一个占据整个内容宽度的图像,然后是成分列表和食谱步骤。我不想堆叠后两个内容组,因为如果我堆叠它们,成分列表的右侧会有很多空白,所以我希望步骤坐在成分旁边,给我两列图片下方。

用于布局的 CSS 网格或 FLEXBOX?

我知道我想如何在普通桌面屏幕上布置这个食谱,并且有多种方法可以对这个布局进行编码和对内容进行分组,但我如何对其进行分组,以及我想在双屏上实现什么布局在我编码之前需要考虑设备。根据我为桌面视图所做的草图,我可以使用 flexbox 和 CSS Grid 的组合来实现我想要的布局,我将成分和步骤分组到一个 flex 容器中。但是让我勾勒一下我希望我的页面如何在双屏上显示。

垂直折叠位置的可折叠设备上的理想布局通过显示屏将内容分开,因此不会被铰链遮挡。

如果我想在布局上有更大的灵活性,那么我不能将我的成分和步骤分组到一个 flex 容器中,否则,无论图像没有进入哪一列,都会有很大的空白。

如果我只在这个布局中使用 flexbox,它会产生一些我想避免乱用的间距。

添加我们的内容

我将在桌面和双屏布局中只使用 CSS Grid。所以,让我们构建我们的内容。

<main>
  <section class="recipe">
      <div class="recipe-meta">
          … <!—Contains our recipe title, yield and servings -->
      </div>
      <img src="imgs/pasta.jpg" alt="Pasta carbonara photographed from above on a rustic plate" />
      <div class="recipe-details__ingredients">
          …<!— Contains our ingredients list -->
      </div>
      <div class="recipe-details__preparation">
          … <!— Contains our list of steps to put the ingredients together -->
      </div>
  </section>
</main>

接下来,让我们构建页面的结构。我要定义我的网格:我只想要三列,并且我希望它们是容器的相等部分。

.recipe {
display: grid;
grid-template-columns: repeat(3, 1fr);

接下来,我将定义我的行,并且我将使用grid-auto-rowswith minmax,这样我的行是最小的,175px但可以增长到最大内容高度的最大值。

grid-auto-rows: minmax(175px, max-content);

然后我将添加更多属性: my grip-gap、我的最大内容宽度和一个边距,以使我的布局在页面上居中。

grid-gap: 1rem;
max-width: 64rem;
margin: 0 auto;
}

然后,我将把我的内容放入我定义的网格中:

.recipe-meta {
   grid-column: 1 / 4;
}

.recipe-meta p {
   margin: 0;
}

img {
   width: 100%;
   grid-column: 1 / 4;
}

.recipe-details__ingredients {
   grid-row: 3;
}

.recipe-details__preparation {
   grid-column: 2 / 4;
   grid-row: 3;
}

这将根据我的草图为我提供布局:

布局在桌面上按预期呈现

伟大的!但是我的双屏布局呢?让我们深入了解我们的horizontal-viewport媒体功能和双屏网格。

使用媒体查询和调整容器布局

首先,这是我现在在双屏上的布局:

在没有实现任何双屏代码的情况下,如果用户想要将浏览器跨过两个显示器,那么页面将是这样的。

如果我们向下滚动:

如果用户选择跨越两个显示器,则内容会被铰链遮挡。

不是很好。我们的内容被铰链遮住了,所以让我开始重新定义我的网格。

对于我的网格列,我仍将使用三列,但我希望一列占据左侧的第一个视口段,另外两列占据右侧视口段,因此我将使用我的 CSS环境变量env(viewport-segment-width 0 0)告诉浏览器,对于我的第一列,我希望它占据第一个显示区域的整个视口。

@media (horizontal-viewport-segments: 2) {

/* Body styles for smaller screens */
body {
       font: 1.3em/1.8 base, 'Playfair Display', serif;
       margin: 0;
  }

.recipe {
   grid-template-columns: env(viewport-segment-width 0 0 1fr 1fr;
   grid-template-rows: repeat(2, 175px) minmax(175px, max-content);
}

}

对于我的行,我希望在放置上更灵活一点,所以我将重复两行175px,这是关于带有配方标题、产量和时间信息的容器的高度,之后的行应该匹配我最初在网格中定义的内容。

如果我在 DevTools 中检查我的设计,我可以看到我在配方容器上设置的widthmargin最初将我想要与我的视口段对齐的网格线推到正确的视口段中。

添加我的代码后,我的内容不再被遮挡,但仍需要一些间距调整。

要重置它,我将重置我的marginand max-width

@media (horizontal-viewport-segments: 2) {

.recipe {
   grid-template-columns: env(viewport-segment-width 0 0) 1fr 1fr;
   grid-template-rows: repeat(2, 175px) minmax(175px, max-content);
   margin: 0;
   max-width: 100%;
}

}

重置我的边距和填充会掩盖右侧显示中的内容。

现在我要把我的内容放在网格中并调整我的布局。

.recipe-meta {
   grid-column: 1 / 2;
   padding: 0 2rem;
}

img {
   grid-column: 2 / 4;
   grid-row: 1 / 3;

   width: 100%;
   height: 100%;
   object-fit: cover;
   /* necessary to keep the image within the grid lines */
}

.recipe-details__ingredients {
   grid-row: 2;
   padding: 0 2rem;
}

.recipe-details__preparation {
   grid-column: 2 / 4;
   grid-row: 3;
   padding: 0 2rem 0 3rem;
}

我已经对内容应用了填充,除了我决定要跨越整个视口的图像。对于图像下方的内容,由于从物理铰链下方开始的网格线的性质,我想添加额外的填充,因此它看起来左侧的填充与其他带有填充的项目相同。如果我不添加额外的,它会落得太靠近铰链。因为我已经有一个 grid-gap1rem并且我想将 padding 加倍,所以我将添加3rem而不是4rem为我们提供双屏设备上的最终布局:

我可以重新添加尺寸更合适的填充来显示内容,因此它不会在带有物理铰链的设备上被遮挡。

只需对我们的 CSS 进行一些小的调整并使用其中一项新的媒体功能,我们就有了一个适应双屏设备的布局。要查看体验,请前往此处的 Edge 演示站点或基于 Chromium 的浏览器,然后打开浏览器开发人员工具以查看 Surface Duo 仿真。如果您在 Chrome 中打开该站点,请确保在 下启用了实验性网络平台功能标志chrome://flags,以便演示正确显示。

单屏响应式设计细节

为了确保我们考虑到小型单屏设备,我为手机布局选择的代码使用了 flexbox 并将所有内容放在一个列中:

@media (max-width: 48rem) {

   body {
       font: 1.3em/1.8 base, 'Playfair Display', serif;
  }

   .recipe-details {
       display: flex;
       flex-direction: column;
  }

}

API 浏览器可用性和无设备测试

默认情况下,这些双屏 API 在 Microsoft Edge 和 Android 上的 Edge 中可用,从版本 97 开始。这些计划很快就会出现在其他 Chromium 浏览器中,但具体时间尚未确定。要在 Chrome 中启用这些 API,请转到chrome://flags并启用实验性网络平台功能。

虽然这些是相对较新的设备,但许多现在已经进入第二代和第三代,因此公司正在投资它们。如果您无法使用物理设备,最好的测试方法是使用浏览器开发工具。我已经在仿真工具和 Surface Duo 上测试了我的网站,Duo 的仿真工具似乎是相同的。我的设计在设备上的外观与在 DevTools 中的外观相同。它使构建和设计双屏设备就像开发桌面和单屏移动设备一样容易。

如果您使用的是不支持这些 API 的桌面或设备,则可以为 Visual Viewport Segments 属性提供一个 polyfill。CSS 媒体查询没有 API。目前,市场上的双屏设备都是基于安卓的,这些API计划在安卓上可用的基于Chromium的浏览器中。

如果可折叠设备上的浏览器不支持这些功能,您可以使用 polyfill 或确保您的网站在小单屏上仍能很好地呈现,因为用户可以灵活选择如何在双屏上显示网站屏幕设备。他们可以跨两个显示器跨越一个网站,或者他们可以选择让它跨一个显示器,如果他们选择后者,它将像在平板电脑或手机上一样显示。即使您的网站没有双屏实现,用户仍然可以选择单显示视图。双屏 API 提供了一种方法来逐步增强拥有设备的用户的体验。

结束

双屏设备只是响应式设计的下一个发展方向。如果您有 PWA 或网站,可用的 API 可以无缝集成到您现有的代码库中。还有其他方法可以为双屏设备构建应用程序,您可以在Surface Duo 文档https://docs.microsoft.com/en-us/dual-screen/中查看这些方法。这是在网络上进行布局的激动人心的时刻,双屏提供了获得更多创意的机会。

为帮助到一部分同学不走弯路,真正达到一线互联网大厂前端项目研发要求,首次实力宠粉,打造了《30天挑战学习计划》,内容如下:

HTML/HTML5,CSS/CSS3,JavaScript,真实企业项目开发,云服务器部署上线,从入门到精通

  • PC端项目开发(1个)
  • 移动WebApp开发(2个)
  • 多端响应式开发(1个)

共4大完整的项目开发 !一行一行代码带领实践开发,实际企业开发怎么做我们就是怎么做。从学习一开始就进入工作状态,省得浪费时间。

从学习一开始就同步使用 Git 进行项目代码的版本的管理,Markdown 记录学习笔记,包括真实大厂项目的开发标准和设计规范,命名规范,项目代码规范,SEO优化规范

从蓝湖UI设计稿 到 PC端,移动端,多端响应式开发项目开发

  • 真机调试,云服务部署上线;
  • Linux环境下 的 Nginx 部署,Nginx 性能优化;
  • Gzip 压缩,HTTPS 加密协议,域名服务器备案,解析;
  • 企业项目域名跳转的终极解决方案,多网站、多系统部署;
  • 使用 使用 Git 在线项目部署;

这些内容在《30天挑战学习计划》中每一个细节都有讲到,包含视频+图文教程+项目资料素材等。只为实力宠粉,真正一次掌握企业项目开发必备技能,不走弯路 !

过程中【不涉及】任何费用和利益,非诚勿扰 。

如果你没有添加助理老师微信,可以添加下方微信,说明要参加30天挑战学习计划,来自!老师会邀请你进入学习,并给你发放相关资料。

30 天挑战学习计划 Web 前端从入门到实战 | arry老师的博客-艾编程

这里是云端源想IT,帮你轻松学IT”

嗨~ 今天的你过得还好吗?

生命是不倒行的

也不与昨日一同停留

- 2024.04.08 -

随着现代网页设计的不断演进,传统的布局方式已经逐渐不能满足设计师和开发者们对于高效、灵活且强大布局系统的追求。而CSS Grid网格布局,正是在这样的背景下应运而生的。

今天,我们就来深入探讨CSS Grid布局的魅力所在,带你解锁这项强大的设计工具,让网页布局变得更加简单和高效。


一、什么是CSS Grid布局?

CSS Grid布局,简称为Grid,是CSS的一个二维布局系统,它能够处理行和列,使得网页布局变得更加直观和强大。与传统的布局方式相比,Grid能够轻松实现复杂的页面结构,而无需繁琐的浮动、定位或是使用多个嵌套容器。


Grid网格布局是一种基于网格的布局系统,它允许我们通过定义行和列的大小、位置和排列方式来创建复杂的网页布局。

这与之前讲到的flex一维布局不相同。


设置display:grid/inline-grid的元素就是网格布局容器,这样就能触发浏览器渲染引擎的网格布局算法。

<div>
<div class="item item-1">
<p></p >
</div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</div>

上述代码实例中,.container元素就是网格布局容器,.item元素就是网格的项目,由于网格元素只能是容器的顶层子元素,所以p元素并不是网格元素。


二、Grid的基本概念

首先,我们来了解一下CSS Grid布局的核心概念:


容器(Container):

设置了display: grid;的元素成为容器。它是由一组水平线和垂直线交叉构成,就如同我们所在的地区是由小区和各个路构成。


项目(Item):

容器内的直接子元素,称为项目。


网格线(Grid Lines):

划分行和列的线条,可以想象成坐标轴。正常情况下n行会有n+1根横向网格线,m列有m+1根纵向网格线。比如田字就好像是一个三条水平线和三条垂直线构成的网格元素。

上图是一个 2 x 3 的网格,共有3根水平网格线和4根垂直网格线。

行:

即两个水平网格线之间的空间,也就是水平轨道,就好比我们面朝北边东西方向横向排列的楼房称为行。

列:

即两个垂直网格线之间的空间,也就是垂直轨道,也就是南北方向排列的楼房。



单元格:

由水平线和垂直线交叉构成的每个区域称为单元格,网络单元格是CSS网格中的最小单元。也就是说东西和南北方向的路交叉后划分出来的土地区域。

网格轨道(Grid Tracks):

两条相邻网格线之间的空间。

网格区域(Grid Area):

四条网格线围成的空间,可以是行或列。本质上,网格区域一定是矩形的。例如,不可能创建T形或L形的网格区域。

三、Grid的主要属性

CSS Grid网格布局的主要属性包括:

  • display:设置元素为网格容器或网格项。例如,display: grid; 将元素设置为网格容器,而 display: grid-item; 将元素设置为网格项。
  • grid-template-columns 和 grid-template-rows:用于定义网格的列和行的大小。
  • grid-column-gap 和 grid-row-gap:用于定义网格的列和行的间距。
  • grid-template-areas:用于定义命名区域,以便在网格中引用。
  • grid-auto-flow:用于控制网格项的排列方式,可以是行(row)或列(column)。
  • grid-auto-columns 和 grid-auto-rows:用于定义自动生成的列和行的大小。
  • grid-column-start、grid-column-end、grid-row-start 和 grid-row-end:用于定义网格项的位置。
  • justify-items、align-items 和 place-items:用于对齐网格项。
  • grid-template:一个复合属性,用于一次性定义多个网格布局属性。



下面将详细介绍这些属性的概念及作用:


3.1 display

通过给元素设置:display:grid | inline-grid,可以让一个元素变成网格布局元素。

语法:

display: grid | inline-grid;


  • display: grid:表示把元素定义为块级网格元素,单独占一行;
  • display:inline-grid:表示把元素定义为行内块级网格元素,可以和其他块级元素在同一行。


3.2 grid-template-columns和grid-template-rows

grid-template-columns和grid-template-rows:用于定义网格的列和行的大小。

  • grid-template-columns 属性设置列宽
  • grid-template-rows 属性设置行高
.wrapper {
display: grid;
/* 声明了三列,宽度分别为 200px 200px 200px */
grid-template-columns: 200px 200px 200px;
grid-gap: 5px;
/* 声明了两行,行高分别为 50px 50px */
grid-template-rows: 50px 50px;
}

以上表示固定列宽为 200px 200px 200px,行高为 50px 50px。


上述代码可以看到重复写单元格宽高,我们也可以通过使用repeat()函数来简写重复的值。

  • 第一个参数是重复的次数
  • 第二个参数是重复的值



所以上述代码可以简写成:

.wrapper {
display: grid;
grid-template-columns: repeat(3,200px);
grid-gap: 5px;
grid-template-rows:repeat(2,50px);
}

除了上述的repeact关键字,还有:


auto-fill:表示自动填充,让一行(或者一列)中尽可能的容纳更多的单元格。

grid-template-columns: repeat(auto-fill, 200px)

表示列宽是 200 px,但列的数量是不固定的,只要浏览器能够容纳得下,就可以放置元素。


fr:片段,为了方便表示比例关系。

grid-template-columns: 200px 1fr 2fr

表示第一个列宽设置为 200px,后面剩余的宽度分为两部分,宽度分别为剩余宽度的 1/3 和 2/3。



minmax:产生一个长度范围,表示长度就在这个范围之中都可以应用到网格项目中。第一个参数就是最小值,第二个参数就是最大值。

minmax(100px, 1fr)

表示列宽不小于100px,不大于1fr。


auto:由浏览器自己决定长度。

grid-template-columns: 100px auto 100px

表示第一第三列为 100px,中间由浏览器决定长度。


3.3 grid-row-gap 属性, grid-column-gap 属性, grid-gap 属性

grid-column-gap和grid-row-gap,用于定义网格的列间距和行间距。grid-gap 属性是两者的简写形式。

  • grid-row-gap: 10px 表示行间距是 10px
  • grid-column-gap: 20px 表示列间距是 20px
  • grid-gap: 10px 20px 等同上述两个属性



3.4 grid-auto-flow 属性

grid-auto-flow,用于控制网格项的排列方式,可以是行(row)或列(column)。

  • 划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。
  • 顺序就是由grid-auto-flow决定,默认为行,代表"先行后列",即先填满第一行,再开始放入第二行。

当修改成column后,放置变为如下:


3.5 justify-items 属性, align-items 属性, place-items 属性

justify-items、align-items和place-items,用于定义网格项目的对齐方式。

  • justify-items 属性设置单元格内容的水平位置(左中右)
  • align-items 属性设置单元格的垂直位置(上中下)
.container {
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
}


属性对应如下:

  • start:对齐单元格的起始边缘
  • end:对齐单元格的结束边缘
  • center:单元格内部居中
  • stretch:拉伸,占满单元格的整个宽度(默认值)

place-items属性是align-items属性和justify-items属性的合并简写形式。

3.6 justify-content 属性, align-content 属性, place-content 属性

  • justify-content属性是整个内容区域在容器里面的水平位置(左中右)
  • align-content属性是整个内容区域的垂直位置(上中下)
.container {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}

两个属性的写法完全相同,都可以取下面这些值:

  • start - 对齐容器的起始边框
  • end - 对齐容器的结束边框
  • center - 容器内部居中
  • space-around - 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍。
  • space-between - 项目与项目的间隔相等,项目与容器边框之间没有间隔。
  • space-evenly - 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔。
  • stretch - 项目大小没有指定时,拉伸占据整个网格容器。



3.7 grid-auto-columns 属性和 grid-auto-rows 属性

有时候,一些项目的指定位置,在现有网格的外部,就会产生显示网格和隐式网格。


比如网格只有3列,但是某一个项目指定在第5行。这时,浏览器会自动生成多余的网格,以便放置项目。超出的部分就是隐式网格。


而grid-auto-rows与grid-auto-columns就是专门用于指定隐式网格的宽高。


3.8 grid-column-start 属性、grid-column-end 属性、grid-row-start 属性以及grid-row-end 属性

指定网格项目所在的四个边框,分别定位在哪根网格线,从而指定项目的位置。

  • grid-column-start 属性:左边框所在的垂直网格线
  • grid-column-end 属性:右边框所在的垂直网格线
  • grid-row-start 属性:上边框所在的水平网格线
  • grid-row-end 属性:下边框所在的水平网格线
<style>
#container{
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
}
.item-1 {
grid-column-start: 2;
grid-column-end: 4;
}
</style>

<div id="container">
<div class="item item-1">1</div>
<div class="item item-2">2</div>
<div class="item item-3">3</div>
</div>

通过设置grid-column属性,指定1号项目的左边框是第二根垂直网格线,右边框是第四根垂直网格线。

3.9 grid-area 属性

grid-area 属性指定项目放在哪一个区域。

.item-1 {
grid-area: e;
}

意思为将1号项目位于e区域

grid-area属性一般与上述讲到的grid-template-areas搭配使用。

想要快速入门前端开发吗?推荐一个前端开发基础课程,这个老师讲的特别好,零基础学习无压力,知识点结合代码,边学边练,可以免费试看试学,还有各种辅助工具和资料,非常适合新手!点这里前往学习哦!云端源想


3.10 justify-self 属性、align-self 属性以及 place-self 属性

justify-self属性设置单元格内容的水平位置(左中右),跟justify-items属性的用法完全一致,但只作用于单个项目。


align-self属性设置单元格内容的垂直位置(上中下),跟align-items属性的用法完全一致,也是只作用于单个项目。

.item {
justify-self: start | end | center | stretch;
align-self: start | end | center | stretch;
}


这两个属性都可以取下面四个值。

  • start:对齐单元格的起始边缘。
  • end:对齐单元格的结束边缘。
  • center:单元格内部居中。
  • stretch:拉伸,占满单元格的整个宽度(默认值)


四、Grid网格布局应用场景

CSS Grid网格布局的应用场景非常广泛,包括但不限于:

1、创建复杂的网页布局:

CSS Grid网格布局可以轻松创建出复杂的网页布局,如多列布局、不规则布局等。

2、创建响应式设计:

CSS Grid网格布局可以轻松实现响应式设计,通过调整网格的大小和间距,可以适应不同的屏幕尺寸。

3、创建复杂的组件布局:

CSS Grid网格布局也可以用于创建复杂的组件布局,如卡片布局、轮播图布局等。

总的来说,CSS Grid网格布局是一种强大的布局工具,可以帮助网页设计者轻松创建出各种复杂的网页布局。



CSS Grid布局为我们提供了一个全新的视角来思考页面布局,它让复杂布局的实现变得简单明了。随着浏览器支持度的提高,未来的网页设计将更加灵活和富有创意。


掌握了CSS Grid布局,你就已经迈出了成为前端设计高手的重要一步。不断实践,不断探索,你会发现更多Grid的神奇之处。



今天就先讲到这里了,

更多前端开发基础知识点击文末阅读原文查看哦!

记得关注【云端源想IT】一起学编程!


我们下期再见!


END

文案编辑|云端学长

文案配图|云端学长

内容由:云端源想分享