【问题标题】:When first column is not present, remaining columns should occupy the space当第一列不存在时,其余列应占用空间
【发布时间】:2019-12-14 05:47:08
【问题描述】:

我正在尝试用 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

这里是sn-p的代码:

/* 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>

【问题讨论】:

  • 在您的代码中,在figure 元素中,修复属性名称。它不会解决问题,但也无济于事。

标签: html css css-grid


【解决方案1】:

一种方法,我能想到的最简单的方法是,以一种方式设置通用 .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>

JS Fiddle demo.

【讨论】:

  • 非常感谢大卫。我将采用该解决方案,它仍然足够简单且易于理解。在我的实际情况稍微复杂一点,我必须使用兄弟选择器,但想法保持不变:.card__img ~ .card__txt
【解决方案2】:

我认为the answer by @DavidThomas 在这种特殊情况下表现得非常好。

在当前的 Grid 迭代中似乎没有更好的东西 (Level 1)。

为了清楚起见,这里是对问题的描述:

您已经定义了一个两列网格:

.card {
  display: grid;
  column-gap: 1em;
  grid-template-columns: minmax(0, 50%) 1fr;
}

通过使用grid-template-columns,您已经创建了显式 列。此类列从一开始就内置在网格中,无法删除。有人或无人,这些列都存在。

这就是为什么没有图像的示例中的文本不会扩展:第一列保留其空间,定义为 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% 也不起作用,因为在这种情况下,您使用的是图像,并且浏览器会根据图像的指定来计算列宽 值,而不是 used 值 (demo)。

但是,如果您想采用这种方法,以下是它的详细工作原理:

【讨论】:

  • 非常感谢您的详细解释,现在很清楚为什么它不起作用了。我将进一步试验grid-auto-columns,目前我认为@ThomasDavid 的解决方案可以完成这项工作。
【解决方案3】:

repeat()auto-fitminmax() 组合的解决方案:

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

每个项目最多只能占可用空间的一小部分,如果有 2 个则为 50%,如果有 1 个则为 100%。

  • 一般机制

    例如容器为 500px(无间隙),minmax 的最小值为 100px,auto-fit 将创建 5 个 100px 的显式列,放置您在这些列中的项目(如果项目超过 5 个,则创建一个新行),如果某些列是空的,则折叠它们(以及它们的间隙,如果有的话),最后 用项目拉伸列最多达到最大值(来自minmax)。
  • 在您的示例中

    容器为 560 像素,间隙为 16 像素,因此自动适应创建 4 列 100 像素(加上 16*3=48 像素的间隙 - 它不能为 5 col,因为它将是 564 像素)并根据是否有图像折叠 2 或 3,并将您的项目的列拉伸到可用空间的一小部分。

我叉了你的笔here

我使用了这个CSS-Tricks article 关于自动调整/自动填充和 Firefox 检查器网格工具。

【讨论】:

    猜你喜欢
    • 2015-10-31
    • 2014-04-08
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    • 2018-10-09
    • 2015-10-06
    • 1970-01-01
    • 2019-11-19
    相关资源
    最近更新 更多