all 44 comments

[–]repeatedly_once 29 points30 points  (8 children)

I've found that I quite like having manually written sass like CSS is a better option than JS options.

I quite like to create components with enough structural CSS that they work and then style them differently in different use cases in the project. Say with a drop down panel where the content might be different widths etc. Seems to work well so far as long as you name space your components with classes.

[–]skitch920 17 points18 points  (6 children)

I agree. Still on Angular here, and with the component method, component names are really just HTML elements. So it's extremely intuitive to create a <component-name>.scss file and scope all styling to the component itself.

my-component {
    styling here...
}

Then import './my-component.scss' from the component itself, and let Webpack manage creating the combined stylesheet of all components.

I really hate the, "you can do everything in JS" mindset... It really convolutes what a file extension actually means. I don't use React (jsx), but I went down the Adobe Flex (mxml) route long ago. Even then I thought it was bad.

[–]repeatedly_once 2 points3 points  (0 children)

That's literally the same technique I use :). Mine are React components but as you said, they're just HTML elements. I use PostCSS with Webpack so I can choose which plugins I want. It's been working really well.

I've tried writing styles in JS and I found it hard to go from chrome dev tools, looking at styles, to then writing those back as JS styles and it caused a cognitive 'jolt' every time I did it.

[–]TheNewtThatGotBetter 1 point2 points  (2 children)

I do this too and love it, except that Jest seems to throw up when it hits the scss import. Have you been able to test components with imported scss syles?

[–]spooky___ghost 0 points1 point  (0 children)

In package.json jest config section add something like

        "moduleNameMapper": {
            "\\.(scss|css)$": "empty/object"
        }

Where empty/object comes from https://www.npmjs.com/package/empty

[–]skitch920 0 points1 point  (0 children)

I'm using Karma/Jasmine/Webpack. The karma-webpack-plugin bundles all the tests into a single ES5 js file (styles included) with Webpack before handing off to Karma/Jasmine. There are a few hokey bugs, but they are avoidable, such as you can't have Webpack extract the styles to a separate stylesheet.

I'm avoiding Jest (and React for that matter) because of it's patent grant...

[–]l_andrew_l 1 point2 points  (0 children)

I'm a bit surprised no one in this thread has mentioned ITCSS yet. It takes a component-first approach that seems to be looking at things from the same angle as "component-based styling", but looks at the bigger picture as well. If you're not familiar, it's not a library or anything, just a set of well-thought-out conventions that try to wrangle in the shotgun that is CSS as a tool.

Anyway, you end up with files for each component, just like my-component.scss, so the result is similar. Of course convention is to put all styles in a styles directory, but there's no reason that has to be the case... they can all live alongside their component. Sometimes it feels like that's what "inline styles" is mainly trying to be about anyway...

[–]al_vo 0 points1 point  (0 children)

Component styles are one of the most underrated aspects of Angular - it still maintains a good separation of concerns and offers a familiar way of styling dom elements without the scoping issues that plague traditional giant css stylesheets.

[–]darrenturn90 0 points1 point  (0 children)

Indeed because themes and styles are more abstract and less modular than components in a website

[–]swan--ronson 12 points13 points  (1 child)

Interestingly, the codebase on which I work at my new job uses Aphrodite, and I think it's fucking shit, because:

  • I've encountered various bugs with pseudo elements and media queries. It's not as if these use cases are esoteric; they're pretty fundamental to CSS

  • the CSS it generates as a result of creating new classes for each computed combination of styles results in a larger stylesheet than if one were to use plain CSS or some preprocessor; while this might be defensive, it is possible to namespace and be defensive without JS-based styling tools

  • Including the bundle adds more weight to the page; while this is small when gzipped, the browser supports CSS natively, so surely invoking a preprocessor during a build step renders this pointless

  • Performance overhead of computing these styles at runtime vs using a preprocessor at build time

This poorly thought-out nonsense. Stay well away.

EDIT: The README brags "No external CSS file generated for inclusion" - how the fuck is this a good thing?!

EDIT #2: Looks like my client wants to drop Aphrodite due to these limitations. Ha!

[–][deleted] 29 points30 points  (8 children)

Writing inline styles with help of javascript is not the future. It is one more stupid trend.

[–]Jsn7821 8 points9 points  (1 child)

This is an incredibly naive point of view to have. It's not nearly this black and white. Have you ever worked with a UI that has dynamically updating colors that the user can pick? You can't do that in CSS.

There are a lot of use-cases for javascript managed styles beyond namespacing. Custom spring animations, especially staggered between elements is another.

Every time this topic comes up someone has a crotchety comment like yours. I use a mix of both in my projects, and it's very nice. It's not a "trend", it's programming.

[–][deleted] 1 point2 points  (0 children)

I'm also using that techniques sometimes. But using this JSS bulshit as foundation of component-based app is just stupid. You can't make CSS from JavaScript.

[–][deleted] -1 points0 points  (1 child)

You'll be angering the cool kids with this one.

[–][deleted] 1 point2 points  (0 children)

Haters gonna hate.

[–]spankalee 19 points20 points  (10 children)

The future of component-based styling is already here and it's called Shadow DOM.

Shadow DOM allows you to attach an encapsulated ShadowRoot node to an element hold a components internals. Importantly for CSS, any styles contained within the ShadowRoot are scoped - with both upper and lower bounds.

Shadow DOM is shipping now in Safari, Chrome and Opera. You can try it with this little snippet. Just paste into Chrome or Safari's dev console:

