开发者

HTML Table, first and last column fixed width and columns between dynamic, but equal width

开发者 https://www.devze.com 2023-03-23 23:47 出处:网络
Is it possible to have a table with width 100% (so the table fits the screen size), where the first and the last column have a fixed width, and the columns between take the rest, both 50%.

Is it possible to have a table with width 100% (so the table fits the screen size), where the first and the last column have a fixed width, and the columns between take the rest, both 50%.

Like:

+--------------------+--------------------------------------+--------------------------------------+------------+
| width:300px;       | with dynamic, equals next column     | width dynamic, equals prevous column | width:50px;|
+--------------------+--------------------------------------+--------------------------------------+------------+
+--------------------+--------------------------------------+--------------------------------------+------------+
+--------------------+--------------------------------------+--------------------------------------+------------+
+--------------------+--------------------------------------+--------开发者_StackOverflow------------------------------+------------+


Try this:

As you can see the two centre column remain equal sized, due to the table-layout:fixed, even when the content is of different length. Try adding more and less content to the two centre columns.

JSFiddle: http://jsfiddle.net/RtXSh/

CSS

table {
    width:100%;
    border-collapse:collapse;
    table-layout:fixed; 
}

td {
    border: 1px solid #333;
}

HTML

  <table>
    <tr>
      <td style="width:300px;">
        test
      </td>
      <td>
        test test tes test test
      </td>
      <td>
        test
      </td>
      <td style="width:50px;">
        test
      </td>
    </tr>
  </table>


Try using the pseudo element first-child and last-child

If I'm not mistaken the other columns will align equally by themselves. You might need to use the !important statement behind the first-child and last-child widths.

table{ table-layout: fixed; width: 100%; }
td { border: 1px solid black; }
td:first-child{ width: 100px; }
td:last-child{ width: 100px; }
<table>
    <tr>
      <td>100px</td>
      <td>some text</td>
      <td>some text</td>
      <td>100px</td>
    </tr>
</table>

However, as nurettin pointed out, if you use a thead and tbody section you have to style the header. Styling the td:first-child and td:last-child will not work.

table{ table-layout: fixed; width: 100%; }
td { border: 1px solid black; }
th:first-child{ width: 100px; }
th:last-child{ width: 100px; }
<table>
  <thead>
    <tr>
      <th>Column 1</th>
      <th>Column 2</th>
      <th>Column 3</th>
      <th>Column 4</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>100px</td>
      <td>some text</td>
      <td>some text</td>
      <td>100px</td>
    </tr>
  </tbody>
</table>


In my opinion, the simple, nice and easy way is that don't use the px and % together. If you are using table width 100%, then define width of first and last column in % as well. If you are interested in that, here is how you can do:

CSS:

.mytable {
    width:100%;
    border: 1px solid green;
}

.left{
    width:30%;
    border-right:1px dashed blue;
}

.mid1{
   width:30%;
   border-right:1px dashed blue;

}

.mid2{
  width:30%;
   border-right:1px dashed blue;

}

.right{
    width: 10%;
    border-left:1px dashed blue;
}

HTML:

<table class="mytable">
    <tr>
        <td class="left">Left Column, 30%</td>
        <td class="mid1">Mid 1, 30% </td>
        <td class="mid2">Mid 2, 30% </td>
        <td class="right">Right, 10%</td>
    </tr>
</table>


This can be handled by adding the style table-layout:fixed to the table element, and simply not specifying any width value for the columns you wish to evenly divide the width remaining after the fixed columns have been accounted for.

Further, using combinations of <colgroup> can provide robust variable-width scenarios.

I've created an example at JSFiddle: https://jsfiddle.net/3bgsfnuL/1/

<div style="position:relative; height:500px; width:100%;">
<table style="height:100%; width:100%; table-layout:fixed; text-align:center; border-collapse:collapse;">
  <colgroup colspan="1" style="width:200px"></colgroup>
  <colgroup colspan="3">
    <col/>
    <col style="width:30px"/>
    <col/>
  </colgroup>
  <colgroup colspan="1" style="width:200px"></colgroup>
  <tbody>
    <tr>
      <td style="background-color:silver;">left fixed</td>
      <td style="border-right:1px solid black;">col 1</td>
      <td style="background-color:red; color:white; border:1px solid black;">col 2</td>
      <td style="border-left:1px solid black;">col 3</td>
      <td style="background-color:silver;">right fixed</td>
    </tr>
  </tbody>
</table>
</div>


Nobody mentioned this one here <th> trick:

table{ table-layout: fixed; width: 100%; }
th:first-child{ width: 300px; }

<table>
  <thead>
    <tr>
      <th>yourfirst300pxcolumn</th>
      <th>fixedwidth</th>
      <th>fixedwidth also</th>
    </tr>
  </thead>
  <tbody>
    <tr><td>300</td><td>something</td><td>something else</td></tr>
  </tbody>
</table>


Note that in HTML5/CSS3, you can use grid layout to have more control over your tables. It's not that useful for this specific example, with pixel widths, where you can use table-layout:fixed as in Bazzz's answer, but it is useful if you want to use something like min-content.

The following works out of the box on Chrome and Firefox, but not in Safari:

table {
    width: 100%;
    display: grid;
    grid-template-columns: 300px 1fr 1fr 50px;

    /* Or, more usefully: */
    /* grid-template-columns: min-content 1fr 1fr min-content; */
}

td {
    display: block;
}

/* ignore <tr> when laying out the grid; just lay out the cells */
tr {
    display: contents;
}

/* browsers can inject <tbody> into the DOM even if it's not in the HTML */
tbody {
    display: contents;
}

HTML Table, first and last column fixed width and columns between dynamic, but equal width

(Note though that the table border-collapse property doesn't work in this layout, so you may have to fiddle with CSS pseudo-classes like :last-child in order to get your borders to behave the way you want.)

In Safari this doesn't work -- the rows don't break properly. (Although it does work if you use nested <div> elements instead of a <table> and apply similar styles.) However, a simpler layout with just one dynamic 1fr column does work in Safari:

table {
  display: grid;
  grid-template-columns: 300px 1fr 50px;
}

tbody {
  display: contents;
}

tr {
  display: contents;
}

td {
  border: 1px solid #c0c0c0;
}

HTML Table, first and last column fixed width and columns between dynamic, but equal width


What about using jQuery for this and calling javascript function once your table is created or some other event (like click) happens?

See here (I created jsfiddle playground for this)

What it does is that it checks the width of fixed elements (width of the whole table, first and last cell). Then it calculates and assigns the width for the rest of the cells which should have the remaining width divided between them (based on how many there are and how much space is left). Of course this is just quick example of possible solution. It needs polishing (checking null objects, if remaining width is greater than 0, ...)

0

精彩评论

暂无评论...
验证码 换一张
取 消