百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 文章教程 > 正文

如何使用CSS 新语法grid-area来设置网格布局

xsobi 2024-11-23 10:46 7 浏览

grid-area CSS 属性是一种简写,它通过在一个声明中设置网格行开始、网格列开始、网格行结束和网格列结束的值来指定网格布局中网格项的位置和大小。

.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}

.grid-item:nth-child(2) {
  grid-area: 2 / 4 / 4 / 6;

  /* is equivalent to: */
  grid-row-start: 2;
  grid-column-start: 4;
  grid-row-end: 4;
  grid-column-end: 6;
} 

由于 CSS Grid 的默认自动放置行为,此示例中的第二个网格项通常放置在网格第一行的第二列中。但是,由于我们声明了网格面积并将其设置为将网格项的起始边缘和结束边缘与我们所需的网格线对齐,因此该项移动到第二行和第四列,并在两个方向上跨越两条轨道,以满足正确的结束网格线。

使用网格区域 CSS 属性设置第二个网格项的位置和大小。

成分属性

如前所述,网格区域属性是结合了四个属性的简写s:


grid-column-start

.element { grid-column-start: 3; }


grid-column-end

.element { grid-column-end: 4; }


grid-row-start

.element { grid-row-start: 2; }


grid-row-end

.element { grid-row-end: 3; }


Syntax 语法

grid-area: <grid-line> [ / <grid-line> ]{0,3}


此属性最多可以采用四个值,由正斜杠 (/) 分隔。

设置四个值

如果 <grid-line> 设置了

  • 第一个值设置网格行开始属性。
  • 第二个值设置网格列开始属性。
  • 第三个值设置网格行结束属性。
  • 第四个值设置网格列结束属性。
.grid-item {
  grid-area: 2 / 4 / 3 / 6;

  /* is equivalent to: */
  grid-row-start: 2;
  grid-column-start: 4;
  grid-row-end: 3;
  grid-column-end: 6;
} 

设置三个值


  • 第一个值设置网格行开始属性。
  • 第二个值设置网格列开始属性。如果值为 <custom-ident>.否则,网格列端设置为 auto。
  • 第三个值设置网格行结束属性。
/* <custom-ident> */
.grid-item {
  grid-area: 2 / area / 4;
  
  /* is equivalent to */
  grid-row-start: 2;
  grid-column-start: area;
  grid-row-end: 4;
  grid-column-end: area;
}

/* <grid-line> */
.grid-item {
  grid-area: 2 / 4 / 3;

  /* is equivalent to: */
  grid-row-start: 2;
  grid-column-start: 4;
  grid-row-end: 3;
  grid-column-end: auto;
} 
 

设置两个值


  • 第一个值设置网格行开始属性。如果值为 <custom-ident>.否则,网格行结束设置为自动。
  • 第二个值设置网格列开始属性。如果值为 <custom-ident>.否则,网格列端设置为 auto。
/* <custom-ident> */
.grid-item {
  grid-area: area / 4;
  
  /* is equivalent to */
  grid-row-start: area;
  grid-column-start: 4;
  grid-row-end: area;
  grid-column-end: auto;
}

/* another <custom-ident> example */
.grid-item {
  grid-area: area / another-area;
  
  /* is equivalent to */
  grid-row-start: area;
  grid-column-start: another-area;
  grid-row-end: area;
  grid-column-end: another-area;
}

/* <grid-line> */
.grid-item {
  grid-area: 2 / 4;

  /* is equivalent to */
  grid-row-start: 2;
  grid-column-start: 4;
  grid-row-end: auto;
  grid-column-end: auto;
} 
 
 

设置1个值


/* <custom-ident> */
.grid-item {
  grid-area: area;
  
  /* is equivalent to */
  grid-row-start: area;
  grid-column-start: area;
  grid-row-end: area;
  grid-column-end: area;
}

/* <grid-line> */
.grid-item {
  grid-area: 2;

  /* is equivalent to */
  grid-row-start: 2;
  grid-column-start: auto;
  grid-row-end: auto;
  grid-column-end: auto;
} 
 

理解此语法

