Skip to content

Media query ordering changes when converting to object #69

Description

@AlanBreck

I have a problem where a given rule's default definition (.leoButton.isSecondary) gets placed after the media query, which changes the behavior of the rendering. As such, the default overrides the media query, and the media query never takes effect.

Is this a known bug? Is there any known fix for this?

Input

.button.isPrimary {
  --bg: var(--color-secondary-light-mode-70);
  --bg-hover: var(--color-secondary-light-mode-80);
  --bg-active: var(--color-secondary-light-mode-90);
  --bg-focus: var(--color-secondary-light-mode-70);
  --bg-loading: var(--color-secondary-light-mode-50);
  --bg-disabled: var(--color-gray-70);
  --color: white;
}
@media (prefers-color-scheme: dark) {
  .button.isPrimary {
    --bg: var(--color-secondary-dark-mode-50);
    --bg-hover: var(--color-secondary-dark-mode-60);
    --bg-active: var(--color-secondary-dark-mode-70);
    --bg-loading: var(--color-secondary-dark-mode-60);
  }
}
.button.isSecondary {
  --bg: white;
  --bg-active: --color-gray-20;
  --color: var(--color-gray-90);
  --color-hover: var(--color-secondary-light-mode-70);
  --color-loading: var(--color-gray-70);
  --border-width: 1px;
  --border-color: var(--color-gray-30);
}
@media (prefers-color-scheme: dark) {
  .button.isSecondary {
    --bg: black;
    --color-hover: var(--color-secondary-dark-mode-80);
  }
}

Output

{
  ".button.isPrimary": {
    "--bg": "var(--color-secondary-light-mode-70)",
    "--bg-hover": "var(--color-secondary-light-mode-80)",
    "--bg-active": "var(--color-secondary-light-mode-90)",
    "--bg-focus": "var(--color-secondary-light-mode-70)",
    "--bg-loading": "var(--color-secondary-light-mode-50)",
    "--bg-disabled": "var(--color-gray-70)",
    "--color": "white"
  },
  "@media (prefers-color-scheme: dark)": [
    {
      ".button.isPrimary": {
        "--bg": "var(--color-secondary-dark-mode-50)",
        "--bg-hover": "var(--color-secondary-dark-mode-60)",
        "--bg-active": "var(--color-secondary-dark-mode-70)",
        "--bg-loading": "var(--color-secondary-dark-mode-60)"
      }
    },
    {
      ".button.isSecondary": {
        "--bg": "black",
        "--color-hover": "var(--color-secondary-dark-mode-80)"
      }
    }
  ],
  ".button.isSecondary": {
    "--bg": "white",
    "--bg-active": "--color-gray-20",
    "--color": "var(--color-gray-90)",
    "--color-hover": "var(--color-secondary-light-mode-70)",
    "--color-loading": "var(--color-gray-70)",
    "--border-width": "1px",
    "--border-color": "var(--color-gray-30)"
  }
}

Activity

ai commented on Aug 11, 2022

@ai
Member

Can you create a smaller example to understand what is happening?

AlanBreck commented on Aug 11, 2022

@AlanBreck
Author

Sure thing. I've edited my original issue to include the bare minimum to reproduce.

ai commented on Aug 11, 2022

@ai
Member

I got the problem, it happens because you have 2 media queries. JS object doesn’t allow having 2 properties with the same key, so we try to collapse them.

There will not be a proper solution for this limit.

Here is what we can do:

  1. If you can, avoid object format for CSS. It is just not a production ready solution and a hack.
  2. You can use another PostCSS plugin to combine at-media in the end of the file. It still will be dangerous and could create another issue.

ai commented on Aug 11, 2022

@ai
Member

The third option is to change objectifier.js to keep merged at-rule at the position of the latest merging at-rule. Again, it is not a solution, but a hack, since we can create another conflict.

But maybe this strategy will create less issue.

If you want to you try to help me creating a PR.

AlanBreck commented on Aug 11, 2022

@AlanBreck
Author

Could a possible fourth option be to output an array of objects instead of an object? I know that Tailwind (which is my use case) accepts this syntax (see very end of that page for example). I'm not sure how widely acceptable that would be, though.

ai commented on Aug 11, 2022

@ai
Member

Could a possible fourth option be to output an array of objects instead of an object?

We can generate array in case when we have different media with the same params.

AlanBreck commented on Aug 11, 2022

@AlanBreck
Author
  1. You can use another PostCSS plugin to combine at-media in the end of the file. It still will be dangerous and could create another issue.

The sort-media-queries worked quite nicely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions