Mayank

Resetting default popover styles

The HTML standard dictates that user-agents apply the following default styles to elements that have the popover attribute.

Code snippet
[popover]:not(:popover-open):not(dialog[open]) {
  display: none;
}
[popover] {
  position: fixed;
  inset: 0;
  width: fit-content;
  height: fit-content;
  margin: auto;
  border: solid;
  padding: 0.25em;
  overflow: auto;
  color: CanvasText;
  background-color: Canvas;
}

I’m not going to sugarcoat it, these styles are garbage. I don’t want them, and I’d be very surprised if anybody else does.

I find that adding the popover attribute to an existing element will often break its intended visuals. And if that element already has a display set on it (pretty common for layout purposes), then the popover will be unclosable. I’m shocked that this is the experience we get from using a brand new platform API!

To get around this nonsense, I’ve added the following styles to my CSS reset:

Code snippet
[popover] {
  border: none;
  background: none;
  inset: unset;
  color: inherit;
}

[popover]:not(:popover-open) {
  display: none !important;
}

This removes the undesirable visuals and re-inforces that the popover stays hidden when it’s not supposed to be open.

And here’s some preceding parts of my reset that are also relevant for popovers:

Code snippet
*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

dialog:not([open], [popover]) {
  display: none !important;
}

The dialog thing is particularly interesting because it allows me to use a <dialog popover> that can be opened using popovertarget or dialog.showPopover() (instead of dialog.show()).

I’m also toying with unsetting the overflow: auto from popover. I can understand why it exists in the UA styles (it’s because of position: fixed), but I’ve already run into multiple scenarios where it gets in the way. I’ll see how I feel after some more experimentation.


Next up: Resetting default dialog styles.