【问题标题】:Force element not to stretch table cell horizontally强制元素不要水平拉伸表格单元格
【发布时间】:2014-11-18 00:37:38
【问题描述】:

我有一个使用display: table-rowtable-cell 布局的表单,其中每一行包含两个单元格:一个标签和一个输入。两个单元格都有未指定的宽度,因为我希望它们与其中的内容一起拉伸。

但是,在特定单元格中,我需要添加一个包含额外信息的元素。无论其中的信息有多长,我都不希望它拉伸右侧的单元格。我只想让文本换行 好像 块设置了宽度,但没有设置宽度(因为我不知道它必须是什么)

.row {
    display: table-row;
    outline: 1px solid black;
}
.cell {
    display: table-cell;
    padding: 5px;
}
.info {
    display: block;
}
<div class="row">
    <div class="cell">Label</div>
    <div class="cell input">
        <input type="text" />
    </div>
</div>
<div class="row">
    <div class="cell">Another label</div>
    <div class="cell input">
        <input type="text" />
        <span class="info">This text should not make the cell larger</span>
    </div>
</div>

我知道相对较新的width: min-content 应该能够处理这个问题,它在inline blocks 上可以做到这一点,但这违背了使用table-cell 的目的,这是我在previous questionx 中发现的。 IE也不支持,我确实需要。

我尝试将.info 设置为inlineinline-block 在新行上(都使用&lt;br&gt; 和带有display: block 的伪元素),所有这些都与word-break: break-word 结合使用,但徒劳无功。

奇怪的是,当我将max-width: 0 应用到.input div 页面呈现(使用开发人员工具)之后,单元格将缩小以适应输入,它会产生完全预期的效果.但是,预先设置这个值实际上会强制一个 0 宽度的单元格,并且所有的内容都会溢出。
我真的不想在使用 javascript 渲染后不得不设置这个值。有没有 CSS 方法可以做到这一点?

【问题讨论】:

  • 为什么不用桌子?
  • @TylerH - 为什么会有帮助?
  • @LcSalazar 如果他下定决心要让它表现得像一个表格,那么实际上使用 HTML 表格将允许内置控件和表格行为,在使用 CSS 时你必须伪造。
  • 这个:css table-cell equal width 看起来很有希望。
  • @TylerH - 首先,这里的问题不是让它表现得像一张桌子,它已经做到了。问题出在其他问题上……其次,不建议将 HTML 表格用于布局。

标签: html css tablelayout


【解决方案1】:

由于对实际确实需要固定宽度的特定不相关列的宽度进行了一些不相关的修改,我偶然发现了这个修复:

.input { 
    width: 1px;
}

我完全忽略了这样一个事实,即在具有display: table-cell 的元素上,width 属性的作用就像在其他元素上的 min-width 一样。因此,通过设置 1 像素宽度,单元格始终会缩小到所需的最小宽度。输入不能缩小,因此这是单元格占用的最小尺寸,.info 元素实际上被包装以适合单元格内部。这在一个简单的 CSS 规则中完全解决了我的问题。

如果我想拥有一个确实现在推动单元格宽度的元素,我可以简单地在它上面设置一个宽度,或者使用white-space: nowrap 来不包裹它(所以它只是有推动单元格边界)。

.row {
    display: table-row;
    outline: 1px solid black;
}
.cell {
    display: table-cell;
    padding: 5px;
}
.input { 
    width: 1px;
}
.info {
    display: block;
}
<div class="row">
    <div class="cell">Label</div>
    <div class="cell input">
        <input type="text" />
    </div>
</div>
<div class="row">
    <div class="cell">Another label</div>
    <div class="cell input">
        <input type="text" />
        <span class="info">This text should not make the cell larger</span>
    </div>
</div>

