Skip to content

postcss-custom-media - Support variables for setting media rules #680

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
2 of 3 tasks
Preen opened this issue Oct 31, 2022 · 19 comments · Fixed by #472 or #846
Closed
2 of 3 tasks

postcss-custom-media - Support variables for setting media rules #680

Preen opened this issue Oct 31, 2022 · 19 comments · Fixed by #472 or #846

Comments

@Preen
Copy link

Preen commented Oct 31, 2022

What would you want to propose?

Be able to set custom-media with variables such as

$medium_up: 767px;
@custom-media --medium-up-viewport (min-width: $medium_up);
@custom-media --medium-up-viewport (min-width: design-token("media.breakpoints.medium-up", to px));

Suggested solution

I dont have any :)

Additional context

No response

Validations

  • Follow our Code of Conduct
  • Check that there isn't already an issue that request the same feature to avoid creating a duplicate.

Would you like to open a PR for this feature?

  • I'm willing to open a PR
@Preen Preen added the feature request New feature or request label Oct 31, 2022
@romainmenke
Copy link
Member

@Preen Thank you for reaching out.

We can not add this to the custom-media plugin because this feature request deviates from the specification.

This plugin has a very clear and well defined scope that must align with what browsers will implement in the future.


@custom-media --medium-up-viewport (min-width: design-token("media.breakpoints.medium-up", to px));

We can investigate how design tokens can be used in at-rules.
This would include @custom-media and @media.

For now I prefer to keep this unresolved because this is a feature that has been requested in the standardised design token format.

Inventing some syntax now would also imply a breaking change later if the two are not compatible.

@Preen
Copy link
Author

Preen commented Oct 31, 2022

Thank you for your quick response and it sounds like a good way forward :)

@romainmenke
Copy link
Member

romainmenke commented Jan 24, 2023

Hi @Preen

We have released an update to our design tokens plugin : https://www.npmjs.com/package/@csstools/postcss-design-tokens

You can now use design tokens in any at rule :

@media (min-width: design-token('viewport.medium')) {
	.foo {
		padding-bottom: design-token('size.spacing.medium' to rem);
	}
}

/* becomes */

@media (min-width: 35rem) {
	.foo {
		padding-bottom: 1.1rem;
	}
}

@mantismamita
Copy link

Hi @Preen, I had the same question. @romainmenke I was wondering if it would be possible to envision using postcss-global-data as a way to include design tokens in @custom-media rules. Perhaps if they were in the correct order? Maybe @Antonio-Laguna already envisioned this scenario?

@romainmenke
Copy link
Member

@mantismamita Do you have a concrete example?
I don't immediately understand how this would look like.

The design tokens plugin supports any and all at rules.

This will just work :

@something-made-up design-token('foo') {}

So will this :

@custom-media --foo (min-width: design-token('viewport-tablet' to px));

But it is important to keep in mind that there is no magic here.
This will not do anything special :

{
  "viewport-tablet": {
    "value": "320"
  }
}
/* 1 */
@custom-media design-token('viewport-tablet');
/* becomes */
@custom-media 320;

/* 2 */
@custom-media --foo design-token('viewport-tablet');
/* becomes */
@custom-media --foo 320;

The design token plugin doesn't try to figure out what you are trying to do.
It does a simplistic find/replace of CSS tokens.

@mantismamita
Copy link

mantismamita commented Feb 9, 2023

What I had in mind was

@tokens url('../../lib/assets/tokens/viewport.json') format('style-dictionary3');

@custom-media --xxs-min-viewport (min-width: token("viewport.px.xxs"));
@custom-media --xs-min-viewport (min-width: token("viewport.px.xs"));
@custom-media --small-min-viewport (min-width: token("viewport.px.small"));
@custom-media --medium-min-viewport (min-width: token("viewport.px.medium"));
@custom-media --large-min-viewport (min-width: token("viewport.px.large"));
@custom-media --xl-min-viewport (min-width: token("viewport.px.xl"));
@custom-media --xxl-min-viewport (min-width: token("viewport.px.xxl"));