基于值数量的不同方案 <custom-ident> - 更不用说案例 - 乍一看可能看起来很复杂和奇怪。但如果你仔细想想,这一切都是有道理的。

以以下网格项为例:

.grid-item {
  grid-area: 2 / 4 / 3;
}


在这里,省略了grid-column-end(因为这是一个三值语法),grid-column-start设置为 4。grid-column-end 属性不能也为 4,因为网格项的起始边缘和结束边缘将指向同一行。浏览器不会将起始边缘与 4 对齐,并将网格项跨越一列作为默认行为。这就是为什么当一条边没有值时,它会设置为自动——以防它的另一条边指向带有数值的网格线。

现在,如果将网格列开始值设置为名称怎么办?例如,用 x 代替 4:

.grid-item {
  grid-area: 2 / x / 3;
}

X 值可以是网格线或网格区域的名称。如果有一条名为 x 的网格线,则网格列端也设置为 x,但由于网格项的两个列边缘都指向同一网格线 — x — 浏览器的默认行为再次是充当好像网格列结束设置为自动并且网格项跨越一列。

另一方面,如果存在一个名为 x 的网格区域,则 grid-column-start 设置为该网格区域的起始边缘,而 grid-column-end 设置为其结束边缘。

当你在代码中看到它时,更容易理解所有这些:

.grid-item {
  grid-area: 2 / x / 3;

  /* is equivalent to */
  grid-row-start: 2;
  grid-column-start: x-start;
  grid-row-end: 3;
  grid-column-end: x-end;
} 

/* Keyword value */
grid-area: auto;

/* <custom-ident> value */
grid-area: my-area;
grid-area: main-start / sidebar-start;
grid-area: main-start / sidebar-start / footer-start / main-end;
grid-area: line1 / line2 / line3 / line4;

/* <integer> + <custom-ident> values */
grid-area: 3;
grid-area: 2 / -3;
grid-area: main 2;
grid-area: 2 a / 4 b / 2 x;

/* span + <integer> + <custom-ident> values */
grid-area: span 3;
grid-area: 1 / 3 / span 2 / 5;
grid-area: 1 / span myline;
grid-area: 2 / span gridline 3;

/* Global values */
grid-area: inherit;
grid-area: initial; /* same as `auto` */
grid-area: revert;
grid-area: revert-layer;
grid-area: unset;

auto

这是默认值。它指示默认范围 (1) 和自动放置行为,这意味着网格项将自动放置在下一个可用的空网格单元格中。

<custom-ident>

此语法允许您使用整数来引用编号的网格线,或使用字符串来引用命名网格线或命名网格区域。换句话说,可以通过网格项边缘的数字索引或名称来指定网格线。

按行号定位项目

每个网格轨道之前和之后都有两条网格线,从数字 1 开始,自动为其分配一个数字索引。

演示行和列网格轨道的索引。

在本文的第一个示例中,我们使用此语法通过索引(2 和 4)引用第二行和第四行网格线,以将网格项的开始边缘和结束边缘与第二行和第三行的开始边缘和结束边缘对齐。此外,我们参考第四列和第六列网格线,将网格项的开始和结束边缘与第四列和第五列的开始和结束边缘对齐。

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

请注意,您也可以使用负数来指代网格线,但它从网格的结束边缘开始计数。以下代码指向上一示例中的相同网格线,但计数相反:

.grid-item:nth-child(2) {
  grid-column: -4 / -4 / -2 / -2; /* same as: grid-area: 2 / 4 / 4 / 6; */
}

请注意,负整数已分配给我们的网格:

使用网格区域 CSS 属性将第二个网格项放入第二行和第三行以及第四列和第五列。

按行名定位元素

您可以使用网格模板列和网格模板行基于线条的放置网格属性为网格线指定自定义名称,以按其名称引用该线。

让我们回到我们的示例,并像这样命名列和行轨道行:

.grid {
  display: grid;
  grid-template-rows: 100px [row2] 100px 100px [row4] 100px;
  grid-template-columns: 1fr 1fr 1fr [fourth] 1fr 1fr [second-to-last] 1fr;
}

我们可以通过自定义名称(row2、row4、第四和倒数第二)来引用第三行和第五行,而不是它们的索引值(分别为 2、4、4 和 6):

.grid-item:nth-child(2) {
  grid-area: row2 / fourth / row4 / second-to-last; /* same as index numbers 2 / 4 / 4 / 6 */
}

<custom-ident> 请注意,不能采用 span 值。 span 是网格放置属性的保留关键字(例如 grid-column: 1 / span 2)。

通过grid areas来定位元素

使用 grid-template-areas 属性定义网格区域时,将根据区域的名称免费获得隐式行名称。例如,名称为 content 的网格区域在其前面生成一个名为 content-start 的行,在其之后生成一个名为 content-end 的行。您可以参考这些行来设置网格项的位置。

.grid-item:nth-child(2) {
  grid-area: content-start / content-start / content-end / content-end;
}

或者,您可以引用区域的名称,将项目定位在名为 area 的内容的开始行和结束行:

.grid-item:nth-child(2) {
  grid-area: content;
}

如下是完整例子

<body>
  <header></header>
  <main></main>
  <aside></aside>
  <footer></footer>
</body>
body {
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: min-content 1fr min-content;
  grid-template-areas:
    "header header header"
    "content content sidebar"
    "footer footer footer";
}

header {
  grid-area: header;
}

main {
  grid-area: content;
}

aside {
  grid-area: sidebar;
}

footer {
  grid-area: footer;
}

这将设置网格元素在网格中的位置,我们希望它们在网格中的位置.

使用网格区域 CSS 属性按名称将网格项放入网格区域中。

<integer> && <custom-ident>?

这种语法风格允许您在存在重复名称时按网格线定位网格项。如果存在同名的网格线,则此语法有助于指定要引用的网格线。

.grid {
  display: grid;
  grid-template-columns: [a] 1fr [b] 1fr [b] 1fr [b] 1fr [b];
  grid-template-rows: [x] 1fr [y] 1fr [y] 1fr [y] 1fr [y];

  /*
    Using repeat() function also gives you repeated named grid line, for example:
    grid-template-columns: repeat(3, [b] 1fr);
  */
}

假设您想在行轨道中选择第三行,但该行与第二、第四和最后一个网格线同名 — 它们都称为 y。由于名为 y 的第二行是第三条网格线,因此可以使用 2 选择它作为起点。在以下示例中,相同的计数方式适用于网格面积的其他值:

.grid-item:nth-child(2) {
  grid-area: 2 y / 3 b / 4 y / 4 b;

  /* This is equivalent to: */
  grid-row-start: 2 y;
  grid-column-start: 3 b;
  grid-row-end: 4 y;
  grid-column-end: 4 b;
} 

请注意,值的顺序无关紧要。我们也可以像这样编写前面的代码:

.grid-item:nth-child(2) {
  grid-area: y 2 / b 3 / y 4 / b 4;
}

与前面的语法一样,您也可以使用负整数来计算从网格结束边缘开始的网格线。在我们的示例中,如果我们想引用相同的行,我们可以从网格的结束边缘开始计数并像这样写:

.grid-item:nth-child(2) {
  grid-area: -3 y / -2 b / -1 y / -1 b;
}

请注意,整数值不能为零。

span && [ <integer> || <custom-ident> ]

此语法允许网格项跨越网格轨道。可以通过三种不同的方式指定它。

请注意,如果未在此语法中的任何位置指定整数,则默认值为 1。

span <integer>

使用 span 关键字后跟整数表示网格项从特定网格线跨越的轨道数。例如,如果我们希望网格项跨越三个行轨道和两个列轨道朝向其起始边缘,我们可以应用以下值:

.grid-item:nth-child(2) {
  grid-area: span 3 / span 2;

  /* This is equivalent to */
  grid-row-start: span 3;
  grid-column-start: span 2;
  grid-row-end: auto;
  grid-column-end: auto;
} 

网格项使用网格区域 CSS 属性跨越两列和三行。

span <custom-ident>

还可以将 span 关键字与网格线的名称组合在一起,以使网格项扩展,直到到达指定的网格线。

.grid-item:nth-child(3) {
  grid-area: auto / 3 / auto / span lastline;
}

