Why are my Styled Components' generated class names colliding? - css

I usually build my Styled Components with a root <Container> tag. However, in my current project, class names generated by Styled Components with identical names are colliding.
For example, <FooWidget> will be styled with the Container styles of <BarWidget>.
This happens unpredictably, but deterministically. I.e. not all <Container>s collide, but when they do, they do so in the same way every time. I can fix this by changing the components' names or root elements, but then this eliminates the scoping benefits of CSS-in-JS.
I've never had this problem before, which makes me suspect in may have to do with server side rendering on Next.js, which I'm using for the first time. If I restart the dev server, everything will display correctly on the initial render, but then break and stay broken on first refresh.
I installed Styled Components according to the Next.js guide. I found this bug on Github that may be related: https://github.com/styled-components/styled-components/issues/3125.

Related

React CSS Modules: any reason to -not- extract all CSS to a static file?

I have built my app with React Boilerplate, and have been surprised to find all my CSS modules are not generating CSS as I thought, but the CSS is instead generated from JS and embedded in the header of the page. The image below shows just some of the many, many style elements that appear in my header after the page has loaded.
For development, I can see this making sense for HMR etc. However, for a production build, it is not what I would expect.
I would think the most performant build (ie, best) would be a static CSS file alongside the js. In fact, in our production build there is a lot of stutter as the site loads and applies styles to the elements in a staggered manner.
It seems straight-forward to build a static CSS file, so why isn't it the default (especially for RBP, whose major claim is that it is production-ready). After 5 mins of searching I found https://github.com/webpack-contrib/mini-css-extract-plugin, which seems to do exactly what I want.
Is there a benefit to dynamically adding the CSS in the document header as pictured? Is there anything we would lose if we built a static CSS document instead?

CSS Overriding Differently Between Two Projects?

I've mostly done back-end work in the past, but I'm taking it upon myself to learn how to use Vue, and in addition to being partially color blind, design is not my strong suit. As such, I'm using a template so that I can at least have a base to start learning from.
Weirdly, however, I've noticed many times the way the CSS is loaded on my copy differs from the template, and I cannot seem to figure out why. Simply put, it seems like the SASS I've copied to a new project does not override in the same way.
My Version:
Template project, directly from GitHub:
I can get around this somewhat by finding the CSS in question and adding a "!important" to the end, though this feels like a rather hacky solution to the problem, and I'd be better off finding the real culprit, though perhaps that is the best solution.
The SASS has been directly copied from the template, so I know that nothing there is amiss. My version and the template also use the Vue-CLI that comes with Webpack, so I'm not sure if it can be some variation there, with Webpack choosing that one file cascades the other? I have all the same dependencies in my package.json file, so I know I'm not missing some crucial dependency.
I've labeled the Imgur pictures in the link I provided, but for clarification, I'd like the background to be transparent for the inspection I provided. In the template, the transparent background overrides the white, but when I run the copy of this template, the white overrides the transparent. This happens in a good handful of places I've found, so it is not just one specific part.
Hopefully this question doesn't have so many possibilities that it's impossible to answer. I just don't understand at all what could be amiss.
As you can see, the two CSS rules have the same specificity, so all things equal the rule that comes second will overwrite the first rule. In this project, there are essentially two style imports: Vuetify and the SASS files for the template (found in #/styles/index.scss).
I was able to recreate the issue by moving around the imports of these two style sheets.
In order to get the intended behaviour, you must import the styles provided by vuetify-material-dashboard after the stylesheet provided by Vuetify.
In the template project, Vuetify is imported first in main.js as import './plugins'. The vuetify-material-dashboard stylesheet, which overrides Vuetify styles, is imported in App.vue (a child of main.js).

CSS modules and rollup - generating separate CSS files ("themes") with same hashes

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)
},
]
}

How to structure all project styles by smacss methodology?

I really liked modular architecture by smacss.com/book/categorizing. But in real project I stumbled on simple case (as I thought).
ok, what I got:
1) I created a folder structure for my css-files by smacss:
Base
Layout
Module
State
Theme
2) In folder Module I've made a file with base modal windows styles, like this:
Base
Layout
Module/modal/modal.css
State
Theme
3) But I have a few types of modal windows with common styles (which I separated in modal.css - colors, borders, positions etc), but they have their own parameters. First window is very simple with two buttons, second has a lot of different content.
Question is: where should I put styles for these two windows?
a) Create folders for them as modules:
Module/modal/modal.css
Module/confirm/confirm.css
Module/product/product.css
b) or create for each css-file and put them in Base folder?
Base/confirm.css
Base/product.css
Module/modal/modal.css
I would be glad to get any advice. thank you
the main reason to use SMACCS is to organize your CSS files, therefore, there are a lot of approaches which totally depends on your project.
According to the author, as long as you keep the concept of SMACSS in your mind, you then are able to modify your project as you wish. So, what I recommend you is to have a look at your project and check your folders and files and just do whatever it makes sense more not only for you but also for other developers in the team or in the future while reading your code.
There are only two main goals that you should bear in mind:
A Base rule is applied to an element using an element selector, a
descendent selector, or a child selector, along with any
pseudo-classes. It doesn’t include any class or ID selectors. It is
defining the default styling for how that element should look in all
occurrences on the page.
and
a Module is a more discrete component of the page. This is the
meat of the page. Modules sit inside Layout components. Modules can
sometimes sit within other Modules, too. Each Module should be
designed to exist as a standalone component.
so, with this clear definition, you know now that if your rules should be standalone put them under the Module, however, if they are going to work as default to the elements so put them under the Base. In contrast, to me Product or Modal all can be Module and they are not Base as base are clearly stated as default element rules like I said on top.
I am just concern that you have written CONFIRM which looks like a State rules and I assume it can be placed under State folder.
A state is something that augments and overrides all other styles. For
example, an accordion section may be in a collapsed or expanded state.
A message may be in a success or error state.
I strongly recommend you, read SMACCS book or website one more time and have a look at one of the Jonathan Snook workshop that can be found on Youtube. It will help you to understand more and make a better decision.

Hawtio - CSS of a plugin affects CSS of another plugin

We deployed a number of Hawtio plugins (as .war files) to our JBoss Fuse / Karaf server. We noticed that since we are repeating some class and id names for our HTML elements, the CSS behavior of say, plugin A affects the style of another plugin, plugin B, especially when we reference Bootstrap-specific names like col-lg-12 and so on. Furthermore, even if plugin A does not have a bootstrap.css file packaged within it, we are able to use bootstrap-like behavior which seems to be referenced from the bootstrap.css file of plugin B. We realize that ids and classes becomes global to the entire Hawtio environment (we don't know if it's just in CSS alone that this occurs). Any tips on how to remedy this?
Thanks.
At the moment that's really how things are, CSS selectors apply to all elements in the page regardless of how they get there.
A nice solution eventually for this problem will be web components, in a browser with proper support (Chrome and Opera at the moment) you get CSS isolation in a web component, where you can define CSS for elements in your web component and it doesn't leak out and affect other elements. And to style a web component that's in a page you have to use special selectors, so web components aren't affected by global CSS rules.

Resources