MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

CSS grid-template-columns与grid-template-rows的灵活运用

2023-08-234.2k 阅读

CSS grid - template - columns与grid - template - rows的基础概念

grid - template - columns

grid - template - columns属性用于定义网格容器中列的布局。它允许我们以一种灵活且直观的方式设置每一列的宽度。语法如下:

grid - template - columns: <track - list>;

这里的<track - list>是一个用空格分隔的值列表,每个值代表一列的宽度。常见的值类型有以下几种:

  1. 固定长度值(Length):可以使用绝对单位如px,也可以使用相对单位如emrem。例如,要创建三列,第一列宽200px,第二列宽300px,第三列宽150px,可以这样写:
.grid {
    display: grid;
    grid - template - columns: 200px 300px 150px;
}

在HTML中配合以下代码:

<div class="grid">
    <div class="item">Item 1</div>
    <div class="item">Item 2</div>
    <div class="item">Item 3</div>
</div>
.item {
    background - color: lightblue;
    padding: 20px;
    border: 1px solid gray;
}

这样就会呈现出三列宽度固定的网格布局。

  1. 百分比(Percentage):基于网格容器的宽度来计算列宽。比如,要创建两列,第一列占容器宽度的40%,第二列占60%,代码如下:
.grid {
    display: grid;
    grid - template - columns: 40% 60%;
}

这种方式在响应式设计中很有用,当容器宽度改变时,列宽会按比例自动调整。

  1. fr单位(Fractional Unit)fr代表一个灵活的分数单位,用于分配剩余空间。例如,要创建三列,第一列宽200px,剩下的空间平均分配给第二列和第三列,可以这样写:
.grid {
    display: grid;
    grid - template - columns: 200px 1fr 1fr;
}

这里1fr表示将剩余空间分成一份,两个1fr就意味着将剩余空间平均分成两份,分别给第二列和第三列。

grid - template - rows

grid - template - rows属性与grid - template - columns类似,用于定义网格容器中行的布局。语法如下:

grid - template - rows: <track - list>;

<track - list>同样是用空格分隔的值列表,每个值代表一行的高度。常见的值类型也包括固定长度值、百分比和fr单位。例如,要创建三行,第一行高100px,第二行高200px,第三行高150px,可以这样写:

.grid {
    display: grid;
    grid - template - rows: 100px 200px 150px;
}

结合HTML代码:

<div class="grid">
    <div class="item">Item 1</div>
    <div class="item">Item 2</div>
    <div class="item">Item 3</div>
</div>
.item {
    background - color: lightgreen;
    padding: 20px;
    border: 1px solid gray;
}

就会呈现出高度固定的三行布局。

如果使用百分比,例如要创建两行,第一行占容器高度的30%,第二行占70%,代码如下:

.grid {
    display: grid;
    grid - template - rows: 30% 70%;
}

当使用fr单位时,假设要创建三行,第一行占用剩余空间的2份,第二行和第三行各占用1份,可以这样写:

.grid {
    display: grid;
    grid - template - rows: 2fr 1fr 1fr;
}

结合使用grid - template - columns与grid - template - rows创建复杂布局

简单的表格布局

我们可以利用grid - template - columnsgrid - template - rows来创建类似表格的布局。例如,要创建一个简单的三行三列的表格布局,代码如下:

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

这里repeat(3, 1fr)表示重复创建三列,每列宽度为1fr,即平均分配剩余空间。repeat(3, 50px)表示重复创建三行,每行高度为50px。gap属性用于设置网格项之间的间距。HTML代码如下:

<div class="grid">
    <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>
.item {
    background - color: lightcoral;
    display: flex;
    justify - content: center;
    align - items: center;
}

这样就创建了一个简单的三行三列的表格状布局,每个单元格有一定的间距。

多区域布局

假设我们要创建一个复杂的网页布局,包含页眉、侧边栏、主要内容区域和页脚。可以这样使用grid - template - columnsgrid - template - rows

