csstools / postcss-plugins

PostCSS Tools and Plugins
https://preset-env.cssdb.org/
MIT No Attribution
877 stars 70 forks source link

Using plain breakpoints defintion from root #435

Closed lhtdesignde closed 2 years ago

lhtdesignde commented 2 years ago

Hi! I was going through the documentation but could not get it working so I need to ask. I have breakpoints in root looking like this.

:root {
  --break-desktop: 1025px;
  --break-tablet: 1024px;
  --break-tablet-min: 600px;
  --break-mobile: 599px;
  --break-mobile-min: 320px;
}

I'm trying to use them just like this:

  @media (min-width: var(--break-desktop)) {
    background-color: red;
  }

This seems not to work? Am I doing something wrong? I'm using webpack 5 and scss. Also your webpack configuration in the docu did not work with webpack 5 (options has an unknown property 'plugins') for me so I needed to adjust it a bit.

      rules: [
        {
          test: /\.s[ac]ss$/i,
          use: [
            'style-loader',
            {
              loader: 'css-loader',
              options: {
                importLoaders: 1,
                modules: {
                  localIdentName: '[local]-[hash:base64:5]'
                }
              }
            },
            {
              loader: 'sass-loader',
              options: {
                implementation: require('sass')
              }
            },
            {
              loader: 'postcss-loader',
              options: {
                postcssOptions: {
                  plugins: [
                    postcssCustomMedia()
                  ]
                }
              }
            }
          ]
        }
      ]
    }
jonathantneal commented 2 years ago

Hello!

Hopefully this will get you going. The syntax for custom media queries is different than custom properties.

@custom-media --narrow-window (max-width: 30em);

@media (--narrow-window) {
  /* narrow window styles */
}

Would you try out that syntax and let us know if you have any issues? I hope you have a great experience using custom media queries.

lhtdesignde commented 2 years ago

Hey thanks for the quick answer! I was reading that @custom-media is not possible within :root. In my use case i need to consume the breakpoints from root as i'm sharing those breakpoints throughout multiple repos. Is there a way to do that?

So basically doing this:

:root {
@custom-media --narrow-window (max-width: 30em);
}

and then using that
@media (--narrow-window) {
  /* narrow window styles */
}
jonathantneal commented 2 years ago

Hi @lhtdesignde,

They will be accessible. Custom Media rules are global, like @font-face or @keyframes rules.

lhtdesignde commented 2 years ago

Oww ok. I have to try that out. They are running in parallel though. So I do have a global css file where i could add the custom media but then there would be another css file generated from another webpack build that would be able to use that? Font-face and the like are understood from the browser but i need to compile this somehow into something media would understand. I guess i would need to do something with the import function then?

romainmenke commented 2 years ago

Hi @lhtdesignde,

We recently picked up maintenance postcss-custom-media and migrated the plugin to the mono repo here.

Part of this move was updating all the docs. https://github.com/csstools/postcss-plugins/blob/main/plugins/postcss-custom-media/INSTALL.md#webpack

This should be up to date for Webpack 5.


:root {
  @custom-media --narrow-window (max-width: 30em);
}

and then using that
@media (--narrow-window) {
  /* narrow window styles */
}

Can you elaborate on why these @custom-media declarations need to exist in :root ? Currently the plugin only handles @custom-media which do not have any parent.

/* works */
@custom-media --narrow-window (max-width: 30em);

:root {
  /* ignored by the plugin */
  @custom-media --narrow-window (max-width: 30em);
}
lhtdesignde commented 2 years ago

@romainmenke Thanks for this. I'll update my webpack config. It looks a bit different.

In regards to why i need it in root. I'm running a more complex architecture with microfrontends. I have a shared repo that's acting as a design/pattern library. from there I'm sharing colors etc. I also need to share the breakpoints. I'm able to set it to :root but the children need to consume those somehow and till now I didn't find a good way. The older plugin seemed to be able to do what I wrote in the starting question post so I was hopeful that method could work.

romainmenke commented 2 years ago

But why does it need to be in :root?

Can you try declaring them at the top level (not in :root)

/* shared library */
@custom-media --break-desktop (min-width: 1025px);
@custom-media --break-tablet (min-width: 1024px);
@custom-media --break-tablet-min (min-width: 600px);
@custom-media --break-mobile (min-width: 599px);
@custom-media --break-mobile-min (min-width: 320px);

Use them like this :

/* consumer */
@media (--break-desktop) {
  background-color: red;
}
lhtdesignde commented 2 years ago

ya I was not fully aware of how powerful custom-media is. I'll try it today. Thanks for the input. I think also webpack is configured wrong. So with the new config, it hopefully works.

lhtdesignde commented 2 years ago

Does it add complication because i'm using scss? So it does not work as I thought unfortunately. The problem is I think that I have 2 webpack builds. I have this plugin added to both. If I put @custom-media right next to @media in the file of the child, it works (webpack setup seems right now). But this is not what I want to achieve. If the custom-media lives next to the body definition, it is somehow removed and not shown in the generated css. if i leave out the plugin from the shared library, it's there but it is not consumed because the css is already generated in the child. So that's why I would need it to be in :root. it needs to work like the css variables. It cannot be generated since there are 2 independent builds. Is that what the import is made for? should i somehow tell the child webpack build to import from the shared?

Screenshot 2022-06-07 at 14 26 37 Screenshot 2022-06-07 at 14 25 56

romainmenke commented 2 years ago

Can you remove all PostCSS plugins that are polyfills from the process/config for the shared library?

@custom-media isn't (yet) supported by browsers so this is downgraded to something native. If you run these plugins when processing the shared library the output from this will not have any @custom-media.

lhtdesignde commented 2 years ago

ya the screenshots are from only the child having the plugin. but it does not work since it's not within the same build i think. that's why I think I might need to point the child webpack config to the other generated css.

romainmenke commented 2 years ago

🤔 That sounds like a complicated setup :)

Personally I would prefer something more like this :

Shared Library :

Consumer :

This however is not something we can be of much help with unfortunately as the plugins are all working and there is no bug here. Is it ok if we close this issue?

lhtdesignde commented 2 years ago

For sure. Thanks so much for the support. I'll figure something out 😆

romainmenke commented 2 years ago

I'll figure something out

I know you will 🚀