SharePoint / sp-dev-docs

SharePoint & Viva Connections Developer Documentation
https://docs.microsoft.com/en-us/sharepoint/dev/
Creative Commons Attribution 4.0 International
1.24k stars 1.01k forks source link

SPFX - SCSS modules, support for CSS @Container queries #9385

Open stevesuk opened 10 months ago

stevesuk commented 10 months ago

What type of issue is this?

Question

What SharePoint development model, framework, SDK or API is this about?

💥 SharePoint Framework

Target SharePoint environment

SharePoint Online

What browser(s) / client(s) have you tested

Issue description

I noticed that when compiling .scss modules for an SPFX, CSS container queries are not supported. Since webparts can end up being inserted in to a variety of different container widths, depending on the section layout - it would be really useful to be able to use container queries (which use the parent element width/height as a trigger for CSS styling). My work around at the moment is to include a standard CSS file with the styling that benefits from container queries, and use a unique CSS classname in my SPFX. However, it would be better if you could use these queries in compiled SCSS modules.

Is there a way of doing this?

ghost commented 10 months ago

Thank you for reporting this issue. We will be triaging your incoming issue as soon as possible.

StfBauer commented 9 months ago

This one can be added to a list of problems:

Let's talk about container queries for a moment. While they might seem super fancy, they could work better with SharePoint. SharePoint has a 12-grid layout, which is documented here: https://learn.microsoft.com/en-us/sharepoint/dev/design/grid-and-responsive-design

Under the Hood, they use:

The last vertical section is out of the grid and needs to be added to the documentation.

To make the container query work - you could rely on min-width width of all sorts, but you still don't know the container you are in. If you tend to define container-name as well as container-type then every web part would overwrite each of the values newly with every new webpart, despite for the columns you need to change the out of the box CSS styles, which is not supported nor recommended. If container-name ever has to come from Microsoft, it needs to be documented for us to save to use it.

The other option would be chasing down pixel value for the outer container, which doesn't indicate how many grid columns your web part can populate. Also, you do not know if you may be on four grid columns on a tablet or 12 grid on a desktop. Neither will it be safe when Microsoft changes pixel values only by a bit because your breakpoints may not match.

Container queries in this context are a fragile construct. So the webpart might work today but not tomorrow suddenly out of the blue anymore.

So the safer way is to work with the SharePoint given grid system and not against it as described here - https://n8d.at/how-to-make-your-web-parts-responsive-to-the-parent-container.

Those grid columns are defined and documented, and maybe, in future, we can use something like CSS Subgrid.

We are currently on the sass 1.44, which should already support @ container queries, but those will likely be lost along the way, presumably in postCSS and CSS module compilation.

Would it be great to have it in future - I need to find out where SharePoint and the page designs are heading, so the customisations might break. Also, we need more documentation from Microsoft on the page side of things before we can fully leverage container queries.

What's good for early adoption might not be good for production.

StfBauer commented 3 months ago

@nick-pape any news or workaround not that?

StfBauer commented 3 months ago

I found the reason why container queries along side with so many other browser supported web standard do not work.

image

clean-css@4.2.1 which the SASS SPFx build task uses was released almost 6 years ago and does a decent job by 6 year old standard, by removing all it is unaware of. Such as @layer and @container CSS options.

However a there is a workaround that get offered by the build change and clean-css. It is to disable it completely. The negative impact is that is doesn't do it's magic anymore, while allowing to write web standard and widely browser supported CSS.

Another interesting fact that sp-build-core tasks got already update. Not so the @microsoft/sp-build-web@1.20.1 package.

The workaround

Like I said the workaround is to disable it completely.

build.sass.setConfig({
  dropCssFiles: true,
  useCSSModules: true,
  warnOnNonCSSModules: false,
  cleanCssOptions: {
    level: 0,
    compatibility: {
      colors: {
        hexAlpha: false, // controls 4- and 8-character hex color support
        opacity: true // controls `rgba()` / `hsla()` color support
      }
    }
    , returnPromise: true
  },
  autoprefixerOptions: { overrideBrowserslist: ["> 1%", "last 2 versions", "not dead"] }
});

With these options inserted into the gulpfile.js.

 cleanCssOptions: {
    level: 0,
    compatibility: {
      colors: {
        hexAlpha: false, // controls 4- and 8-character hex color support
        opacity: true // controls `rgba()` / `hsla()` color support
      } 
    }
    , returnPromise: true
  }

Clean CSS Level 0 disable clean-css entirely, not optimal but even better than use this outdate version.

In addition to the autoprefixerOptions:

{
autoprefixerOptions: { overrideBrowserslist: ["> 1%", "last 2 versions", "not dead"] }
}

These options finally remove the support for IE10+ making the CSS by itself more cleaner.

I really hope that we will see these enhancements in the 1.20.0 version of the generator.

@nick-pape @AJIXuMuK @stevesuk

PS: There are in addition to this other bug in the CSS compilation that causes other issues too.

tymvios commented 3 months ago

Hello @StfBauer ,

I tried the workaround with no success on the container queries. Do we have an update when this will be officially supported natively by SPFx? We currently use a bunch of media queries like the suggestions in your article for the webpart to know where it is. But I feel this creates a lot more overhead when trying to make things responsive and having to change layouts in multiple locations in your css.

(the attachment below is the same webpart just placed in different placeholders)

image

stevesuk commented 3 months ago

Our workaround is to reference a standard CSS file in the project, which we use only for the elements that require a Container query. All the other styling in the project stays within SCSS modules. In the CSS file, we reference the elements we wish to apply Container sizing to by ID - so as not to conflict with the class names generated from the SCSS modules.

It would be great to be able to manage the whole process in SCSS - but our current work-around is OK until the framework is updated.

StfBauer commented 3 months ago

@tymvios This can be accomplished with using :global and :local statements and use the official CSS classes provided by Microsoft. I wrote a blog post a long time ago and still works today. https://n8d.at/how-to-make-your-web-parts-responsive-to-the-parent-container

Meanwhile I create a SASS Mixin that has all the media queries include too.

You design is fairly easy to accomplish without container queries.

@stevesuk Worked for me without any problem - meanwhile I have a complete blog post out. https://n8d.at/how-to-implement-contemporary-css-in-sharepoint-framework

One thing I had to do is to write SASS in the form of:

@charset "utf-8";

.helloworldcontainer {
  display: flex;
  container-type: inline-size;
  container-name: helloworld;

  @container helloworld (width > 300px) {

    .helloworld {
      background-color: green;
    }
  }

}

.helloworld {
  background-color: lime;
}

When I moved the @container out of the class it haven't worked. With this approach the compiled CSS looked like this:

.helloworldcontainer_2e4f0223 {
    display: flex;
    container-type: inline-size;
    container-name: helloworld
}

@container helloworld (width > 300px) {
    .helloworldcontainer_2e4f0223 .helloworld_2e4f0223 {
        background-color: green
    }
}

.helloworld_2e4f0223 {
    background-color: lime
}

With that I was able to successfully apply it to one of my customer projects.

StfBauer commented 3 months ago

@tymvios You will find the mixin here: https://github.com/pnp/custom-learning-office-365/blob/65c95835c6fab42455649e1dcd4694e9de46d82f/src/webpart/src/webparts/common/_rwd-opt.scss