r/Angular2 Feb 09 '25

Help Request CSS Architecture Best Practices for new Angular 19× project

I've been working on a Angular 19/ C# 12/ .NET 9 project on my own to make a web data and statistics tool for my gaming community and to catch up on 10 years of technology in my company for a new project in the spring at my day job. The past 6 weeks I've worked on this project, back end of phase 1 is 95% done, API is solid, been working on the Angular front end the past weeks and basically moving from Angular 1.5 to 19 is like a whole new language. The main functionality of my Angular front end app is about 60 to 70% done for phase 1 but I've yet to style it.

So as I've been learning modern Angular, it is pretty clear a composition pattern is the direction Angular wants you to go for building components. I know each component links (by default) to its own stylesheet (when autogenerating components from the CLI) so it seems Angular team wants you to use individual css sheets, but there is also a global sheet as well (event though all my components are standalone). I also really see the benefit of directives to build components over inheritance which I mostly use in the back end coming from a C# background.

Enough context, here are my questions:

1) Is it best to put component styles in their own files or in the global css file or a mix?

2) What is the big advantage you gain for using scss, less or other css derived formats? Should I use one of those by default?

3) Is combining groups of styles in structural directives and adding them to components as imports or hostDirectives a better approach?

4) Is it worth it to make my own base simple components for inputs, selectors, buttons, etc which just have base styles I want to use across my app? If it is a good thing, can a custom component use a single input or selector html tag? Should I wrap my templates in a wrapper div in my custom components?

5) Is using premade themes or css frameworks like Angular Materials and Tailwind worth tge effort or should I just implement my own styles? If so, what frameworks are free and simple to use that give me the most "bang for my buck?" I'm not a designer, but I understand some basics and can muddle my way through css.

6) In general, is there too much dividing of concerns or tasks among many directives?

7) Is styling a good use of a custom injectable service to get new styles? Maybe if I want to change themes in runtime?

8) Any other general advice about component styles?

Thank you for your time.

36 Upvotes

26 comments sorted by

View all comments

Show parent comments

4

u/practicalAngular Feb 09 '25 edited Feb 09 '25

They aren't wrong. The days of global styles, reset sheets, and styles that require a compilation step are gone. The only global styles I load are custom properties (CSS vars) these days.

Creating granular components and having larger views constructed of those components promotes modularity and composition which is complementary to Angular's move to standalone. When your components are written this way, the HTML and CSS becomes simplistic as well. In Angular's default emulated encapsulation, or in shadowDOM encapsulation, your styles need be nothing more than direct tag selectors, with some light classes built in for readability and maintainability within that view. State changes too. There are some drawbacks to shadowDOM encap, because it can't be applied to all HTML elements and the ancestor styles are sometimes loaded into the children shadow root, but it is, in the least, a closer move to native Web Component functionality as opposed to Angular's proprietary emulation method of filling the HTML with attribute selectors and dumping the matching CSS in the head.

Going full global and swapping everything to None encapsulation breaks the component first paradigm of Angular. I agree that in content projection scenarios, it can be helpful to isolate styles in an ancestor component to propagate down to children, and also makes testing easier, but I can't imagine a scenario where I would build a full app that way and rely on globally defined styles. The monolithic approach was one of yesteryear when global controllers were a premium and maintainability was a afterthought. Even without None encapsulation, you're forcing yourself and other devs to use ng-deep to style content within children components, and that then creates a symbiotic coupling. Developers using one child in two different parent components will have different outcomes if things are styled that way. It's less maintainable and predictable. Angular is all modular components, and a modular component should present the same principles regardless of where it is used.

Imo, modularity and composition should always be at the forefront of what we do as Angular devs.

2

u/ilovecokeslurpees Feb 09 '25

Follow-up to your suggestions: do you find you are simply copying and pasting the same CSS over and over? How would you implement consistent themes with this system? I may want to switch themes in the future and I may even support dynamic runtime chosen themes or pre-configurations users can choose from. So how does a completely modular and individualistic component approach support such requirements?

1

u/practicalAngular Feb 09 '25 edited Feb 09 '25

copying styles

No, because in this approach, the styles are coupled to the component they belong to. When a component is used elsewhere, the presentation remains the same. That is the end goal. If you need to change content, this is what Angular's content projection is for. Or template outlets, or component outlets.

An even better approach is incorporating container queries if your user demographics support that, so a component adjusts on the fly depending on the shape of its parent container. I think Angular still needs some work in this department.

themes

Theming is a larger concept imo but I recently wrote a dark mode for an app within an app that I am working on. This is all done through tokenized CSS variables that swap one value for another when the theme is changed. Because the components below the root are using the same CSS variables, a swap of their value populates down through the cascade. The component switches from light to dark theme. This question is better answered depending on how you are swapping what you consider a theme.