How can I emulate “” with CSS?

2019-04-05 08:43发布

问题:

I'm writing a web application using ExtJS. I'm putting a table inside a table, and for various reasons it's impossible to refactor it all into one big table with rowspan/colspan, etc.

The "outside" table has borders around its cells. I'd like my "inside" table to have borders between its cells, so that I wind up with the effect of "splitting" the existing ("outside") cell.

If it makes things clearer, this is what I'm shooting for, as (poor) ascii art:

-----------------
|               |
|     |   |     |
|  -----------  |
|     |   |     |
|  -----------  |
|     |   |     |
|               |
-----------------

(The "inner" table looks like a tic-tac-toe grid; the "outer" table's cell has an unbroken border)

I looked around, and found a <table> attribute called RULES, which sounds like it does just this. However, it seems to be poorly supported, and anyway I'm not supposed to put style in markup (right?). The documentation I've found says "use CSS instead", but I can't seem to find a simple way of saying "put a border between cells, but not if the edge of the cell touches the outside of the table" in CSS. Help?

回答1:

This http://codepen.io/morewry/pen/GnBFu is about as close as I can get. I suspect there will be some support issues and the alignment of the cells is off by the amount of the border-spacing.

table{
    table-layout:fixed;
    border-collapse:separate;
    border-spacing:0.25em;
    border:1px solid red;
}
    tr{
        display:block;
        border-bottom:1px dashed blue;
    }
    tr:last-child{ border:0; }
        td{
            padding-right:0.25em;
            vertical-align:top;
            border:1px dotted orange;
            border-width:0 1px;
        }
        td:first-child,
        td + td{ border-left:0; }
        td:last-child{ padding-right:0; border-right:0; }

Edit

Upon re-reading I realized you weren't looking for separated borders in a single table, but only to suppress the borders except between cells on a nested table. That's much simpler http://codepen.io/morewry/pen/yxvGg:

table{
    table-layout:fixed;
    border-collapse:collapse;
    border-spacing:0;
    border-style:hidden;
}
    td{
        padding:0.25em;
        border:1px solid black;
    }

Border conflict resolution states that the border-style:hidden takes precedence, so the only ones that appear in the collapsed model are between the cells.

The only issue here is that IE doesn't support hidden, so for IE you'd need workarounds. The pseudo-classes ought to work for IE8. I don't think IE7 supported :last-child, so it would need some extra help, and IE6 would need a workaround for both :first-child and :last-child.

For IE8 and IE7, the following will simulate border:hidden

table{ border:2px solid transparent; }

You'd get 2 extra pixels of transparent space in those browsers, but it's more efficient. IE6, as I recall, doesn't properly support transparent borders, it would still have issues. See http://codepen.io/morewry/pen/bIvJa.



回答2:

You could lift Mozilla's implementation of the rules attribute, which is entirely in CSS:

http://hg.mozilla.org/mozilla-central/file/3fd770ef6a65/layout/style/html.css#l289 and http://hg.mozilla.org/mozilla-central/file/3fd770ef6a65/layout/style/html.css#l337 are the styles, going on through line 410.



回答3:

Simple Example: http://jsfiddle.net/xixionia/v3eVq/

Simple Table (albiet without tbody):

<table>
    <tr>
        <td>00</td>
        <td>01</td>
        <td>02</td>
    </tr>
    <tr>
        <td>10</td>
        <td>11</td>
        <td>12</td>
    </tr>
    <tr>
        <td>20</td>
        <td>21</td>
        <td>22</td>
    </tr>
</table>

Simple CSS (albiet not completely compatible with all browsers):

/* outline */
table
{
    border: 2px solid red;
}

/* rows */
tr
{
    border-top: 2px solid black;
    border-bottom: 2px solid black;
}

/* columns */
td
{
    padding: 10px;
    border-left: 2px solid black;
    border-right: 2px solid black;
}

/* resets */
tr:first-child
{
    border-top: none;
}

tr:last-child
{
    border-bottom: none;
}

td:first-child
{
    border-left: none;
}

td:last-child
{
    border-right: none;
}

Psuedo-selector reference on W3 Schools: http://www.w3schools.com/css/css_pseudo_classes.asp

Instead of using psuedo-selectors:

You can set a class for each first-child and last-child, and use that class as your selector.



回答4:

The HTML5 spec has CSS rules in it’s section “Rendering“. Just pick the rule value you're looking for and fetch the corresponding CSS. Let me copy and paste the rules for <table rules=...>:

Note: the "i" in the attribute selector is CSS4 and ignores case. I.e. rules=ROWS is as good as rules=rows.

table {
  box-sizing: border-box;
  border-spacing: 2px;
  border-collapse: separate;
  text-indent: initial;
}

table, td, th { border-color: gray; }
thead, tbody, tfoot, tr { border-color: inherit; }
table[rules=none i], table[rules=groups i], table[rules=rows i],
 ... and many more selectors in this fashion ...
table[rules=all i] > tfoot > tr > td, table[rules=all i] > tfoot > tr > th {
  border-color: black;
}

table[rules=none i], table[rules=groups i], table[rules=rows i],
table[rules=cols i], table[rules=all i] {
  border-style: hidden;
  border-collapse: collapse;
}

table[rules=none i] > tr > td, table[rules=none i] > tr > th,
table[rules=groups i] > tr > td, table[rules=groups i] > tr > th,
table[rules=rows i] > tr > td, table[rules=rows i] > tr > th 
   ... more selectors for none/groups/rows ...
{
  border-width: 1px;
  border-style: none;
}
table[rules=cols i] > tr > td, table[rules=cols i] > tr > th,
table[rules=cols i] > thead > tr > td, table[rules=cols i] > thead > tr > th,
table[rules=cols i] > tbody > tr > td, table[rules=cols i] > tbody > tr > th,
table[rules=cols i] > tfoot > tr > td, table[rules=cols i] > tfoot > tr > th {
  border-width: 1px;
  border-style: none solid;
}
table[rules=all i] > tr > td, table[rules=all i] > tr > th,
table[rules=all i] > thead > tr > td, table[rules=all i] > thead > tr > th,
table[rules=all i] > tbody > tr > td, table[rules=all i] > tbody > tr > th,
table[rules=all i] > tfoot > tr > td, table[rules=all i] > tfoot > tr > th {
  border-width: 1px;
  border-style: solid;
}

table[rules=groups i] > colgroup {
  border-left-width: 1px;
  border-left-style: solid;
  border-right-width: 1px;
  border-right-style: solid;
}
table[rules=groups i] > thead,
table[rules=groups i] > tbody,
table[rules=groups i] > tfoot {
  border-top-width: 1px;
  border-top-style: solid;
  border-bottom-width: 1px;
  border-bottom-style: solid;
}

table[rules=rows i] > tr, table[rules=rows i] > thead > tr,
table[rules=rows i] > tbody > tr, table[rules=rows i] > tfoot > tr {
  border-top-width: 1px;
  border-top-style: solid;
  border-bottom-width: 1px;
  border-bottom-style: solid;
}