How to modularize one LESS stylesheet into multiple stylesheets? - css

I am looking to take my styles.less file (which currently contains 3000 lines of stylesheet code for my entire site) and break it apart into multiple stylesheets, i.e. navigation.less, buttons.less, footer.less, etc.
I suppose I would then #import all of these individual stylesheets into a master stylesheet, such as all.less which would compile/minify down to all.css
One issue I am experiencing with breaking this styles up into individual sheets is that variable references are broken. So for example, if I port over my buttons CSS to buttons.less, my buttons CSS contains references to LESS variables that are defined in styles.less. How do I fix this issue?
Is there a better approach to modularizing my CSS code with LESS? 3000 lines of LESS code is getting completely unmanageable for one file and I need to break it up.

Most people handle this by having two particular files, something like variables.less and mixins.less.
Then if these are needed in the modules, you use import-once instead of just import (for versions prior to the at present upcoming 1.4; at which time import by default will act as import-once). You use this in both the module files and in your all.less. That way when they are all brought together inside the all.less file, the imports only occurs once at the top of the final file, and not for each individual module file loaded.

Related

(SCSS/SASS) Way to import whole document without #import

I have multiple SCSS files that I want to import into one main SCSS file. I want ALL of the contents of that file to be imported, basically copying the entire document into the other one. Currently, I am using #import, which is exactly what I need. But now it has been announced that it will be removed from SCSS, and I'm afraid that #use cannot replicate this functionality that I need. With #use, I can only import selected variables, classes etc., but I want the entire file.
Two possible solutions (that I don't want to go for):
A) Writing everything in the same file. But that would become quite messy. I have one template SCSS file with variables and utility classes (a lot of them), and 3 other files for custom code (so the CSS of a site can be changed by multiple people at the same time, having only one file would limit it to one person at a time)
B) Loading multiple stylesheets on the site. That would be the better option, but that would cause a lot of unnecessary requests on the server.
Any ideas? I'm using SCSS in Wordpress. Will the #import rule be unusable once it's been removed from the language? What if I didn't update the Plugin that compiles the SCSS? It's frustrating because the current #import rule does exactly what I need...
Thank you!
The question is more or less resolved. I was trying to migrate from #import to #use in an environment that does not support the #use rule at all. As I said, I'm using a Wordpress plugin to compile. #use is only available in Dart Sass and upon using it in my setup, the compiler would throw errors, as it is based on phpsass, which does not have #use or #forward and still uses #import. Which make everything a lot easier!

How to transform global css into css modules?

I am using react-bootstrap and bootstrap in my nextjs project, thus I have to include the global css:
// _app.js
import 'bootstrap/dist/css/bootstrap.min.css';
The problem is that I load a lot of unused css in every page, thus google lighthouse diminishes my score.
I have tried to purge the unused css, and even thought the score increases, there are still unused styles. I do not need an alert, or a button everywhere. I would like to import only the styles I need in every specific page.
Is there a way to transform global css into css modules so I only import what I need? Maybe some webpack configuration or similar?
I can do it by myself manually splitting the bootstrap code into components. But I would like to know if there is any automatic way of doing it. So I do not have to go through this procedure for all my node_modules that need stylyng.
This is one of Bootstrap's cons — outside of eliminating modules from the core bootstrap.scss file and recompiling a unique version, there isn't a way to do this out of the box. (e.g., remove #import "accordion"; from bootstrap.scss to eliminate accordion styles)
In theory, you could compile each import as a separate .scss file and load the .css only when it's needed but there are some nuance interdependencies and would need consideration to ensure some code doesn't duplicate (e.g., variables, reboot, functions)
Inversely, you most likely are only using a few modules (grid.scss, spacing.scss, buttons.scss) and can eliminate all others.

Is there a method to reduce two CSS files to one containing unique selectors?

What I have is a large CSS file which was compiled from Sass. I have some of the original Sass files, but looking at the source map not all of them.
I'm able to compile the Sass that I do have into CSS, but of course some of the style rules are missing.
How can I reduce these two files into only the rules that are unique to the original? I would like to be able to do that so that I can include that CSS with the source Sass I have on hand to speed up future development.
I would do it like this:
take original CSS and convert it to Sass by changing extension to .scss
if original CSS is minifed use something like CSS Formatter to get readable code
name it something like legacy and import first in your master Sass file
use nanocss in your build process to dedupe duplicate styles (make sure discard-duplicates plugin is enabled)
optional: enable dedupe only for production build since it slows down CSS generation
drawbacks:
if changing properties on existing classes in Sass dedupe will not match against legacy and you end up with almost-duplicates - to prevent that, I would manually go into legacy to delete old classes when changing them in sass partials
Based on your input you should do following "backwards-engineering":
1) Compare you CSS files in a diff-program, e.g. diffchecker.com (let us call your files: file1.css and file2.css).
2) The diff-program will mark duplicate areas with color.
3) Decide which file to update and remove the duplicates, in that file.
Note!. This method will only solve if you have duplicated text blocks in your CSS files. It will not solve to "clean & improve" e.g. if you have spreadout "duplicate" information.