由于网格项的起始线是已知的 (3),我们可以跨越该项,直到它到达名为 lastline 的列网格线。

网格项跨越网格,直到它使用网格区域 CSS 属性到达名为 lastline 的指定网格线。

span <custom-ident> <integer>

如果指定的网格线名称分配给多个网格线 - 换句话说,如果我们重复命名的网格线 - 我们需要说出我们想要定位的网格线。为此,我们可以在值中添加一个整数,指定我们引用的网格线。

以以下网格为例:

.grid-container {
  display: grid;
  grid-template-columns: [y] 1fr [x] 1fr [x] 1fr [y] 1fr [x] 1fr [x];
}

.grid-item:nth-child(3) {
  grid-area: 2 / 2 / 4 / span x 2;
}

我们将网格项的起始行设置为第二列行。然后我们希望它向前跨度,直到它到达名为 x 的网格线。由于我们希望它是第二条x网格线,因此我们最终得到span x 2。

因此,我们的网格项从第二行开始,如下图所示。它命中的第一行是第一行 x,后跟 y,最后,它命中所需的第二行,名为 x。

S使用 grid-area 属性将网格项的位置从第二列行调整到第二个 x 命名行。

当您希望使用网格项的名称将网格项跨越到网格线时,此语法非常有用。但请注意,使用此方法有多个同名的网格线,因此我们添加一个整数来表示我们想要该网格线的 N。

请参阅网格行开始、网格行结束、网格列开始和网格列结束,以获取每个构成属性的详细信息和语法示例。

例子

让我们通过几个例子来演示如何使用网格区域在网格上放置项目。

创建多层横幅

假设此图形是由您的设计团队交给您的:

他们还提供了另一个版本来向您展示它是在网格上设计的:

让我们首先设置我们的 HTML:

<figure>
  <img class="back" src="back.jpg" alt="Please">
  <img class="middle" src="middle.jpg" alt="fill your alt">
  <img class="front" src="front.jpg" alt="properly">
  <figcaption>Freedom is the oxygen of the soul...</figcaption>
</figure>

设计中有十四列九行。我们可以这样写出来:

figure {
  display: grid;
  grid-template-columns: repeat(14, 50px);
  grid-template-rows: repeat(9, 50px);
}

我们需要将所有这些子<img>元素放入其右侧网格区域中。为此,我们使用网格区域属性:

.back {
  grid-area: 1 / 3 / -2 / -1;
}

.middle {
  grid-area: 2 / 1 / 7 / 9;
}

.front {
  grid-area: 4 / 4 / -1 / -3;
}

figcaption {
  grid-area: -3 / -4 / -1 / -1;
}

您可以在下图中看到结果:

查看演示以了解有关此示例的更多详细信息:

堆叠网格项

在网格上定位项目时,我们可以将它们堆叠或重叠在一起。这使我们能够有时使用 CSS 网格作为绝对定位的替代方案。例如,我们可以在不使用位置属性的情况下将标题层放在图像顶部,如下所示:

<figure>
  <img src="image.png" alt="how dare you leave alt empty?">
  <figcaption>The caption of our image</figcaption>
</figure>
figure {
  display: grid;
}

img,
figcaption {
  grid-area: 1 / 1 / -1 / -1;
}

默认情况下,网格项按源顺序堆叠,但您可以使用 z-index 属性控制其级别。在下面的示例中,我们重叠了一些项目,我们使用 z-index 属性将第二个项目带到堆栈上下文中的最高级别:

.item:nth-child(2) {
  grid-area: 2 / 2 / 4 / 4;
  z-index: 1;
}

使用 z-index 属性将第二个网格项置于堆栈顶部。

可访问性

使用网格放置属性时需要注意的一点是重新排列项目引起的问题。更改项目的位置时,只有网格项目的可视顺序会更改,并且该顺序可能与原始文档顺序不同。对于在键盘上按 Tab 键浏览文档或收听按与 HTML 相同的顺序读取内容的屏幕阅读器的人来说,这可能会导致非常糟糕的体验。

因此,当元素的 HTML 顺序很重要时,请避免更改网格项的顺序。例如,它可能适用于随机图像库,但可能不适用于表单输入。

