网站建设时布局设计需要创新,然后就往往会遇到排版很不好做的一些设计,实现起来难度很大。
这篇文章是对具有独特布局和一组约束的特定组件的案例研究。构建适用于大量需求以及未知内容的布局,需要应用横向思维和大量问题解决方案来找到正确的解决方案。
一个这样的组件看起来像这样:
它由一个图像或视频,一个水平和垂直居中的大标题和一个文本块组成。在这种情况下,文本块与图像的顶部对齐,但如果由内容作者选择,则可以同等地对齐到图像的底部。
你可能会想,并不是太繁重,而且应该用现代布局方法很简单。但是这个组件带有一组限制:
- 标题必须在组件内水平居中,并在图像上垂直居中。
- 文本块必须与图像的顶部或底部对齐,除非文本长于可用空间,在这种情况下,文本块应向上(或如果与底部对齐)向下延伸。
- 图像尺寸未知,并且不受宽高比的限制 – 换句话说,内容作者可以上传任何尺寸的图像,而不会导致它们被裁剪。
- 标题和文本块的长度也是未知的。
设计本身由一个24列网格和组件的多个变体组成 – 图像和文本块可以对齐各种不同的网格列。出于本文的目的,我们暂时不会关注列轴,因为这里的主要焦点是行轴上网格项的对齐。
我创建了相同组件的简化视图,这使我们可以更轻松地查看每个元素的边界框。(想象一下,粉红色轮廓是组件的边界框。)
让我们假设网格容器和直接子项(我们的网格项)的以下标记 – 为了本文的目的,我们将忽略这些元素中的每一个,这样我们就可以专注于布局:
<article class="grid">
<div class="grid__heading">Heading</div>
<figure class="grid__image"></figure>
<div class="grid__text"></div>
</article>
我们有以下CSS来定义我们的网格并在列轴上放置项目:
.grid {
display: grid;
grid-template-columns: minmax(0, 1fr) repeat(24, minmax(0, 60px)) minmax(0, 1fr);
column-gap: 20px;
}
.grid__heading {
/* Using a negative line for the grid-column-end value allows us to easily center the position of the heading when we have a large grid */
grid-column: 5 / -5;
}
.grid__image {
grid-column: 2 / 16;
}
.grid__text {
grid-column: span 5 / -1;
}
如果您对我们用于grid-template-columns
物业的价值感到好奇。
现在我们需要定义网格行。我最初的想法是我们可以grid-template-rows
如下定义属性:
.grid {
grid-template-rows: 1fr auto 1fr;
}
这给了我们一个中心行,其中auto
包含我们标题的值(因为我们不知道这将是多长时间,我们希望轨道增长以适应内容),以及两个周围的行1fr
。这两个外行将占用可用空间的相等比例。如果我们设置row-gap: 40px
(使用速记gap
这里grid-row-gap
和grid-column-gap
),那么我们将得到上方和标题下方一个40像素排水沟,保持它与文本块之间的空间。
我们也可以在Grid中使用flex对齐属性,这在这里非常有用。我正在使用align-items: center
水平居中我们的网格项目。我们需要这样做的原因尚不清楚,但如果我们的文本内容比可用空间长,我们很快就会发现它变得更有用。
.grid {
/* ...Other grid code */
grid-template-rows: 1fr auto 1fr;
gap: 40px 20px;
align-items: center;
}
现在我们可以将网格项放在行轴上:
.grid__heading {
grid-row: 2;
}
.grid__image {
/* From the start of the grid to the end */
grid-row: 1 / -1;
}
.grid__text {
grid-row: 1;
}
我们所有的项目当前都在它们的网格框中居中对齐,但是如果我align-self: flex-start
在文本块上使用那么该项目将对齐到组件的顶部,而标题和图像是集中对齐的(由于align-items: center
我们在网格本身)。
.grid__text {
grid-row: 1;
align-self: flex-start;
}
到现在为止还挺好。看起来我们已经固定了这种布局。只有一个问题:当文本块比标题和图像顶部之间的空间长时,组件会扩展以容纳它,推动图像并向下(这是我们想要的) – 但遗憾的是底部的网格也在扩展,为我们提供了额外的空间:
如果我们将多个组件堆叠在一起,那么它们之间的垂直空间将是不均匀的。这不太理想。我们想要的是组件在顶部(文本块的一侧)垂直生长,而不是底部。
要解决这个问题,我必须创造性地思考!让我们一步一步地完成解决方案。
首先,我们要将三排轨道尺寸更改为auto
:
.grid {
grid-template-rows: auto auto auto;
gap: 40px 20px;
align-items: center;
}
然后我们可以在现有行的上方添加一个额外的行,其高度为1fr
。使用fr
行轴上的单位会发生什么情况可能并不那么明显。在列轴上,我们知道网格的宽度(默认情况下为100%),因此很容易想象1fr
填充该空间比例的列轨道。当涉及行轴时,在这种情况下,我们网格的高度将由最高网格项目的高度确定 – 图像 – 当前从第一个网格线到最后一个网格线放置。
.grid {
grid-template-rows: 1fr auto auto auto;
gap: 40px 20px;
align-items: center;
}
我们添加的行实际上是一个隐藏的行 – 0
除非我们在其中放置内容,否则它将崩溃。
在我们查看项目放置之前,我们需要对网格容器做更多的事情。我们将设置row-gap
为0并在标题行和其相邻行之间添加40px的轨道。我们也可以删除align-items: center
,因为我们不再需要它了。
.grid {
grid-template-rows: 1fr auto 40px auto 40px auto;
gap: 0 20px;
}
既然我们的网格有六行,那么可视化将网格项放在行轴上的位置并不容易。有更多的网格线可以跟踪!在这里命名我们的网格线将非常有用。然后我们可以引用这些行名来放置我们的网格项。
.grid {
grid-template-rows:
[text-start] 1fr [image-start] auto [text-end]
40px [heading-start] auto [heading-end] 40px
auto [image-end];
gap: 0 20px;
}
.grid__heading {
grid-row: heading;
}
.grid__image {
grid-row: image;
}
.grid__text {
grid-row: text;
align-self: flex-start;
}
老鹰眼的读者可能会注意到我们的文本块现在跨越两个轨道(从网格线1开始),我们的图像不再从网格线1开始,而是从第2行开始。但是,视觉上没有任何改变。
当我们在文本块中添加更长的文本段落时,我们可以看到这些更改的好处。重要的是, -我们添加膨胀,同时图像和标题仍然是集中相互对准隐藏的行,而不在网格的底部添加额外的空间!
希望现在更明显的是为什么我们需要设置row-gap
为0而不是使用额外的轨道作为我们的排水沟:如果我们有40px row-gap
,即使文本内容较短,因此在网格的顶部也可以看到它,因此第一个轨道有完全崩溃了。遗憾的是,我们不能gap
在单个轴上为属性设置不同的值,否则我们不需要那些额外的行。
对于不同的组件变体 – 文本块低于标题而不是上面 – 我们只需更改grid-template-rows
属性以包含隐藏行和结尾而不是开头。
.grid--text-bottom {
grid-template-rows:
[media-start] auto 40px
[heading-start] auto [heading-end]
40px [text-start] auto [media-end]
1fr [text-end];
gap: 0 20px;
}
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/259357.html