or Ideally

@custom-media --xxs-min-viewport (min-width: token("viewport.px.xxs" to px));

I'm using postcss-global-data in order to have access to @custom-media rules in all files of a svelte project.

Edit: actually the latter syntax works already. I was trying with "xxs": { "value": "360px" } in the json.

@romainmenke
Copy link
Member

actually the latter syntax works already

awesome!
So then all is fine? :)

@mantismamita
Copy link

Yes, thank you for responding so quickly!

@Preen
Copy link
Author

Preen commented Feb 9, 2023

@romainmenke wow, nice solution. Great work!

@mantismamita
Copy link

Argh, I spoke too soon. I'm wondering if it might not be the order of the plugins.
I restarted and now I'm getting the tokens unreplaced.

<style>.outer{background-color:#00000020;width:100%}[class*=inner]{--quarks-grid-column-number:1;background-color:#00000040;grid-column:span 1}@media (min-width:token("viewport.px.medium" to px)){[class*=inner]{--quarks-grid-column-number:4;grid-column:span 4}}
</style>

@romainmenke
Copy link
Member

The order of the plugins is definitely important.
I would always place the global data plugin first or as early as possible.

What is you current order?

@mantismamita
Copy link

I've tried changing the order but this one seems the most logical

module.exports = {
  plugins: [
    require('@csstools/postcss-design-tokens')({
      importAtRuleName: 'tokens',
      valueFunctionName: 'token',
    }),
    require('@csstools/postcss-global-data')({
      files: ['./__customMedia.css'],
    }),
    require('postcss-import')(),
    require('autoprefixer'),
    require('postcss-custom-media')(),
    require('postcss-custom-properties')(),
    require('postcss-nested')(),
    require('cssnano'),
  ],
};

@romainmenke
Copy link
Member

In that order the design tokens plugin will not see the CSS that is injected by the global data plugin.

This is what I would do, but I can't test or verify this obviously :)

module.exports = {
  plugins: [
    require('postcss-import')(),
    require('@csstools/postcss-global-data')({
      files: ['./__customMedia.css'],
    }),
    require('@csstools/postcss-design-tokens')({
      importAtRuleName: 'tokens',
      valueFunctionName: 'token',
    }),
    require('autoprefixer'),
    require('postcss-custom-media')(),
    require('postcss-custom-properties')(),
    require('postcss-nested')(),
    require('cssnano'),
  ],
};

@mantismamita
Copy link

mantismamita commented Feb 9, 2023

Ok I tried that as well as

module.exports = {
  plugins: [
    require('@csstools/postcss-global-data')({
      files: ['./__customMedia.css'],
    }),
    require('@csstools/postcss-design-tokens')({
      importAtRuleName: 'tokens',
      valueFunctionName: 'token',
    }),
    require('postcss-import')(),
    require('autoprefixer'),
    require('postcss-custom-media')(),
    require('postcss-custom-properties')(),
    require('postcss-nested')(),
    require('cssnano'),
  ],
};

but no luck 😢
I'll keep trying to move around the order then.

@romainmenke
Copy link
Member

@mantismamita We found and resolved a minor issue that is likely the cause of what you are seeing.

We will release this as soon as possible.

@romainmenke
Copy link
Member

Release just went out for @csstools/postcss-global-data : https://www.npmjs.com/package/@csstools/postcss-global-data

@mantismamita can you give this a try and let us know if everything is now working?

@mantismamita
Copy link

Hi, looking good! Its working fine in dev mode but I'll wait till the build to confirm just in case.

@mantismamita
Copy link

Ok, I think I can safely say that everything is working properly. Thank you so much @romainmenke ! 😄

@romainmenke
Copy link
Member

Awesome!
Thank you for providing us with all the extra info and for testing everything so thoroughly 🙇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants