指定哪些单元格扩展单元格区域以及哪些单元格不在CSS网格中的内容

Ath*_*ari 11 html css css3 css-grid

我希望网格中有一个单元格,其中包含不重要的信息,这些信息不会使任何其他单元格扩展到超出绝对要求的范围.它的高度不应超过其他细胞的高度,其宽度应为空的未占用区域.

让我们说每个项目我有一个缩略图,一个标题(单个不可绕行的行),信息(零行或多行),描述(可能很长,只有在空白时显示).

我想出了这个:

.list {
  display: flex;
  flex-wrap: wrap;
  font: 12px/14px Verdana;
}
.item {
  display: grid;
  grid-template-areas:
    "thumb thumb thumb thumb"
    "sl    title desc  sr   "
    "sl    info  desc  sr   ";
  grid-template-columns:
    auto auto 1fr auto;
  grid-template-rows:
    auto auto 1fr;
  min-width: calc(var(--min-item-size) + 4px);
  max-width: calc(var(--max-item-size) + 4px);
  border: dotted 2px darkblue;
  margin: 4px 2px auto 2px;
}
.item > * {
  min-width: 0;
  min-height: 0;
  border: dotted 1px dodgerblue;
  margin: 1px;
}
.thumb {
  grid-area: thumb;
  margin: auto;
  height: 100px;
  background: linear-gradient(lightskyblue, deepskyblue);
}
.title {
  grid-area: title;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.info {
  grid-area: info;
  overflow: hidden;
  text-overflow: ellipsis;
}
.desc {
  grid-area: desc;
  position: relative;
  overflow: hidden;
}
.desc-text::after {
  position: absolute; /*clean hack*/
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  content: var(--lorem-ipsum);
}
.desc-text.short::after {
  content: var(--lorem-ipsum-short);
}
:root {
  --lorem-ipsum: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
  --lorem-ipsum-short: "Lorem";
  --min-item-size: 100px;
  --max-item-size: 150px;
}
Run Code Online (Sandbox Code Playgroud)
<div class="list">
  <div class="item">
    <div class="thumb" style="width: 150px">1</div>
    <div class="title">Short title</div>
    <div class="info">Short info</div>
    <div class="desc">
      <div class="desc-text"></div>
    </div>
  </div>
  <div class="item">
    <div class="thumb" style="width: 150px">2</div>
    <div class="title">Very long and detailed title</div>
    <div class="info">Very long and detailed info</div>
    <div class="desc">
      <div class="desc-text"></div>
    </div>
  </div>
  <div class="item">
    <div class="thumb" style="width: 50px">3</div>
    <div class="title">Short title</div>
    <div class="info">Short info</div>
    <div class="desc">
      <div class="desc-text"></div>
    </div>
  </div>
  <div class="item">
    <div class="thumb" style="width: 50px">4</div>
    <div class="title">Very long and detailed title</div>
    <div class="info">Very long and detailed info</div>
    <div class="desc">
      <div class="desc-text"></div>
    </div>
  </div>
  <div class="item" style="grid-template-columns: 22px auto 1fr 22px /*dirty hack*/">
    <div class="thumb" style="width: 150px">5</div>
    <div class="title">Short title</div>
    <div class="info">Short info</div>
    <div class="desc">
      <div class="desc-text short"></div>
    </div>
  </div>
  <div class="item">
    <div class="thumb" style="width: 150px">6</div>
    <div class="title">Very long and detailed title</div>
    <div class="info">Very long and detailed info</div>
    <div class="desc">
      <div class="desc-text short"></div>
    </div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

我必须将描述放入相对定位的单元内的绝对定位的容器中.这使得网格忽略内容并且有点有效,但是有几个问题:

  1. 如果描述很短(参见第5项),我不能像1fr描述中那样使信息块居中,所以将间距列(slsr)设置为除了0不起作用之外的任何东西(以样式属性的形式进行脏攻击)不计算,它只是显示间距单元格的使用).

  2. 它看起来不像纯CSS网格解决方案.我想知道是否有更多"本地"方式来指定细胞生长如何受到内容的影响.


如果您想要"干净利落",可以position: absolute; /*clean hack*/从CSS中删除该行,style="grid-template-columns: 22px auto 1fr 22px /*dirty hack*/"从HTML中删除该属性.一些定位CSS属性已经过时,但它们不再影响定位.如果你愿意,也可以删除它们.

干净的开始:

.list {
  display: flex;
  flex-wrap: wrap;
  font: 12px/14px Verdana;
}
.item {
  display: grid;
  grid-template-areas:
    "thumb thumb thumb thumb"
    "sl    title desc  sr   "
    "sl    info  desc  sr   ";
  grid-template-columns:
    auto auto 1fr auto;
  grid-template-rows:
    auto auto 1fr;
  min-width: calc(var(--min-item-size) + 4px);
  max-width: calc(var(--max-item-size) + 4px);
  border: dotted 2px darkblue;
  margin: 4px 2px auto 2px;
}
.item > * {
  min-width: 0;
  min-height: 0;
  border: dotted 1px dodgerblue;
  margin: 1px;
}
.thumb {
  grid-area: thumb;
  margin: auto;
  height: 100px;
  background: linear-gradient(lightskyblue, deepskyblue);
}
.title {
  grid-area: title;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.info {
  grid-area: info;
  overflow: hidden;
  text-overflow: ellipsis;
}
.desc {
  grid-area: desc;
  overflow: hidden;
}
.desc-text::after {
  content: var(--lorem-ipsum);
}
.desc-text.short::after {
  content: var(--lorem-ipsum-short);
}
:root {
  --lorem-ipsum: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
  --lorem-ipsum-short: "Lorem";
  --min-item-size: 100px;
  --max-item-size: 150px;
}
Run Code Online (Sandbox Code Playgroud)
<div class="list">
  <div class="item">
    <div class="thumb" style="width: 150px">1</div>
    <div class="title">Short title</div>
    <div class="info">Short info</div>
    <div class="desc">
      <div class="desc-text"></div>
    </div>
  </div>
  <div class="item">
    <div class="thumb" style="width: 150px">2</div>
    <div class="title">Very long and detailed title</div>
    <div class="info">Very long and detailed info</div>
    <div class="desc">
      <div class="desc-text"></div>
    </div>
  </div>
  <div class="item">
    <div class="thumb" style="width: 50px">3</div>
    <div class="title">Short title</div>
    <div class="info">Short info</div>
    <div class="desc">
      <div class="desc-text"></div>
    </div>
  </div>
  <div class="item">
    <div class="thumb" style="width: 50px">4</div>
    <div class="title">Very long and detailed title</div>
    <div class="info">Very long and detailed info</div>
    <div class="desc">
      <div class="desc-text"></div>
    </div>
  </div>
  <div class="item">
    <div class="thumb" style="width: 150px">5</div>
    <div class="title">Short title</div>
    <div class="info">Short info</div>
    <div class="desc">
      <div class="desc-text short"></div>
    </div>
  </div>
  <div class="item">
    <div class="thumb" style="width: 150px">6</div>
    <div class="title">Very long and detailed title</div>
    <div class="info">Very long and detailed info</div>
    <div class="desc">
      <div class="desc-text short"></div>
    </div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

val*_*als 4

我认为我已经有了一个非常好的解决方案。

唯一的缺点是我需要设置一个max-widthon.title.info

您的第一个问题是分配水平空间。您希望第二列为title提供尽可能多的空间。但不能超过所包含元素的自然宽度。因此,我们需要一些与内容相关的东西,以及它的最大宽度max-content

然后,我们希望第三列(带有desc)采用任何左侧宽度(如果有),并且不能超过它可以填充的宽度。这可以通过min-max(0, max-content)来实现

最后,我们希望将任何剩余空间放入第一列和第四列,即1fr

这种安排之所以有效,是因为自由空间分布在 2 轮中,一轮用于 minmax 函数,第二轮用于fr元素。

此设置的问题是标题最大内容可能会溢出容器。我们无法在网格本身上解决(我认为)这个问题,我们需要在元素本身上设置最大宽度。

起初,您可能会认为这里的 minmax 函数会有所帮助。不,不能。你可以在这里看到解释

另一个问题是处理desc的高度。由于它跨越两行,但两行都必须对内容敏感,所以我们在这里运气不佳。

幸运的是,这里已经有了一个嵌套结构。使容器溢出:隐藏并限制内部元素高度就可以了。内部元素没有足够的高度容纳其内容,但由于溢出:无而显示它们。容器的高度适合网格,并剪掉溢出的内容

:root {
  --lorem-ipsum: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
  --lorem-ipsum-short: "Lorem";
  --min-item-size: 100px;
  --max-item-size: 150px;
  --max-item-desc-height: 32px; /* added */
}

.list {
  display: flex;
  flex-wrap: wrap;
  font: 12px/14px Verdana;
}
.item {
  display: grid;
  grid-template-areas:
    "thumb thumb thumb thumb"
    "sl    title desc  sr   "
    "sl    info  desc  sr   ";
  grid-template-columns: 1fr max-content minmax(0px, max-content) 1fr; /* changed */
  grid-template-rows: auto auto 1fr;
  min-width: calc(var(--min-item-size) + 4px);
  max-width: calc(var(--max-item-size) + 4px);
  border: dotted 2px darkblue;
  margin: 4px 2px auto 2px;
}
.item > * {
  min-width: 0;
  min-height: 0;
  border: dotted 1px dodgerblue;
  margin: 1px;
}
.thumb {
  grid-area: thumb;
  margin: auto;
  height: 100px;
  background: linear-gradient(lightskyblue, deepskyblue);
}
.title {
  grid-area: title;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  max-width: var(--max-item-size); /* added */
}
.info {
  grid-area: info;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: var(--max-item-size); /* added */
}
.desc {
  grid-area: desc;
  overflow: hidden;
  max-height: var(--max-item-desc-height); /* added */
}
.desc-text::after {
  content: var(--lorem-ipsum);
}
.desc-text.short::after {
  content: var(--lorem-ipsum-short);
}
Run Code Online (Sandbox Code Playgroud)
<div class="list">
  <div class="item">
    <div class="thumb" style="width: 150px">1</div>
    <div class="title">Short title</div>
    <div class="info">Short info</div>
    <div class="desc">
      <div class="desc-text"></div>
    </div>
  </div>
  <div class="item">
    <div class="thumb" style="width: 150px">2</div>
    <div class="title">Very long and detailed title</div>
    <div class="info">Very long and detailed info</div>
    <div class="desc">
      <div class="desc-text"></div>
    </div>
  </div>
  <div class="item">
    <div class="thumb" style="width: 50px">3</div>
    <div class="title">Short title</div>
    <div class="info">Short info</div>
    <div class="desc">
      <div class="desc-text"></div>
    </div>
  </div>
  <div class="item">
    <div class="thumb" style="width: 50px">4</div>
    <div class="title">Very long and detailed title</div>
    <div class="info">Very long and detailed info</div>
    <div class="desc">
      <div class="desc-text"></div>
    </div>
  </div>
  <div class="item">
    <div class="thumb" style="width: 150px">5</div>
    <div class="title">Short title</div>
    <div class="info">Short info</div>
    <div class="desc">
      <div class="desc-text short"></div>
    </div>
  </div>
  <div class="item">
    <div class="thumb" style="width: 150px">6</div>
    <div class="title">Very long and detailed title</div>
    <div class="info">Very long and detailed info</div>
    <div class="desc">
      <div class="desc-text short"></div>
    </div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)