我正在尝试用CSS制作卡片组件,我认为这很简单,但是我在CSS网格属性方面苦苦挣扎。另外,在这种情况下,我不能使用flexbox ,原因不值得解释:)
布局非常简单:左侧是图片,右侧是一些文本。
<div class="card">
<figure card="card__img">
<img src="https://via.placeholder.com/600" width="600" height="600">
</figure>
<p class="card__txt">Lorem ipsum tempus fugit.</p>
</div>
这是棘手的部分:图像是可选,并且在显示时,宽度不得超过50%。
当我为图片添加最大宽度时,如果图片不存在,文本将不会展开。
这是我目前的状态:
.card {
display: grid;
column-gap: 1em;
grid-template-columns: minmax(0, 50%) 1fr;
}
我试图弄乱grid-template-columns
的宽度,但是我对此还不熟悉。
您可以在此Codepen上看到它的运行情况:https://codepen.io/tcharlss/pen/gVvOjY
这是代码段:
/* Layout stuff I'm strugling width*/
.card {
display: grid;
column-gap: 1em;
grid-template-columns: minmax(0, 50%) 1fr;
}
/* Decoration & miscellaneous */
body { font-family: sans; }
.container {
display: grid;
column-gap: 1em;
grid-template-columns: repeat(auto-fill, 35em);
}
.container + .container {
margin-top: 2em;
}
.explication {
color: hsl(230, 100%, 45%);
font-family: monospace;
font-style: italic;
}
.card {
border: 1px solid hsl(230, 100%, 45%);
min-height: 18em;
}
.card__txt {
background-color: hsl(0, 0%, 90%);
margin: 0;
}
figure {
margin: 0;
}
img {
max-width: 100%;
height: auto;
}
<div class="container">
<div class="col">
<p class="explication">If an image is present, it can't be wider then 50%</p>
<div class="card">
<figure card="card__img">
<img src="https://via.placeholder.com/600" width="600" height="600">
</figure>
<p class="card__txt">Lorem ipsum tempus fugit. Aut rerum nostrum qui adipisci est aut. Est error omnis sit velit.</p>
</div>
</div>
<div class="col">
<p class="explication">Without image, the text should expand to fill all the available space</p>
<div class="card">
<p class="card__txt">Lorem ipsum tempus fugit. Aut rerum nostrum qui adipisci est aut. Est error omnis sit velit.</p>
</div>
</div>
</div>
答案 0 :(得分:2)
最容易想到的一种方法是,以一种方式设置通用.card__text
元素的样式,然后使用+
组合器设置.card__img
元素之后的元素的样式与此不同:
/* here we use Grid layout, setting two columns
each of 1fr (using the repeat() function): */
.card {
display: grid;
grid-gap: 1em;
grid-template-columns: repeat(2, 1fr);
}
/* setting the default presentation of the
.card__txt elements; positioning them
in the first column, spanning two
columns: */
.card__txt {
grid-column: 1 / span 2;
}
/* separately styling the .card__txt elements
that follow a .card__img element; here we
place them in the second column: */
.card__img + .card__txt {
grid-column: 2;
}
/* Decoration & miscellaneous */
body {
font-family: sans;
}
.container {
display: grid;
column-gap: 1em;
grid-template-columns: repeat(auto-fill, 35em);
}
.container+.container {
margin-top: 2em;
}
.explication {
color: hsl(230, 100%, 45%);
font-family: monospace;
font-style: italic;
}
.card {
border: 1px solid hsl(230, 100%, 45%);
min-height: 18em;
}
.card__txt {
background-color: hsl(0, 0%, 90%);
margin: 0;
}
figure {
margin: 0;
}
img {
max-width: 100%;
height: auto;
}
/* changes */
.card {
display: grid;
grid-gap: 1em;
grid-template-columns: repeat(2, 1fr);
}
.card__txt {
grid-column: 1 / span 2;
}
.card__img+.card__txt {
grid-column: 2;
}
<div class="container">
<div class="col">
<p class="explication">If an image is present, it can't be wider then 50%</p>
<div class="card">
<!-- Note the correction, in your posted code the following
was written:
<figure card="card__img">
I corrected 'card' to 'class' -->
<figure class="card__img">
<img src="https://via.placeholder.com/600" width="600" height="600">
</figure>
<p class="card__txt">Lorem ipsum tempus fugit. Aut rerum nostrum qui adipisci est aut. Est error omnis sit velit.</p>
</div>
</div>
<div class="col">
<p class="explication">Without image, the text should expand to fill all the available space</p>
<div class="card">
<p class="card__txt">Lorem ipsum tempus fugit. Aut rerum nostrum qui adipisci est aut. Est error omnis sit velit.</p>
</div>
</div>
</div>
答案 1 :(得分:1)
我认为the answer by @DavidThomas和在这种特定情况下一样好。
在当前的Grid(Level 1)迭代中似乎没有什么更好的。
为清楚起见,以下是对该问题的描述:
您已经定义了一个两列网格:
.card {
display: grid;
column-gap: 1em;
grid-template-columns: minmax(0, 50%) 1fr;
}
使用grid-template-columns
创建了 explicit 列。这样的列从一开始就内置在网格中,无法删除。这些列已被占用或未被占用。
这就是示例中没有图像的文本不会展开的原因:第一列保留其空间,该空间定义为minmax(0, 50%)
。
人们可能会认为该列在未占用时将默认为 min 值(0
),从而使第二列(1fr
)在容器中扩展。
但事实并非如此。 The minmax()
function defaults to the max value.这就是为什么您在示例中看到50%的空白区域而没有图像的原因。
除了@DavidThomas提出的选择器向导之外,我能想到的解决方案的最佳方法包括从grid-template-columns
切换到grid-auto-columns
。
这会将您从显式网格(始终存在列)带到隐式网格(必要时存在列)。此方法还可以消除列间隙。
但是这种方法有许多障碍要克服,包括:
minmax(0, 50%)
将始终是第一列; order
属性将无济于事,因为它适用到项目,而不是列); min-content
并将项目设置为max-width: 50%
都不起作用,因为在这种情况下,您使用的是图像,浏览器根据图像的宽度计算列宽指定的值,而不是使用的值(demo)。但是,如果您想采用这种方法,请按以下步骤进行操作:
答案 2 :(得分:0)
结合了repeat()
,auto-fit
和minmax()
的解决方案:
.card {
display: grid;
column-gap: 1em;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); }
每个项目最多可以占可用空间的一小部分,因此,如果有2个,则为50%,如果有一个,则为100%。
minmax
的最小值为100px,则auto-fit
将创建5个100px的显式列,将您的项目放置在这些列中(如果有5个以上的项目,则创建新行),如果某些列为空,则将其折叠(如果有的话,将其间隙),最后将最多包含项的列拉伸到最大值(从minmax
开始)。我叉了你的笔here。
我使用了CSS-Tricks article来介绍自动调整/自动填充和Firefox检查器网格工具。