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>