Force element not to stretch table cell horizontally

喜欢而已 提交于 2019-12-13 05:17:21

问题


I have a form laid out using display: table-row and table-cell, where each row contains two cells: a label and an input. Both cells have an unspecified width, because I want them to stretch along with the contents inside them.

However, in a particular cell I need to add an element with extra information. No matter how long the information in it is, I don't want it to stretch the right-hand cell. I just want the text to wrap as if the block had a width set, but without setting one (because I do not know what it will have to be)

.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>

I know that the relatively new width: min-content should be able to handle this, which it does on inline blocks but that defies the purpose of using table-cell, which I found out during my previous questionx. Also it's not supported by IE, which I do need.

I've tried setting the .info to inline and inline-block on a new line (both using <br> and a pseudo-element with display: block), all in combination with word-break: break-word but to no avail.

Strangely, when I apply max-width: 0 to the .input div after the page rendered (using the developer tools) the cell will shrink to fit the input, and it produces exactly the desired effect. However, setting this value beforehand will actually force a 0 width cell and all the contents will overflow.
I really don't want to resort to having to set this value after rendering using javascript. Is there a CSS way to do this?


回答1:


With inspiration from table-cell - some kind of colspan?, using another CSS table layout inside, and assuming you want a result like

The idea being to use a table-caption for the part you want to be only as wide as the items above it.

.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>



回答2:


Simplifying @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>



回答3:


As a result of some unrelated tinkering to the width of a specific unrelated column that actually did need a fixed width I stumbled upon this fix:

.input { 
    width: 1px;
}

I completely overlooked the fact that on elements with a display: table-cell, the width property acts like a min-width would on other elements. So by setting a 1 pixel width, the cell always shrinks to the minimum width it needs. Inputs can't be shrunk so that's the smallest size the cell takes, and the .info element is actually wrapped to fit inside the cell. This completely solved my problem in one simple CSS rule.

If I want to have an element that does push the cell width now, I can simply set a width on it, or use white-space: nowrap to not have it wrapped (so then it simply has to push the cell boundary).

.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>



回答4:


Okay, here is a table that I believe does what you are asking.

I cannot think of a situation where choosing an arbitrary width of the below p element beforehand will be a problem; if you want an element that is smaller than the input box (the minimum width) then it's no problem and it won't change the size anyway.

However, if you want to add a description element that is bigger than the input box (and would grow the cell's width), or you want to add content, then the cell is going to grow anyway.

It will be difficult to really tell, I think, without knowing all the kinds of elements you will have. In the comments you mentioned radio buttons as well. I would add a different class for each type of input device (box, radio button, True/False choice, slider, dropdown box) and set a unique fixed width for each one of those.

At that point, however, it may in fact end up easier (fewer LOC) to do in JavaScript. I can't speculate there, as I don't really know 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;
}


来源:https://stackoverflow.com/questions/26001304/force-element-not-to-stretch-table-cell-horizontally

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!