Here is a snippet with a sample code:
table {
border-collapse: collapse;
}
th, td {
border: 1px solid gray;
padding: 3px 6px;
}
[contenteditable]:empty:not(:focus)::before {
content: attr(data-placeholder);
color: gray;
font-size: .9rem;
}
<table>
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
</tr>
</thead>
<tbody>
<tr>
<td contenteditable="true" data-placeholder="Firstname"></td>
<td contenteditable="true" data-placeholder="Lastname"></td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
</tr>
</tbody>
</table>
In Chrome and Safari, it works pretty much as expected:
For some reason, in Firefox, the contenteditable tds don't get the placeholder:
How can I fix this issue?
EDIT: It seems this is issue is more related to :empty than [contenteditable] as this code kinda works:
[contenteditable]:not(:focus)::before {
content: attr(data-placeholder);
color: gray;
font-size: .9rem;
}
But then the placeholder is always shown, hence not being an actual "placeholder" anymore.
CodePudding user response:
Firefox has incompatibility with td:empty not because there is an issue with the css engine but because of the way Firefox handles contenteditable is by adding a br tag into the region.
An alternate way to do this would be to change the html to use inputs that you disable when content is present.
table {
border-collapse: collapse;
}
th,
td {
border: 1px solid gray;
padding: 0;
}
table input {
border: none;
}
[placeholder] {
color: gray;
font-size: .9rem;
}
<table>
<thead>
<tr>
<th>Forename</th>
<th>Surname</th>
</tr>
</thead>
<tbody>
<tr>
<td><input placeholder="Forename"></td>
<td><input placeholder="Surname"></td>
</tr>
<tr>
<td><input placeholder="Forename" value="John" disabled></td>
<td><input placeholder="Forename" value="Doe" disabled></td>
</tr>
</tbody>
</table>
CodePudding user response:
As @DreamTeK mentioned, Firefox seems to add a <br> in empty contenteditable elements.
His answer, using input instead of contenteditable is valid.
In case you have no choice but to use contenteditable, here is a fix in JS to remove this unwanted br:
// VanillaJS
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll('[contenteditable]').forEach((elt) => {
if (elt.children.length === 1 && elt.firstChild.tagName === "BR") {
elt.firstChild.remove();
}
})
});
// jQuery
/*
$(document).ready(() => {
$('[contenteditable]').each((_, elt) => {
if ($(elt).children().length === 1 && $(elt).has('br')) {
$(elt).html('');
}
});
});
*/
table {
border-collapse: collapse;
}
th, td {
border: 1px solid gray;
padding: 3px 6px;
}
[contenteditable]:empty:not(:focus)::before {
content: attr(data-placeholder);
color: gray;
font-size: .9rem;
}
<table>
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
</tr>
</thead>
<tbody>
<tr>
<td contenteditable="true" data-placeholder="Firstname"></td>
<td contenteditable="true" data-placeholder="Lastname"></td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
</tr>
</tbody>
</table>



