I read from time to time that it is bad practice to override css selectors in node_modules. Good practice is to override the stylesheets with more specific selectors in your own project. Can someone please explain to me why exactly this is bad practice.
To give you an example, I use the ngx-bootstrap datepicker and have had to adapt it for an application. For this I have added a custom theme to the bs-datepicker.css file. The bs-datepicker.css file was finally placed in the app folder, so everyone who pulls the project via gitlab will have the datepicker as custom when installing the dependencies via npm.
Could one say it depends, or is it fundamentally bad practice to extend the css of a node module or even overwrite selectors here?
you node module will only stay in your computer. If someone else uses your code and tries to run npm install , they will not get you manual css changes.
Also if you ever update your node_modules then also your changes will be overridden
Therefore you are suggested to make your changes in your code not in node modules.
You can use ::ng-deep in your code to make changes to some css in a library
Related
I've recently updated from angular 10 to 12.
I use SCSS.
After updating I noticed my logo is behind the content and all my z-index values have # prepended to the values and I don't know the reason why nor can't find any good information on where this change originates from or what is the cause.
Nothing changed in my config files or build pipelines except src package.json updates for packages
I also use angular material as my UI components library and have bootstrap spacing module imported additionally
I know the CSS is invalid. (after build). It's valid in design time but after build in runtime it gets hashtag prepended for whatever reason.
This was NOT the case before updates
Here's the design time
Is this some new angular feature that I'm missing here. Can't find anything relevant in docs.
Is this tied to Ivy?
Edit:
I believe this could be tied to recent sass API changes moving from #import to #use statements. ng update command should (according to docs) update and refactor scss for me but that's not the case.
Once I'm done refactoring if it fixes the issue I'll post it as answer here
Update to the latest available version of Angular. I had the same issue with 12.0.1, after ng update (12.0.5) the issue was fixed.
Check if it is inheriting the z-index from parent class. If it is then place it outside the parent class.
I just committed and pushed a minor CSS tweak. On my server I git pull, npm run build, and forever restart __sapper__/build
Now there seems to be more than one version of the same CSS rule across different files, as per the below screenshot (this is after disabling browser cache):
The correct rule is the third one (vertical-align: top; margin-top: 1px;), which seems to be a combination of CSS files.
Any idea where the 'old' rules are coming from? Cached somewhere somehow?
/EDIT This is my rollup.config.js: https://gist.github.com/Bandit/bbcfd6c70ace5800765313dfe6021854
/EDIT2 The styles in question are in a /style/global.scss file, which is included using the following code in /routes/_layout.svelte:
<style lang="scss" global>
#import "./style/global.scss";
main {
background-color: white;
padding: 5rem 1rem 0 1rem;
}
</style>
Guessing this is somehow the issue? Where is the right place to 'inject' global stylesheet for colours/theme/typography etc?
/EDIT3 The styles being included via _layout.svelte are being included more than once in dev as well, here's a screenshot:
These selectors don't seem to come from a Svelte component, since they're not scoped (e.g. .split-button.svelte-a9ylb1)? Or are you using :global(.split-button) in a Svelte component?
Anyway... I failed to reproduce your issue, but my intuition is that your problem probably comes from the postcss plugin. It has an inject option that is enabled by default. What this option does is injecting a <style> tag in the <head> of your doc; the code that does this is appended to your modules' JS by the postcss plugin. This behaviour might very well clash with what svelte-preprocess or rollup-plugin-svelte is doing.
Try adding inject: false in the 3 places where you're using postcss in your Rollup config, and see if this helps.
Another possibility might be the service worker. I don't think an issue there could produce your result you get, but we never know... You should try options like "Update on reload" and "Bypass for network" (I don't know what are the equivalent options in your browser) to see if that makes a difference.
Otherwise, you may have to show more of your code. Where does this precise CSS rule come from (e.g. style tag in a Svelte component, SCSS file in node_modules, ...)? How is it imported into your project (e.g. import './app.css', #import './app.scss', etc.), and where? Also, I'm surprised that you have the postcss rollup plugin only in the server (the one that is not registered in sveltePreprocess)... What do you need this for, that you don't need on the client?
EDIT: Follow up
Wait, what? You've got some style files under your routes directory?? routes/style/global.scss?
Even with that, I don't appear to be able to reproduce your problem, but it's worth noting that Sapper will try to include every file it encounters under this directory. If you've got a plugin that lets you import *.scss files, then Sapper will actually see a global.scss.js, so it will think it's a server route. Without a plugin that can eat SCSS, it should... crash. If the plugin in question is postcss with its default inject option still to true, to me it looks like a star suspect...
Anyway, some further points of clarification...
svelte-preprocess enables lang="xxx", global attribute in <style global ...>, in .svelte files only.
rollup-plugin-postcss can additionally be added, directly in plugins array (i.e. not as an option of svelte plugin). It gives support for import './foo.scss', in .js files, as well as in the <script> part of .svelte files.
(Of course, SASS support by PostCSS, or PostCSS support by Svelte preprocess are depending on the config you feed them.)
OK. So now there are multiple places where some CSS / SCSS can enter your build. That I can think of, there are the following ways:
<link rel='stylesheet' href='global.css'> in src/template.html: this one will copied as is without processing.
I suppose you can also have such a "custom" <link> tag in the markup (~HTML) part of a .svelte file, and it would be included as is in the resulting HTML (you'd still have the responsibility that the reference CSS file be accessible at the given URL).
import 'something.css' or 'import 'something.scss'in a.jsor JS part of a.sveltefile: these will get processed by bundler & plugins, and converted to some JS code, with optionally additional assets that the JS can reference (typically, a proper CSS file is generated, and some JS code dynamically injects atag for it at runtime; another approach is to generate some JS that will inject every CSS rule in the doc). PostCSS withinject: true` uses the CSS + inject tag method.
the CSS / SCSS style that you write in the <style> part of a .svelte file will also be processed by the Svelte plugin in a similar way as described just before (preprocess option required to accept anything else than raw CSS); depending on the plugin configuration, it may also try to write a '.css' file for your application (see docs. With the emitCss option, that is apparently needed for Sapper, it should output one CSS file per component (or maybe entrypoint).
In your case, you say that you've removed rollup-plugin-postcss from your config, so the 3rd point (import css from js) should not be possible anymore.
Well... I just hope this can help you investigate further.
I've pushed a Sapper + PostCSS example on a branch on this repo. As far as I can tell, it doesn't have the issue you're describing here. So maybe you can find the problem by comparing with what you have. See this commit for the diff with the vanilla official template.
I tried to also add rollup-plugin-postcss, like you initially had in your config, in order to be able to import .scss from outside of Svelte components. But I failed to find a way to do this that don't conflict with Sapper.
EDIT 2
Oh, and just to be sure... Be sure to try a little rm -r __sapper__ && rm -r src/node_modules/#sapper (notice: node_modules under src, not the one in your project's root) before pursuing your investigation. I'm sure you've already done that, but better safe than sorry. Stale things can live in there.
I'm using CSS Modules (Sass) with rollup on a component library project, which is working well. Each component ends up with a dist folder containing a single JS bundle file, and a corresponding CSS file with the scoped CSS classes so consumers of the component don't have to worry about CSS class name conflicts. All they do is include the JS bundle and the CSS file and everything is great. Yay CSS Modules.
The problem I'm now facing is that some components really need separate "themes" - ideally, separate CSS files, one per theme. So consumers can continue as they've been doing: including the JS bundle, but now choosing which CSS file to include to pick a theme.
I'm not sure how to get this going with CSS modules & rollup, and whether this is even the sort of approach others are taking. From what I can see, rollup always handles bundling things together, whereas I want separate CSS files, all of which get their classes renamed identically during the build phase. That way, if within my JS I refer to styles.myclass, if myclass had gotten renamed to scoped-myclass by CSS modules for the original CSS file, for a second CSS file it would also get the same name.
This would keep consumption of the component extremely simple - just a matter of including a different CSS file.
Any suggestions?
Awfully late, but let me answer this 3 years on. So what I ended up doing was totally detaching the CSS generation step from rollup and relying on the Sass CLI to handle that portion of the build process. It felt a bit klutzy, but I remember it wasn't awfully hard to do and solved the problem I outlined above. I don't believe there was a plain rollup solution at the time, nor do I think there's one today.
However... in my case the whole approach was kinda mistaken. This certainly won't be everyone's scenario, but let me spell it all out because hey it may be useful and it definitely wasn't obvious to me at the time.
This was for an in-house shared component library, where each component and its corresponding CSS was a separate npm package stored in our Artifactory. When it grew, plenty of internal references popped up, e.g. multiple components would reference the Button component, and over time they'd reference different versions of the Buttons component - each of which needed its own properly scoped CSS, unique to that package-version.
So what I found was that by doing it this way - having the CSS generated as part of the npm package dist files - I had to write an additional layer for the consumer applications that would parse their node_modules/ folder for our own internal components and combine all the different CSS files, such as the multiple versions of buttons. e.g. the main application would directly import buttons v1.0.0 in its package.json file, but the Dialog component (also included in the package.json) could include buttons 2.0.0 as its own dependency. For every version of the package, there was a uniquely scoped version of the CSS - so the consuming application HAD to include every version otherwise the styling would be borked.
So all in all, it ended up being way more complex that I wanted. I thought I could make it easier & better with the separate generated themed CSS files as part of the package dist, but it didn't end up that way. If I could revisit that project today, I'd re-examine a solution used by Material UI and others which I kinda poo-poo'd at the time: automatic injection of the CSS into the page by the component JS, rather than generating standalone CSS files which required extra work by the consumer applications to gather up and add to the final webpage. Frankly, now I regard it as the "least crap". There are definite downsides to the injection approach (extra work done on every page render for everyone! Yikes!), but there's no doubt in my mind it hugely simplifies the job of the consumer applications. It's a balancing act, but in 20-20 hindsight I'd lean towards the injection approach. With that, scoping & theming is a different and much simpler problem.
If I got you right, consider looking at SCSS plugin: rollup-plugin-scss. It captures all spare .css files imported in the components, and then processes them through underlying node-sass. The catch is, it seems like you can write a custom callback function that'd handle your CSSs differently based on conditions you throw in.
Based on the example from the plugin's page:
import scss from 'rollup-plugin-scss'
...
export default {
input: 'src/index.tsx',
output: [...],
plugins: [
...
output: function (styles, styleNodes) {
// replace this with conditioned outputs as needed:
writeFileSync('bundle1.css', styles)
writeFileSync('bundle2.css', styles)
},
]
}
I think this should be possible, though dont know, I use tools like 'gulp' and 'webpack' to bundle asset files but is there any tool that extracts the necessary css classes, only that are being used, from the css files and pack them.
What you are looking for is called tree shaking, and usually it's already done in the build process with webpack,
You can install this plugin for css specific tree shaking or you can look for more info here about how it works with javascript (something similar happens in css)
In Gulp there is package called Uncss
https://github.com/ben-eb/gulp-uncss
and also an addon that is available for firefox
https://addons.mozilla.org/en-US/firefox/addon/dust-me-selectors/
which will help you in removed unused css
Take a look into tree shaking, there are several that are for specific css.
I tried to take a look around here and on the Liferay forums but I couldn't find a documented solution to my issue.
I am currently using Liferay 6.2 and am very new to the environment. My issue arises from CSS #import functions. Our architecture is one main stylesheet with all supporting stylesheets imported into this document. Those CSS documents in the same directory present no issue - for example #import url(document.css);. We do have a master stylesheet located in another portlet and all other portlets reference this stylesheet with an import call similar to #import url(../../../../folder/folder/document.css);. When using this command, the CSS in this file isn't imported into the portlet. If I place the master stylesheet in the same directory as the CSS for that portlet and adjust the import path accordingly, the stylesheet is imported without any issues. I can also place it one directory up such as #import url(../folder/document.css); and the CSS is imported correctly.
Several team members do not have this issue, while several members do experience this issue - all running the same version of Liferay and on identical machines.
I'm sure my question is fairly vague due to me being new with the environment so if I can clarify or provide any additional details, please let me know!
If all of the portlets reference the same CSS file they shouldn't: Just assume that the necessary CSS is deployed through the theme and add it to the theme once. This is way more elegant than delivering it multiple times, relying on relative paths to not have changed, and potentially not being available (at runtime, nobody guarantees that an appserver even unzipps your warfiles).
Through enforcing the assumption that you're running in an environment that has proper styling, life will be so much easier.