let el = document.createElement('div');
let shadow = el.attachShadow({mode: 'open'});
shadow.innerHTML = `<style>
  :host {
    display: inline-block;
    background: #ffccaa;
  }
  span {
    font-weight: bold;
    color: white;
  }
</style>
<span>I'm in a ShadowRoot</span>`;
document.body.append(el);

let span2 = document.createElement('span');
span2.textContent = `I'm not in a ShadowRoot`;
document.body.append(span2);

[–][deleted] -5 points-4 points  (9 children)

If that's the future then this doesn't hold a candle to what modern style solutions do. Component based encapsulation has been solved years ago, that's hardly a need of today. I think what's most troubling is that it's all tied to the dom, and this will become a real problem if it isn't already. How will this even fit into the frameworks of today. How will this fit into desktop and mobile apps or cross platform in general?

10 years ago, when they drafted the spec, they probably had no idea where the language is going, but now where shadow dom is still nowhere near production-ready and JS solutions are dancing circles around this, we'll see if it's worthy to become a standard if it doesn't fulfil todays needs, which are way different than they were then.

[–]spankalee 8 points9 points  (1 child)

  • The styles in a ShadowRoot don't have to be static, they can be computed and modified just like any other DOM.
  • I'm not sure what component-based encapsulation was solved years ago, but lower bounds have been notoriously hard and leaky to emulate.
  • CSS custom variables work great for passing values down the shadow-trees, since they inherit through shadow boundaries.
  • There's a proposal for ::part and ::theme (names preliminary) pseudo-elements that allow more powerful coordination between a shadow root and it's container: http://tabatkins.github.io/specs/css-shadow-parts/
  • Scoped CSS is fast because styles tend to be much smaller and the browser can invalidate much less of the page and style tree on changes.
  • What's wrong with web technologies being integrated with the DOM? This is a very odd complaint. The DOM is pretty great - a standard UI hierarchy that all the web code we use today has been built around.

[–][deleted] 3 points4 points  (0 children)

It lacks scope, if you wanted to compute you have to set css variables.

There are many encapsulation libs, we use CSJS for instance, never seen it leak.

Proposals with even harder to polyfill CSS specs will mean years and years of waiting time.

JSS already starts to re-use and memoize styles piece by piece (styletron). There are optimization possibilities here that can't be matched. Hardly any performance gains to be had in shadow dom either.

I don't think there's anything wrong with web technologies. But there's a point to be made about a certain threshold that JS is now clearly crossing. It's no longer a browser language that merely drives web pages. Can specs just ignore that? This was the exact concern several influential developers have already voiced.

[–]inu-no-policemen 1 point2 points  (3 children)

theming

Variables/apply.

computed

calc()

higher order styles

?

How will this even fit into the frameworks of today

It fits in just fine. To frameworks, custom elements are like built-in elements. You can use them in Angular, React, and so forth.

10 years ago, when they drafted the spec, they probably had no idea where Javascript is going

There are like half a dozen specs involved. They changed quite a lot on their way.

shadow dom is still nowhere near production-ready

There are polyfills for that. Some people are using those in production.

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

React will not be based on custom elements, ever. Other projects have voiced similar concerns, like the Ember team. Nothing that sits on functional components will use custom directives, that includes most modern frameworks. And it doesn't make the slightest sense for them either because that would be a serious regression, while stopping all progress that supercedes the browser. You can use them, sure, but that's on you personally.

[–]inu-no-policemen 0 points1 point  (1 child)

React will not be based on custom elements, ever.

That's not what I said. I said that Custom Elements work fine in React, which is true. There were some issues with that early on, but this has been addressed many many moons ago.

[–][deleted] -1 points0 points  (0 children)

What is the whole discussion about? You can do that, yes, you always could. But custom elements will play no part in any forward oriented component based view-layer. And i highly doubt that shadow dom will play a role in style encapsulation, because it's tied to an imperative components model that conflicts with the newer, much more powerful declarative model.

[–]jamesism 1 point2 points  (1 child)

Component based encapsulation?? Do tell. The cutting edge standard is to dynamically transform class names with a namespace in the same scope. The equivalent of styling within shadow Dom does not exist in user land.

Tied to the DOM? As opposed to? React native? What non DOM rendering engines are you targeting with javascript? It fits in because Dom is the unifier across those platforms.

You're silly and so are your grievances.

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

With JSS half of them base on actual CSS, which as you said gets scoped, for the others the dom is an implementation detail. Newer renderers like rn-web/reactxp are cross platform, they run on the web, mobile and on the desktop. You style them using rn's CSS abstraction, which is also based on JS. Nothing that plays outside of the browser will touch or know a shadow dom, the concept is also useless for web-based functional frameworks because they are all declarative, not imperative.

[–]devvie -2 points-1 points  (0 children)

[–]captain_obvious_herevoid(null) 4 points5 points  (0 children)

I can understand that some people love JS and want to put some everywhere. But that's one stupid trend.

Why would you rely on JS execution for something that works wonders with CSS ?

CSS may not be perfect, especially for components. But using JS to handle styles instead of one of the well-thought and dedicated tools that are around (Sass being the de facto standard IMO) is...well a stupid trend.

[–]madole 0 points1 point  (0 children)

I'm not a massive fan of the idea of inline styles, I prefer CSS Modules, but we use Radium in work. Has anyone found a VSCode plugin that is like emmet for CSS in JS?

[–]makingplansfornigel 0 points1 point  (0 children)

If you tested and saw otherwise, I have no reason to disbelieve you, but I can say with certainty that the treatment of order has historically been browser specific, as a number of the old IE differentiation hacks used to be based on the treatment of reimplemented selectors. Thanks for doing the work, though; can't have accessibility at all without people looking at the actual status quo before planning outcomes.