【讨论】:

    【解决方案2】:

    简化@AndrewMorton's answer

    <span class="info">
        <span class="info-inner">
            This text should not make the cell larger
        </span>
    </span>
    
    .info {
        display: table;
        width: 100%;
    }
    .info-inner {
        display: table-caption;
    }
    

    .row {
        display: table-row;
        outline: 1px solid black;
    }
    .cell {
        display: table-cell;
        padding: 5px;
    }
    .info {
        display: table;
        width: 100%;
    }
    .info-inner {
        display: table-caption;
    }
    <div class="row">
        <div class="cell">Label</div>
        <div class="cell input">
            <input type="text" />
        </div>
    </div>
    <div class="row">
        <div class="cell">Another label</div>
        <div class="cell input">
            <input type="text" />
            <span class="info">
                <span class="info-inner">
                    This text should not make the cell larger
                </span>
            </span>
        </div>
    </div>

    【讨论】:

    • 哇,太好了!也适用于所有相关的浏览器。
    • 对不起 Oriol,虽然这是一个巧妙的修复,我已经能够在另一种情况下使用它(其中包装器是不应拉伸的 inline-block),特别是如果包装器是table-cell,我找到了一个更简单的答案。因为这也适用于实际的tds,所以我认为我的解决方案实际上更适合这个问题。不是想抢你的风头,但我不会接受这个答案。
    • @StephanMuller 当然,我也认为你的回答更好。
    【解决方案3】:

    table-cell - some kind of colspan? 获得灵感,在内部使用另一个 CSS 表格布局,并假设您想要类似的结果

    这个想法是为您希望与上面的项目一样宽的部分使用表格标题。

    .row {
      display: table-row;
      outline: 1px solid black;
    }
    .cell {
      display: table-cell;
      padding: 5px;
    }
    .info {
      display: table-caption;
      caption-side: bottom;
      width: 100%;
    }
    <div class="aTable">
      <div class="row">
        <div class="cell">
          <label for="inp1">Label</label>
        </div>
        <div class="cell input">
          <input type="text"  id="inp1" />
        </div>
      </div>
      <div class="row">
        <div class="cell">
          <label for="inp2">Another label</label>
        </div>
        <div class="cell">
          <div class="aTable">
            <div class="row">
              <div class="input">
                <input type="text" id="inp2" />
                <label>
                  <input type="radio" id="r1" name="radioChoice" value="radiogaga" />
                  Radio GAGA
                </label>
                <label>
                  <input type="radio" id="r2" name="radioChoice" value="radiokaos" checked />
                  Radio KAOS
                </label>
              </div>
              <div class="info">
                This text should not make the cell any larger - it works in my testing with IE11 and FF32.0.2.
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    【讨论】:

    • @Oriol 感谢您的代码-sn-pting - 我第一次尝试时无法让它工作。
    • 这是一个有趣的解决方案!它似乎不适用于 Chrome,但我肯定会深入研究它,看看我是否可以让它做 FF 所做的事情。我以前从未听说过table-captioncaption-side,所以+1 仅此而已。修改后继续
    • @AndrewMorton +1 好主意。但是,也许还不够清楚到底是什么技巧,所以我发布了另一个答案来总结您的代码。
    【解决方案4】:

    好的,这是一张我相信可以满足您要求的表格。

    我想不出事先选择下面p 元素的任意宽度会成为问题的情况;如果您想要一个小于输入框(最小宽度)的元素,那么没问题,它也不会改变大小。

    但是,如果您想要添加比输入框更大的描述元素(并且会增加单元格的宽度),或者您想要添加内容,那么单元格将会增加无论如何。

    我认为,如果不知道您将拥有的所有类型的元素,这将很难真正说出。在 cmets 中,您也提到了单选按钮。我会为每种类型的输入设备(框、单选按钮、真/假选择、滑块、下拉框)添加一个不同的类,并为每一个设置一个唯一的固定宽度。

    然而,到那时,它实际上可能最终在 JavaScript 中变得更容易(更少的 LOC)。我无法推测那里,因为我真的不知道 JavaScript。

    JSFiddle

    <table rules="rows">
        <tr>
            <td>This is a super long label to show that the table can grow.</td>
            <td class="right-col"><input/></td>
        </tr>
        <tr>
            <td>Another Label</td>
            <td class="right-col"><input/>Delete this text to see that non "p" description text will still make the table shrink or grow.<p>This is a fixed-width description with the same length as the input element above.</p></td>
        </tr>
        <tr>
            <td>A Third Label</td>
            <td class="right-col"><input type="radio"/>This text gets to expand the cell.<p>Another test example.</p></td>
        </tr>
    </table>
    

    CSS:

    table {
        border: 1px solid black;
    }
    
    .right-col p {
        margin: 0;
        width: 150px;
        color: red;
    }
    
    input[type=radio] ~ p {
        margin: 0;
        width: 25px;
        color: blue;
        word-wrap: break-word;
    }
    

    【讨论】:

    • .right-col p { width: 150px; } 与我的代码 sn-p 中的 .input { width: 150px; } 完全相同。关键是我无法对宽度进行硬编码,因为我并不总是确定输入的宽度。
    • @StephanMuller 为什么不让它们全部为 150px 或 200px 之类的,然后在必要时让文本滚动?如果它有一个您想要实现的表单的更完整示例,这个问题会更好。
    • 这个例子是解释我的问题所需的最低限度。我可以包含我的整个项目的代码,但它不会让你更聪明。我不知道右栏中的元素有多大,但我是开发人员,必须构建设计师给我的东西,而他给了我这个。我正在寻找最灵活、最易于维护的设计实现方式。
    • @StephanMuller "None the wiser" 好吧,我不同意,因为需要找到一个适用于输入框的解决方案并不一定包括适用于单选按钮的解决方案,但它没有实际意义,因为有一个接受的答案。
    猜你喜欢
    • 1970-01-01
    • 2020-11-10
    • 1970-01-01
    • 2022-01-23
    • 2011-08-25
    • 2015-07-15
    • 1970-01-01
    • 1970-01-01
    • 2012-01-29
    相关资源
    最近更新 更多