How to use less mixins in meteor with #import and not get multiple definitions

in my current meteor app I have split the less declarations in one file per Controller (iron-router). I have a common file - where I have defined some mixins - which is imported in each less file. My problem is that the classes are imported multiple times in each route.
The file structure is:
mixins.import.less (new names, reference http://docs.meteor.com/#less)
.grid-container {
// something
}
postList.less
#import (once) url('/client/views/mixins.import.less');
postDetail.less
#import (once) url('/client/views/mixins.import.less');
Then in the Chrome inspector I found duplicated everything I have written in mixins.import.less. Is it possible to avoid this double import?
Assuming you want the mixin code at least once in your compiled css (perhaps not, some just want them as mixins, not classes in the css code), then make sure you set it to bring in the "mixins.import.less" file all by itself. Then for all your dependent files using it, do this:
"postList.less", "postDetail.less", etc.
#import (reference) url('/client/views/mixins.import.less');
The (reference) option has been available since LESS 1.5, and will only bring in the code for reference purposes to be used in the LESS file, but will not itself output any css.
Meteor bundles css and js/html resources all together as a single css and a single js file in production.
In development, they are individually served, but still at the same time, during initial page load (first ever request to server)
For less files, a css file is created for each (during development). Since you are importing, what Meteor basically does is create each corresponding css file that each contain the import individually.
And when they are served to the client all together (take a look at the head section of the generated html), you end up with that many copies of the imported style declarations.
Therefore, due to this bundling behaviour of Meteor, you can just keep one copy of your less mixins in a less file, and not import at all, since they are going to be served to the client in CSS form anyway.
Also, it is possible to trick Meteor into bypassing as described in the unofficial meteor faq:
... you can change the extension of the less files to be imported from .less to .lessimport and then change your #import file.less to #import file.lessimport. This will prevent the less compiler from automatically trying to compile all your import files independently, yet still let you use them ...

IE Question: How many CSS includes can it handle?

I came across a strange behavior while theming Drupal. I turned a few modules that added 5 to 10 link tags to the page. While these new stylesheets were added to the cascade in Firefox, in IE8, by adding these the browser discarded the earlier added CSS files from the hierarchy. In fact, the first files were the first to go, which completely screwed up the styling of the page and had me scratching my head for a while. Eventually I discovered the newly added modules had caused IE to pass some internal threshold where it could not add new includes anymore.
Has anyone seen this behavior before? I'm not sure if it's an issue with browser or with my setup.
Internet Explorer has a maximum limit of 32 CSS file links. Definitely a browser issue. You'll need to think about consolidating your css requests.
Generally you can do this by concatenating them if they're static files, but if you're generating them programatically, you might have to look at a solution to manipulate the response before it gets passed to the browser.
We had to get around this issue for our enterprise ASP.Net project and ended up writing a "Css Multiplexor" that examined the response, found the requested CSS links, generated a web resource for one big css file, and output a link to that instead.
I encountered this issue on our site.
IE8 only permits 32 CSS imports per file. That file could be an HTML file or a CSS file. (*) However, the import limit does not restrict you to 32 CSS files total. You can link to two CSS files in your HTML, each of which #imports 32 CSS files. Playing with tricks like that should get you as many as you need.
The specific workaround we use is to split the CSS files we need into two groups, and have two 'import' CSS files. The HTML page imports the first import CSS file, which imports the first group and the second import CSS file, which imports the second group.
This works fine, but results in lots of HTTP requests, so we only use this workaround on development systems. For our live sites we have a build step that compiles all the CSS into one file.
What Johannes has mentioned -- getting Drupal to aggregate your CSS -- sounds like the best bet.
(*) There's some fine print like: the 32 imports includes the CSS files that have already been imported in the chain from your HTML page. So if your HTML imports a CSS file, then that CSS file can only import 31 other second-tier CSS files, and each second-tier CSS file can only import 30 other third-tier CSS files. You really have to wonder what bizarre algorithm causes this limitation...
The limit is 31 - NOT 32!
While some would say "who cares, close enough, right?" --- With larger applications with hundreds of developers it can be very easy for the page to go over the limit, so you should really know the exact number of css stylesheets can be included on the page.
There are several ways to mitigate the problem:
Reduce the number of CSS files by consolidating into larger files - perhaps manually, or some run time grouping mechanism, or you can use an automated css compiler to combine and minimize all your CSS files
Use #import url(...) statements rather than <link href=""> but remember you can only have 31 #import (again, NOT 32...) statements in one stylesheet
Use #2 above with caution because:
You are only increasing the limit (to 961 css files) not removing it
The browser will be forced to download the CSS files in series rather than in parellel. Normally a browser can download more than 1 css file at a time (the count depends on if the files are in the same domain and which browser you are using) - This can have a significant impact on performance.
Each CSS file requires a round trip to the server adding extra time.

Resources