Reputation: 1346
I'm trying to create a spacer/separator between rows in a table
(please note it's not between EVERY row, but only between some specific rows). The approach I'm taking right now is to create an empty tr
(to add some space), and add a pseudo element tr:after
to it (to draw a grey horizontal line sits in the center of that empty space). Everything works perfectly fine until I try it on Safari.
In Chrome, Firefox and Edge (expected): https://ibb.co/wNSykPQ
In Safari: https://ibb.co/0tsLkym
This is my markup:
<table class="context-menu">
<tr>
<td>Cut</td>
<td>Ctrl+X</td>
</tr>
<tr class="spacer"></tr>
<tr class="disabled">
<td>Paste</td>
<td>Ctrl+Z</td>
</tr>
<tr>
<td>Copy</td>
<td>Ctrl+C</td>
</tr>
</table>
This is the styles for tr.spacer
:
table.context-menu tr.spacer {
position: relative;
height: 8px;
}
table.context-menu tr.spacer:after {
content: "";
position: absolute;
top: 0;
bottom: 0;
margin: auto 0;
height: 1px;
width: 100%;
background-color: var(--item-disabled);
}
Full demo here: https://jsfiddle.net/tfkox4yc/10/
I have explicitly set tr.spacer
position to relative
, so the pseudo element tr.spacer:after
should respect tr.spacer
position. I add top 0
, bottom 0
and margin-top
margin-bottom
auto
to make it vertically center in tr.spacer
. However in Safari, it doesn't seem to be the case, it seems like the pseudo element is relative to the table, not its parent. Is there anything I'm missing here?
Upvotes: 1
Views: 599
Reputation: 67778
Your tr.spacer
is empty, i.e. it does not contain any (td
) cells, which is invalid HTML. Every row has to have the same amount of cells (or there have to be according colspan
attributes)
so your HTML should look like this:
<table class="context-menu">
<tr>
<td>Cut</td>
<td>Ctrl+X</td>
</tr>
<tr class="spacer"><td></td><td></td></tr>
<tr>
<td>Copy</td>
<td>Ctrl+C</td>
</tr>
<tr class="disabled">
<td>Paste</td>
<td>Ctrl+V</td>
</tr>
</table>
I tried it with your jsfiddle in Safari, it works as desired.
Upvotes: 1
Reputation: 622
If I understand you correctly, you want to create a context menu and place a spacer only between specific rows. I have had mixed results trying to style table rows, try adding [td] elements to the spacer row and style those instead. But also, instead of using a [table], perhaps consider using a [menu].
Table:
table.context-menu {
--item-active: #316ac4;
--item-disabled: #ABA89A;
--table-padding: 2px;
list-style: none;
position: absolute;
left: 0;
padding: 2px;
margin: 0;
color: #000;
background-color: #FFF;
border: 1px var(--item-disabled) solid;
border-collapse: separate;
border-spacing: 0px;
min-width: 10em;
}
table.context-menu tr.spacer {
position: relative;
height: 8px;
}
table.context-menu tr.spacer td:after {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
margin: auto 0;
height: 1px;
width: 100%;
background-color: var(--item-disabled);
}
table.context-menu > tbody > tr > td {
white-space: nowrap;
padding: 4px 1em;
}
table.context-menu > tbody > tr.disabled > td {
color: var(--item-disabled);
}
table.context-menu > tbody > tr:not(.disabled):hover > td {
cursor: default;
background-color: var(--item-active);
color: #fff;
}
table.context-menu > tbody > tr > td:first-of-type {
width: 100%;
}
table.context-menu > tbody > tr > td.children {
position: absolute;
padding: 0;
}
table.context-menu > tbody > tr:not(.disabled) > td.children {
position: relative;
}
table.context-menu > tbody > tr:not(.disabled) > td.children:after {
content: "";
position: absolute;
right: 5px;
top: 0;
bottom: 0;
margin: auto 0;
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-left: 5px solid #000;
}
table.context-menu > tbody > tr:not(.disabled):hover > td.children:after {
border-left-color: #FFF;
}
table.context-menu > tbody > tr > td.children > table.context-menu {
display: none;
}
table.context-menu > tbody > tr:not(.disabled):hover > td.children > table.context-menu {
top: 0;
display: table;
}
<table class="context-menu">
<tr>
<td>Cut</td>
<td>Ctrl+X</td>
</tr>
<tr class="spacer">
<td></td>
<td></td>
</tr>
<tr>
<td>Copy</td>
<td>Ctrl+C</td>
</tr>
<tr class="disabled">
<td>Paste</td>
<td>Ctrl+V</td>
</tr>
</table>
Menu:
menu.context-menu {
--item-active: #316ac4;
--item-disabled: #ABA89A;
--table-padding: 2px;
list-style: none;
box-sizing: border-box;
padding: 2px;
position: absolute;
left: 0;
width: 100%;
border: 1px solid var(--item-disabled);
}
.grid {
display: grid;
border-width: 1px 0 0 0;
grid-template-columns: repeat(2, 1fr);
justify-content: space-beteen;
}
.grid > span {
padding: 5px;
white-space: nowrap;
}
.grid > span:last-child {
text-align: right;
}
.grid:not(.disabled):hover {
background-color: var(--item-active);
color: #fff;
}
.grid.disabled {
color: var(--item-disabled);
}
.spacer {
height: 1px;
border: solid var(--item-disabled);
border-width: 0 0 1px 0;
margin: 2px;
}
<menu class="context-menu">
<li class="grid">
<span>Cut</span>
<span>Ctrl+X</span>
</li>
<li class="spacer"></li>
<li class="grid">
<span>Copy</span>
<span>Ctrl+C</span>
</li>
<li class="grid disabled">
<span>Paste</span>
<span>Ctrl+V</span>
</li>
</menu>
Upvotes: 2