CSS网格,其中一列缩小以适合内容,另一列填充剩余空间

时间:2013-11-07 23:17:50

标签: html css layout html-table grid-layout

我需要创建一个水平布局,其中一个块占用所有可用空间,其他块缩小以适合其内容。

例如:

<div class="grid">
    <div class="expand">Long text label</div>
    <div class="shrink">Button</div>
</div>

具有两行(实际网格)的更复杂示例:

<div class="grid">
    <div class="row">
        <div class="shrink">...</div>
        <div class="expand">...</div>
        <div class="shrink">...</div>
        <div class="shrink">...</div>
    </div>
    <div class="row">
        <div class="shrink">...</div>
        <div class="expand">...</div>
        <div class="shrink">...</div>
        <div class="shrink">...</div>
    </div>
</div>

我的要求:

  1. 即使短
  2. ,大块也应填满所有可用空间
  3. 小块应符合其内容
  4. 大块(通常是文本标签)可能是一个比可用空间大的单个字,因此在这种情况下应该被截断
  5. 如果多字
  6. ,大块不应该换行
  7. 小块不应该换行(虽然在多个按钮或图标的情况下,这可以通过为每个组件制作一个块来解决)
  8. 支持多行(即列应对齐)
  9. 我的目标是Android和iOS智能手机。

    我已尝试调整this answer中的代码,但我无法使其适用于多行。此外,源代码必须是乱序的,这是令人困惑的(虽然我的用例没有阻塞)。这是一个jsfiddle:http://jsfiddle.net/k3W8L/

3 个答案:

答案 0 :(得分:16)

我最近在学习在我的应用中使用网格时碰到了这个问题。通过ilyaigpetrov的回答,我得到了一个缩小到适合的列大小可以工作。虽然答案并没有给出太多解释,所以我想我会加上这个:

您需要做的是使用grid-template-column并将要缩小到适合的列的大小设置为auto,并且至少设置一个其他列fr单位。

实施例: 要重新创建侧边栏内容布局,侧边栏可折叠,

-------------------------------
| Sidebar |       Content     |
-------------------------------

您可以将网格创建为:

.grid {
  display: grid;
  ...
  grid-template-columns: auto minmax(0, 1fr); // see note below
  grid-template-areas: "sidebar content";
}
.sidebar {
  grid-area: sidebar;
}
.content {
  grid-area: content;
}

请参阅此处的codepen以获取演示和放大代码:https://codepen.io/khs/pen/vegPBL 您可以单击导航栏以查看自动调整大小。

注意:自写这个答案以来,我学到的一件事是,在大多数情况下,特别是在固定高度/固定宽度的布局中,你应该使用{{1}而不是minmax(0, 1fr)。原因是1fr实际上是1fr的简写。当具有较长内容的固定布局时,这会中断。有关详细信息,请参阅此问题:How come minmax(0, 1fr) works for long elements while 1fr doesn't? 因此,我更新了我的答案以反映这一事实。 minmax(auto, 1fr)可能有点冗长,但它几乎总是你想要的这种布局。

答案 1 :(得分:2)

在尝试创建简洁示例时,我找到了自己问题的答案。

它使用表格布局:

.grid {
    display: table;
    table-layout: auto;
    width: 100%;
}
.row {
    display: table-row;
}
.expand {
    display: table-cell;
    width: 100%;
    max-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.shrink {
    display: table-cell;
    white-space: nowrap;
}

width: 100%中的.expand是块填充所有可用空间的原因,从而满足前两个要求。

请注意width中的.grid只是设置整个网格的宽度,您可以在此使用任何值。

出于某种原因,将max-width: 0放在.expand中可以防止块增长超过可用空间,像100px这样的小值也可以。我偶然发现了这个,我不知道它为什么会起作用。

这是jsfiddle:http://jsfiddle.net/fr253/

This answer帮助我开始。

答案 2 :(得分:0)

我不知道我的代码是否有效,但它完成了工作:使用grid或flex。

.container {
  display: grid;
  grid-template-columns: 1fr auto auto;
}
.one {
  background-color: pink;
}
.two {
  background-color: yellow;
}
.three {
  background-color: lightgreen;
}


/* Now the same but with flex. */
.whole-row {
  grid-column: 1 / -1;
}
.flexy {
  display: flex;
  border: 1px solid red;
}
.flexy > .one {
  flex-grow: 1;
}
.flexy > .two,
.flexy > .three {
  /* flex-grow: 0; <- This value is a default. */
}
<div class="container">

  <div class="one">one</div>
  <div class="two">two</div>
  <div class="three">three</div>

  <div class="one">one</div>
  <div class="two">two</div>
  <div class="three">three</div>

  <div class="whole-row flexy">
    <div class="one">one</div>
    <div class="two">two</div>
    <div class="three">three</div>
  </div>

</div>