Home > front end >  Firefox doesn't style :empty elements
Firefox doesn't style :empty elements

Time:09-22

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:

enter image description here

For some reason, in Firefox, the contenteditable tds don't get the placeholder:

enter image description here

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.

enter image description here

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>

  • Related