body {
    display: grid;
    grid - template - columns: 200px 1fr;
    grid - template - rows: 80px 1fr 60px;
    gap: 10px;
}
header {
    grid - column - start: 1;
    grid - column - end: 3;
    grid - row - start: 1;
    grid - row - end: 2;
    background - color: lightskyblue;
}
aside {
    grid - column - start: 1;
    grid - column - end: 2;
    grid - row - start: 2;
    grid - row - end: 3;
    background - color: lightgreen;
}
main {
    grid - column - start: 2;
    grid - column - end: 3;
    grid - row - start: 2;
    grid - row - end: 3;
    background - color: lightyellow;
}
footer {
    grid - column - start: 1;
    grid - column - end: 3;
    grid - row - start: 3;
    grid - row - end: 4;
    background - color: lightpink;
}

HTML代码如下:

<header>Header</header>
<aside>Sidebar</aside>
<main>Main Content</main>
<footer>Footer</footer>

这里通过grid - template - columns定义了两列,第一列宽200px作为侧边栏,第二列1fr占据剩余空间作为主要内容区域。通过grid - template - rows定义了三行,第一行80px作为页眉,第二行1fr作为内容区域,第三行60px作为页脚。然后通过grid - column - startgrid - column - endgrid - row - startgrid - row - end属性来确定每个元素在网格中的位置。

响应式设计中的应用

基于媒体查询调整布局

在响应式设计中,我们常常需要根据不同的屏幕尺寸调整网格布局。可以结合媒体查询来改变grid - template - columnsgrid - template - rows的值。例如,在大屏幕上,我们希望有一个三列布局,而在小屏幕上,变成一列布局。代码如下:

.grid {
    display: grid;
    gap: 10px;
}
@media (min - width: 768px) {
    .grid {
        grid - template - columns: 1fr 1fr 1fr;
        grid - template - rows: auto;
    }
}
@media (max - width: 767px) {
    .grid {
        grid - template - columns: 1fr;
        grid - template - rows: auto;
    }
}

HTML代码:

<div class="grid">
    <div class="item">Item 1</div>
    <div class="item">Item 2</div>
    <div class="item">Item 3</div>
</div>
.item {
    background - color: lavender;
    padding: 20px;
}

在屏幕宽度大于等于768px时,会呈现三列布局,而在屏幕宽度小于768px时,会变成一列布局。这样可以根据不同设备的屏幕尺寸提供更好的用户体验。

自适应图片布局

我们可以利用grid - template - columnsgrid - template - rows来创建自适应的图片布局。例如,创建一个图片画廊,在大屏幕上每行显示四张图片,在中等屏幕上每行显示三张图片,在小屏幕上每行显示一张图片。代码如下:

.gallery {
    display: grid;
    gap: 10px;
}
@media (min - width: 1024px) {
   .gallery {
        grid - template - columns: repeat(4, 1fr);
        grid - template - rows: auto;
    }
}
@media (min - width: 768px) and (max - width: 1023px) {
   .gallery {
        grid - template - columns: repeat(3, 1fr);
        grid - template - rows: auto;
    }
}
@media (max - width: 767px) {
   .gallery {
        grid - template - columns: 1fr;
        grid - template - rows: auto;
    }
}
.gallery img {
    width: 100%;
    height: auto;
    display: block;
}

HTML代码:

<div class="gallery">
    <img src="image1.jpg" alt="Image 1">
    <img src="image2.jpg" alt="Image 2">
    <img src="image3.jpg" alt="Image 3">
    <img src="image4.jpg" alt="Image 4">
    <img src="image5.jpg" alt="Image 5">
    <img src="image6.jpg" alt="Image 6">
</div>

通过这种方式,图片画廊可以根据不同屏幕尺寸自动调整布局,确保图片在各种设备上都能合适地展示。

与其他CSS属性的协同工作

与grid - auto - columns和grid - auto - rows的配合

grid - auto - columnsgrid - auto - rows属性用于设置隐式网格轨道(即那些没有在grid - template - columnsgrid - template - rows中显式定义的轨道)的大小。例如,我们有一个网格布局,其中一些网格项跨越了多个列或行,导致出现隐式网格轨道。我们可以使用grid - auto - columnsgrid - auto - rows来设置这些隐式轨道的宽度和高度。

.grid {
    display: grid;
    grid - template - columns: 1fr 1fr;
    grid - template - rows: 100px;
    grid - auto - columns: 200px;
    grid - auto - rows: 150px;
    gap: 10px;
}
.item1 {
    grid - column - start: 1;
    grid - column - end: 3;
    grid - row - start: 1;
    grid - row - end: 2;
    background - color: lightblue;
}
.item2 {
    grid - column - start: 1;
    grid - column - end: 2;
    grid - row - start: 2;
    grid - row - end: 3;
    background - color: lightgreen;
}

HTML代码:

<div class="grid">
    <div class="item1">Item 1</div>
    <div class="item2">Item 2</div>
</div>

这里grid - template - columns定义了两列,grid - template - rows定义了一行高度为100px。由于.item1跨越了两列,.item2在新的一行,所以会产生隐式的列和行。grid - auto - columns设置隐式列宽为200px,grid - auto - rows设置隐式行高为150px。

与justify - items和align - items的协同

justify - itemsalign - items属性用于控制网格项在网格单元格内的水平和垂直对齐方式。它们与grid - template - columnsgrid - template - rows一起使用,可以进一步优化布局。例如:

.grid {
    display: grid;
    grid - template - columns: 1fr 1fr;
    grid - template - rows: 100px 100px;
    justify - items: center;
    align - items: center;
    gap: 10px;
}
.item {
    background - color: lightcoral;
}

HTML代码:

<div class="grid">
    <div class="item">Item 1</div>
    <div class="item">Item 2</div>
    <div class="item">Item 3</div>
    <div class="item">Item 4</div>
</div>

这里justify - items: center使网格项在水平方向上居中对齐,align - items: center使网格项在垂直方向上居中对齐。结合grid - template - columnsgrid - template - rows定义的网格布局,能够让内容在网格单元格中更好地呈现。

浏览器兼容性与解决方案

主流浏览器支持情况

目前,大多数现代浏览器都对grid - template - columnsgrid - template - rows有良好的支持。Chrome、Firefox、Safari等主流浏览器在较新的版本中都能很好地渲染基于网格布局的页面。然而,在一些旧版本的浏览器中,可能存在兼容性问题。例如,Internet Explorer对CSS网格布局的支持非常有限。

兼容性解决方案

  1. 特征检测:可以使用JavaScript进行特征检测,判断浏览器是否支持CSS网格布局。如果不支持,可以采用其他布局方式,如Flexbox或传统的浮动布局。以下是一个简单的特征检测示例:
if (!('grid' in document.createElement('div').style)) {
    // 不支持网格布局,采用其他布局
    document.body.classList.add('fallback - layout');
}

在CSS中,可以针对.fallback - layout类定义不同的布局样式。

  1. 前缀使用:在一些较旧的浏览器中,可能需要添加供应商前缀来支持网格布局。例如:
.grid {
    display: -webkit - grid;
    display: -moz - grid;
    display: grid;
    grid - template - columns: 1fr 1fr;
    grid - template - rows: 100px 100px;
}

这里-webkit -前缀用于WebKit内核的浏览器(如Chrome、Safari),-moz -前缀用于Firefox。虽然现代浏览器大多不需要这些前缀,但在考虑兼容性时,添加前缀可以确保在旧版本浏览器中也能尽量正确地渲染布局。

通过了解grid - template - columnsgrid - template - rows的基础概念、结合使用创建复杂布局、在响应式设计中的应用、与其他CSS属性的协同工作以及处理浏览器兼容性问题,前端开发者可以充分发挥CSS网格布局的强大功能,创建出更加灵活、美观且适应各种设备的网页布局。在实际项目中,需要根据具体需求和目标浏览器进行合理的选择和优化,以提供最佳的用户体验。