Media Queries not working for Multi-Panel Plugins?


I think there’s a bug in UXP preventing all media queries from working when you have more than one panel in a plugin.
The css inside the media query just gets applied no matter if the condition is met or not. When I remove all panels except for one from the manifest, the media queries work fine.

Would be great if someone could look into this, I’m planing to finish a very large plugin in the next couple of weeks and this bug makes it impossible to build responsive layouts :confused:


could the team validate this or is it already aware of it?

Has anyone else built a plugin with more than 1 panel yet and can confirm this bug?

Can you share what media queries you’re using?

Nothing special, I just tried it with:

body {
  border: 4px solid crimson;
@media only screen and (min-width: 420px) {
  body {
    border: 4px solid teal;

What I just noticed is, that the original style on the body isn’t applied at all when I have multiple panels. If I hover over the tags in the elements tab of the dev tools, the viewport is not highlighted in blue. So it seems to be the case that the body and html tag don’t have a computed size when using multiple panels.
If I remove all panels except for one, everything works as expected (body style works, media queries work and the body/html element gets highlighted):


I’m getting closer to finding the issue: I just unloaded and loaded the plugin while the style I added to the body was still in the code, this is the result:

So only the first plugin is getting the computed size of the body/html tag. Maybe there’s a problem in the way I load the panels :thinking:

Here’s the relevant code section of my “Controller” function:

  let attachment: any
  let root: HTMLElement
  const create = () => {
    const panel = <Component key={panelId} />
    root = document.createElement("div");
    ReactDOM.render(panel, root);
    return root;

  return {
    show: (event) => {
      if (!root) { create() };
      attachment = event.node;
    hide: () => {
      if (attachment && root) {
        attachment = null;
    destroy: () => { return },

@kerrishotts I did some tests with the ui-react-starter example, to make sure that my panel controller code is not the problem. The results are the same. I gave each panel component a className .panel and added the following CSS:

  border: 8px solid white;

.panel {
  border: 8px solid crimson;
@media only screen and (min-width: 360px) {
  .panel {
    border-color: teal;

So, the body should have a white border and the panel a red one, until you make it wide enough, where it should change the color. Here’s how it looks like:

As you can see, the styles added to the body are only visible in the first panel. This would not be a problem if at least every panel would have its own viewport somehow, but the global viewport (which is relevant for sizing, media queries etc), is completely based on the first panel only.

Btw, for the video, I’ve removed the line this[_root].style.height = "100vh" from the panel controller. If I bring it back, this is the result:

and adding height: 100vh to the .panel class results in the following:

I think it becomes quite clear that the viewport is coupled to the first panel, but expanded in height due to the additional panel being somewhere in the DOM. Also, viewport changes to the first panel trigger media queries across all other panels, while changing the viewport of all other panels is just ignored.

Hopefully there will be a fix for that soon. Right now the only option I see to maybe get it working would be to add the resize event to each panel, checking the size and appending some global classes like .media-s to the panel. All other components would then have to add some CSS selectors accordingly to realize the media query behavior. However, I haven’t tested this yet and it seems like quite an ugly workaround.

I dug into the code, and as far as I can tell, it’s always basing the viewport sizes off the html element, which means that it’s based on the first panel made visible (since that gets attached to the body element).

I’ll file a bug internally.

For now, I think your best option is as you described – have a resize listener that takes care of adjusting some classes so that you can emulate the media query.

Thanks for confirming and filing the bug!