但是,在撰写本文时,有一项解决此问题的建议,有望在未来解决这一问题。

.grid {
  grid-template-columns: 
  grid-template-rows: 
}
.item:nth-child(3) {
  grid-area: 
}



相关推荐

js向对象中添加元素(对象,数组) js对象里面添加元素

一、添加一个元素对象名["属性名"]=值(值:可以是一个值,可以是一个对象,也可以是一个数组)这样添加进去的元素,就是一个值或对象或数组...

JS小技巧,如何去重对象数组?(一)

大家好,关于数组对象去重的业务场景,想必大家都遇到过类似的需求吧,这对这样的需求你是怎么做的呢。下面我就先和大家分享下如果是基于对象的1个属性是怎么去重实现的。方法一:使用.filter()和....

「C/C++」之数组、vector对象和array对象的比较

数组学习过C语言的,对数组应该都不会陌生,于是这里就不再对数组进行展开介绍。模板类vector模板类vector类似于string,也是一种动态数组。能够在运行阶段设置vector对象的长度,可以在末...

如何用sessionStorage保存对象和数组

背景:在工作中,我将[{},{}]对象数组形式,存储到sessionStorage,然后ta变成了我看不懂的形式,然后我想取之用之,发现不可能了~记录这次深刻的教训。$clickCouponIndex...

JavaScript Array 对象 javascript的array对象

Array对象Array对象用于在变量中存储多个值:varcars=["Saab","Volvo","BMW"];第一个数组元素的索引值为0,第二个索引值为1,以此类推。更多有...

JavaScript中的数组Array(对象) js array数组

1:数组Array:-数组也是一个对象-数组也是用来存储数据的-和object不同,数组中可以存储一组有序的数据,-数组中存储的数据我们称其为元素(element)-数组中的每一个元素都有一...

数组和对象方法&amp;数组去重 数组去重的5种方法前端

列举一下JavaScript数组和对象有哪些原生方法?数组:arr.concat(arr1,arr2,arrn);--合并两个或多个数组。此方法不会修改原有数组,而是返回一个新数组...

C++ 类如何定义对象数组?初始化数组?linux C++第43讲

对象数组学过C语言的读者对数组的概念应该很熟悉了。数组的元素可以是int类型的变量,例如int...

ElasticSearch第六篇:复合数据类型-数组,对象

在ElasticSearch中,使用JSON结构来存储数据,一个Key/Value对是JSON的一个字段,而Value可以是基础数据类型,也可以是数组,文档(也叫对象),或文档数组,因此,每个JSON...

第58条:区分数组对象和类数组对象

示例设想有两个不同类的API。第一个是位向量:有序的位集合varbits=newBitVector;bits.enable(4);bits.enable([1,3,8,17]);b...

八皇后问题解法(Common Lisp实现)

如何才能在一张国际象棋的棋盘上摆上八个皇后而不致使她们互相威胁呢?这个著名的问题可以方便地通过一种树搜索方法来解决。首先,我们需要写一个函数来判断棋盘上的两个皇后是否互相威协。在国际象棋中,皇后可以沿...

visual lisp修改颜色的模板函数 怎么更改visual studio的配色

(defunBF-yansemokuai(tuyuanyanse/ss)...

用中望CAD加载LISP程序技巧 中望cad2015怎么加载燕秀

1、首先请加载lisp程序,加载方法如下:在菜单栏选择工具——加载应用程序——添加,选择lisp程序然后加载,然后选择添加到启动组。2、然后是添加自定义栏以及图标,方法如下(以...

图的深度优先搜索和广度优先搜索(Common Lisp实现)

为了便于描述,本文中的图指的是下图所示的无向图。搜索指:搜索从S到F的一条路径。若存在,则以表的形式返回路径;若不存在,则返回nil。...

两个有助于理解Common Lisp宏的例子

在Lisp中,函数和数据具有相同的形式。这是Lisp语言的一个重大特色。一个Lisp函数可以分析另一个Lisp函数;甚至可以和另一个Lisp函数组成一个整体,并加以利用。Lisp的宏,是实现上述特色的...