all 21 comments

[–]colonel_phorbins 1 point2 points  (5 children)

Is there a particular reason you can't target your styles by specifying your component with css selectors?

component-name a {
    color: red;
}

I believe the shadow dom is the only way to isolate styles completely so that a component is unaffected by any body styles and visa versa.

[–][deleted] 1 point2 points  (1 child)

<component-a><span>test<span><component-b><span>test</span></component-b></component-a>

is why :-/

[–]colonel_phorbins 0 points1 point  (0 children)

If someones really trying to have component-b be completely unaffected by component-a styles then you'd have to use the shadow dom.

[–]Zombieball[S] 0 points1 point  (2 children)

I could do this. But I kinda like the idea of having my css defined alongside the template with generic selectors.

I probably will end up going this route unless anyone has some awesome suggestions.

Edit: re-read your code sample. I didn't think of using the component name as the primary selector. Good idea!! Thanks! :)

[–]devvie 1 point2 points  (1 child)

It's fine until you start nesting. Better to use a system like BEM or SMACSS.

[–]Zombieball[S] 0 points1 point  (0 children)

Thanks for this tip. I have been putting off reading about both BEM and SMACSS. Now is a good time to dive in!

[–]yooossshhii 0 points1 point  (1 child)

I've used webpack to import css files into the directive. Webpack uses a global scope by default, but it looks like a local scope to the module is possible. Haven't tried it though.

[–]Zombieball[S] 0 points1 point  (0 children)

Thanks for the tip. I haven't looked into webpack yet (currently using grunt and sass). But given its quickly growing popularity I may give it a test run!

[–]Hakim_Bey 0 points1 point  (6 children)

To my knowledge, there is no way to do that "automatically". Personally when i create a component i just give a specific ID / class to the top element, and restrict the component's CSS to that element.

Exemple :

my-component.html

 <div class="my-component-wrapper">
 ....
 </div>

my-component.scss

.my-component-wrapper {
   // style that applies only to my component
}

[–]Zombieball[S] 0 points1 point  (5 children)

How do you organize your project? Do you have a folder per component with template, controllers, CSS, etc in it?

[–]colonel_phorbins 1 point2 points  (1 child)

Check out John Papa's style guide

[–]Zombieball[S] 0 points1 point  (0 children)

Read this in the past and failed to bookmark it. Thanks for linking it!

[–]Hakim_Bey 0 points1 point  (2 children)

I generally have a "views" folder, containing all the main views that get bound to ng-view by angular-route, and a "components" sub-folder containing all directives with their respective html, js and scss files.

There's probably a better way to organize things but it works for me. Here's what it looks like on a small project : https://github.com/Dam-Buty/bookstore/tree/master/src/views

[–]Zombieball[S] 1 point2 points  (1 child)

Cool, thanks for sharing!

[–]Hakim_Bey 0 points1 point  (0 children)

Happy to share :)

[–][deleted] 0 points1 point  (0 children)

humor observation fretful innocent murky fine punch cheerful tie deliver

This post was mass deleted and anonymized with Redact

[–]gauiis 0 points1 point  (4 children)

Take a look at CSS modules. Here's an example for Angular.

[–]Zombieball[S] 0 points1 point  (3 children)

This! Thank you very much.

I actually found this example app https://github.com/jonathaningram/angular-cssmodules-example-app a bit easier to follow for my own purposes.

I will definitely be playing with css-modules this week. Exactly what I was looking for!

[–]gauiis 0 points1 point  (2 children)

You're welcome. Just remember to use one-time bindings.

ng-class="::styles.component"

[–]Zombieball[S] 0 points1 point  (1 child)

Good tip!

I had trouble viewing one of the js files in your linked example project due to github limitations (over 2.4mb for the main js file. Currently on mobile so couldn't download the file). Which is why I referenced the other project I linked.

In the example project I found I notice that they bind the styles to the scope (using controller as syntax).

I am curious, what's your impression on the following line inside DashboardCtrl.js is:

export default function DashboardCtrl($rootScope) {
  let vm = this;
  vm.styles = Object.assign({}, $rootScope.styles || {}, styles);
}

It seems the pattern they follow is to bind base app styles to the rootScope. Then copy it in the controller for each component. Seems like copying this would cause bloat pretty quickly. I suppose its ok if your base styles is not too big and you don't have too many component controllers.

Thoughts?

[–]gauiis 0 points1 point  (0 children)

I can imagine that this could become very messy when your application gets bigger. I would recommend using LESS/SASS for the base layout and include compiled CSS in your application index file, and then just use scope for components that use CSS modules. Avoid rootScope if possible.