I'm sorry, but there will always be a need for classnames and ids for multiple reasons. A tool like this doesn't remove them from being used, it just partly removes them from the initial code.
Proper usage of CSS preprocessors will result in much the same code that this tool will generate. Because in the end they both generate the same CSS.
That's not really the case. For one, it's incredibly easy to end up with very bloated CSS files if you use something like less/sass. But more importantly, those tools don't give you actual scoping.
Although it's not necessarily the main way the author is suggesting interacting with this library, it can be used as a tool to apply inline styles directly to elements, which gives you total control over the scope of your styles.
If not done properly, anything code-related can result in bloated and inefficient code. I fail to see how introducing Javascript code that requires DOM manipulation is more efficient than a properly built style sheet. Injecting styles inline to elements is an even more inefficient way of doing things, you're likely to cause repaints all over the place during initial rendering.
As I said elsewhere, if this were a system done on the back-end (or even in something like Grunt) so that it was part of a compiling process then it would have merit. But from what I'm seeing this appears to run only on the client side which I feel is a bad idea.
They can be necessary for reasons other than CSS. Trying to do most of them, including CSS, without the usage of classes and ids is just a strange notion.
There are several different ways to handle CSS and each has their own pros and cons. But I'm assuming you're talking inline styles on the HTML elements directly? If so, while useful and I do it myself often, it is not optimum. If you're talking about injecting the styles on or before page load for that particular view, of course you can; but that doesn't mean anything different than what I've been saying at all. In the end it is still CSS and if it doesn't done properly in the beginning it will eventually cause problems.
Not completely. With a virtual DOM based solution (which is where things are trending due to performance), the ids and classnames of HTML become far less relevant.
I agree, but that's tomorrow and in the end that only replaces classnames and ids with something else which will serve pretty much the same purpose. You have to have identifiers of some type, today it is classnames and ids; tomorrow it will be something else.
If you are bad at CSS and good at JS then this tool will not really help you. In the end it generates CSS, which you have to know to some degree to be able to create the JS version of it.
I agree on the complexity issue with the examples, I don't see how the 30% savings claim would hold up.
CSS allows for code reuse, it always has. It's called cascading and classes.
Preprocessors will generate bloated CSS if not coded properly, same as it's possible to hand-code bloated CSS.
There are libraries that generate vendor prefixes at run time. If prefixes are really a bother (they're not as much anymore) then preprocessors and other compiling tools have solutions for that as well. Which will be more efficient for the browser.
2. I know code reuse technics in css, they are mentioned in the presentation. Cascades do not work for component based development. Adding multiple classes to an element leads to awkward code and also will lead to namespace conflicts if you don't name everything very specifically.
3. Vendor prefixes are there and will be used for new features too. They will not go away. Precompilers can't avoid generating all prefixed variants.
The Cascade in CSS can be a real maintenance nightmare, and people seem to have very different ideas on how to handle encapsulation and modularization.
After a while with React, I thought it would be nice to define all styles for a component in the same location (inside my Component JavaScript). Setting the `top` property of a popup in JavaScript, but `width` or whatever in a CSS file just feels weird.
There's been some discussion about making this easier in React[1], but also resistance, so while waiting I wrote my own little library[2] (not React-specific), but it's not as feature rich as JSS.
I think that the fact that many projects[3] like this are popping up is validating the idea.
I'm sorry but I totally fail to see the problem that this is supposedly trying to fix.
In the example provided, the problem is presented as a failure of cascading in CSS. But the problem as I see it, is in the structure of the HTML. The example is a component with a button inside a component with a button. Then global selectors are used which creates a result we don't want.
Slide 11 states global selectors are a problem. Which they can be, if used improperly just like every other tool we have access to.
So, the solution is to write Javascript that results in using classes. Which is what should have been done in the first place.
So, instead of creating a proper class structure in the HTML it is suggested to use Javascript to create classes, inject style sheets into the dom, and inject classes into the HTML elements on page load?
All to avoid using CSS properly?
I'm sure this is a wonderfully coded project, has interesting ideas, and may be useful to some, but as a front-end developer I seriously doubt I would ever use this nor recommend it. I would suggest just learning CSS, it's not that hard.
I would say that this type of project would be far more suited for a back-end library that generates stylesheets on the fly in an effort to maintain code efficiency. But doing all this in Javascript just seems to be about addressing people's attitude towards CSS and not about actual problems in CSS.
How does one properly use classes without making them global? Its either global or tied to your document hierarchy. And tied to a hierarchy is worse because it makes it harder to reuse a class outside that particular hierarchy without modifying the original selector...
You don't. That's the whole point. The reason for classes is to reuse CSS properties for efficiency. If you are making classes that are strictly tied to your hierarchy in a way that prevents proper reuse, then it's being coded the wrong way. Using a tool to fix the improper usage of another tool is not the solution.
If this tool is the solution, that the CSS it generates is the best way to do things, then why not code the CSS that way in the first place?
EDIT: As I'm seeing elsewhere in this thread; why exactly is globals bad in CSS?
Globals make it impossible to reason about separate components in isolation. What classname can I use for this button? Can I use '.button'? What if someone else already uses '.button'? Who knows...
The namespace can be a custom element name, a class or an ID.
The problem with this approach is that you need to declare the namespace in DOM somehow, and depending on the project that can either be easy or rather difficult. I used this technique when I ported a stand-alone application with classes just like ".button" to be a single page in a larger application, and it worked fine.
Anyway, I do think that CSS should have a proper solution to modularization.
EDIT: Now that I could open the link (it didn't open for me previously), I now see that this approach doesn't solve the problem with the article, since it doesn't support nested namespaces. (Although a hacky solution would be a 'reset all rules' helper in the inner namespace).
I have a project now, with multiple developers, that uses this system; we've never had any conflicts in our CSS and I seriously doubt we ever will. It's mostly component driven with the occasional global selector.
As for your example not working with the approach, that's one of the problems as I see it with these solutions. The fancy, complicated approach apparently doesn't support one of the basics of CSS which would go a long way to fixing the problem as they see it.
What if component A and component B need that button? You will comp-a,comp-b{.button{}}? Will you save in comp-a-and-comp-b.scss? What if you need in comp-c and comp-d? As you can see your button is not tight to that comp.
I prefer to have a button class, for example in react that when instanced renders all the time the same. It boundles it's css within, just like this lib.
SASS and LESS are CSS DSLs, you are doing limited programming with CSS, at that stage you may as well do programming in a Turing complete language like JS and reduce the number of tools in your tool chain.
As spion says with web components on the horizon, and with current frameworks like React, having classnames live in the global namespace makes creating reusable components that don't clash with other components impossible.
I have a hunch some consensus will evolve that will use Java/AS3 namespace prefixes to enable sharing, so instead of .button you'll have something like .com-github-dougmartin-button.
Yes, namespacing is the best currently available option. Unfortunately its only an approximation of lexical scope, as the example in the presentation shows (the one with the two red buttons).
True, this is not something that happens often, and we can mostly get away with namespaces. But that's not the point. The point is that lexical scope is a tried and proven (by years of research, in multiple languages) solution to this problem which doesn't have any of these quirks. And JS has lexical scope.
The example with the two buttons is inherently flawed and is a bad example. It specifically creates an easily preventable problem in an effort to show a solution to that problem.
There is nothing that this library can do that I cannot hand-code in CSS myself. Because it has to generate the CSS that the browser expects to get, which is not hard to do.
Yes, namespacing is the best currently available option. Unfortunately its only an approximation of lexical scope, as the example in the presentation shows (the one with the two red buttons).
True, this is not something that happens often, and we can mostly get away with namespaces. But that's not the point. The point is that lexical scope is a tried and proven (by years of research, in multiple languages) solution to this problem which doesn't have any of these quirks. And JS has lexical scope.
Yes, namespacing is the best currently available option. Unfortunately its only an approximation of lexical scope, as the example in the presentation shows (the one with the two red buttons).
True, this is not something that happens often, and we can mostly get away with namespaces. But that's not the point. The point is that lexical scope is a tried and proven (by years of research, in multiple languages) solution to this problem which doesn't have any of these quirks. And JS has lexical scope.
Which is actually quite true, but that problem lies with the person who overwrites the properties. That is not a problem in CSS. The most I would say that the HTML structure and CSS classes was not properly planned out to help prevent such things.
It can be done, it's just most examples of this type of thing is more along the lines of "I want to do it my way!", which is not always a proper way to go about things.
Its definitely not a problem with the person. That person may be working on a, say, date picker component (or something equivalent that is not yet covered with HTLM5) that provides minimal styling (with the ability to override it). They don't even know all their end-users.
They decided to use the name `.calendar`. Was that safe? Nope, their user #3 had an "upcoming events" calendar using the same class name that totally breaks when the datepicker CSS is included on the page. Should they make sure to prefix all their class names with their name? What if someone else with the same name also decides to do this? What if they make a new alternate datepicker, must they add the version number/descriptor too?
This is probably one of the reasons why we don't yet have separate reusable components with minimal overridable styles for the web (instead we have only entire pre-styled frameworks)
If styles had scope and HTML had a way to import them, we could say `import calendar from "path/to/file"`, then use the calendar style on our component and be sure that there is no way its going to leak outside of outside its lexical scope. Web components will fix this (html imports, scoped stylesheets). But web components aren't ready yet.
Let me ask you a different question though: is there a reason for the "oh god, not JS" sentiment? The solution is potentially even simpler than CSS: styles are defined as variables containing JSON objects, they're exported as a module, and can be imported and used by any component and mixed freely. No cascading/selector rules, no priorities, no overrides. When HTML CSS and JS share scope, things become much simpler.
I do have a reason for saying "oh god not JS". In my experience, the biggest reason people try and solve CSS issues with javascript is because they don't fully understand CSS and how to structure it in a maintainable way.
I used to hate CSS. I still think it is very flawed, just google how to center something and watch all the blogs pop up.
But rather than cursing it the rest of my dev days, I took the time to learn it and structure it properly. I now never spend longer than a few minutes trying to resolve a css bug.
Ideas like the OPs only procrastinate someone's true problem, which is they don't know how to properly work with the technology that they are forced to work with.
Your example only shows to me problems in the person and/or the team doing the CSS coding. It is certainly possible to namespace CSS if guidelines are established at project start, just like with coding any other language. What happens if two developers namespace their class in the same way?
The reason I would say no to a JS solution is simply because you are adding yet another step to the render of the page, more code for the browser to parse, and in the end results in the same issues you started with as they are only masked. This is just an attempt to make something work in a fashion it was designed to do. I'd rather fix the problem at the source instead of adding another layer to the problems.
But in the end, no matter what fancy JS code that comes up it still has to render out the CSS exactly as the browser expects it to be. That means that whatever this thing generates, people who know CSS can hand-code the exact same thing. Any problems that exists for CSS exists in this as well, it just masked so it's not readily apparent.
But what if there isn't a single cohesive team developing the website? There are no globally established practices for CSS name-spacing and there are multiple ways to do it (based on what tradeoffs you're willing to make).
See font-awesome for an example of what I mean by library (yes, they prefix everything with `fa-` which is fine until the bootstrap team comes up with a FizzActivity widget in bootstrap, which you wont be able to use together with fontawesome)
What happens if two developers namespace their class in the same way in JS? Well, with CommonJS this is pretty much impossible (import by path), and even without CommonJS there is no incentive to do it as you can easily pick a huge namespace without it affecting anyone. Just adding `var shortName = long.namespace.containing.shortName;` fixes the long name without that short name having effects anywhere else in the code or any of the inner functions (components) you may call, because... lexical scope.
And sure, we can hand-code everything in assembly too - after all thats what compilers do anyway. But that doesn't mean that the higher level language has all the problems that assembly has. A tool like this can do a lot of the job for you, by generating unique names and letting you refer to them via any (variable) name you like.
I don't see the difference between your concern and being concerned with a green developer changing some base class (in java for example) without fully understanding how those changes will affect the rest of the application. You can introduce bugs that a compiler won't catch.
It seems to me your main problem is how do you have people who don't know what they are doing perform like an experienced developer/designer.
So you css will have the same structure as html.. Therefore why not putting your css in your html. Well, in this case you should put the css in the javascript module which renders the html and then the css.
Manually ensuring class names don't clash only scales so far.
The problem this tries to address is the problem of maintainability when the entirety of the codebase doesn't fit in your head (because you have many people committing CSS at a fast pace, or a lot of junior devs, or because the codebase is large, or old, or the deadline is too tight, or any other number of reasons)
There's a world of difference between Facebook with its hundreds of devs commiting code to the same codebase over the span of many years, vs an agency where it's typical for one frontend person to own the entirety of the CSS codebase for a month-long project. In the latter case, you usually don't need the ability to scale the team (or can get away with enforcing ad-hoc processes). In the former case, having tooling that enables non-clashing class names by default is worth the trade-offs.
Creating a more verbose and complicated tool won't solve the problems you describe, they are still there but only masked until it becomes an even bigger problem.
I would be the first to agree that there are problems with CSS, I use it nearly every day and I run into these problems quite a lot. But moving to the JS to attempt to solve these problems is taking several steps backwards to me.
All the problems you list in your example I would say exist as potential problems in any other aspect of a large-scale project. In most of the examples I've seen the problem seems to be giving developers who don't know CSS access to CSS and then wonder why it eventually falls apart.
You can't have proper modules that you just plugin in. I want a button styled a way... it will mix with some other default button. I have to create many button classes.
I admit CSS is a mess, I've never denied it. I simply disagree that a system similar to this approach actually solves anything in the long run.
But you can have proper modules that you just plugin. If you plop in your button and it conflicts with someone else's button; then one of you did it wrong. The solution is to create multiple button classes as you say, but this Javascript solution does the exact same thing.
>but this Javascript solution does the exact same thing.
But with this lib I don't care about classes. I just put thing in, and I have 0 conflicts. I can do whatever I want and no conflicts. Try that in css. Also take a look at react.js this lib is perfect fit for that.
Yup. Pretty much any virtual-dom approach benefits from this type of solution. Furthermore, if you adopt any sort of system on top of the v-dom approach that does layout management with CSS 3D matrices like famo.us does, you end up greatly benefiting from a solution like this as well. Cascading doesn't work really that well if you don't have explicit and persistent semantic nesting all the way down the tree of elements in a window.
The code you write doesn't care about classes, but the CSS that is generated does. Why not do it the CSS way from the beginning and take JS out of the equation altogether so that everything is more efficient?
The most common answer I've seen is "because I don't want to learn CSS", which I don't feel is a good enough answer.
I can write CSS all day using classes that do not conflict in the manner described.
There is another answer pointed out multiple times throughout this thread which is "because name clashes happen if we want to write components in isolation from other teams". Its just that the "writing separate components" part never happens exactly because the infrastructure doesn't support it (except in situations of dire need like fontawesome), so there are "no problems" :)
I'm not claiming this or the vjeux's system (from the presentation link in my other post) are silver bullets, just that they are attempts to solve this specific problem. I'd argue that the reasons presented in vjeux's presentation are not of the clueless-developers-writing-crappy-css variety, although I do concede Facebook-scale problems are not common in the industry.
Personally, I agree that deviating from CSS syntax is not a viable solution for a large number of cases, and neither of those solutions is perfect. I just think it's cool that people are experimenting with different ways of creating collision-resistant styling tools, rather than sticking w/ the status quo.
I think they are interesting as well, but if I see a problem being created in an attempt to address a problem then I say so. I'm sure many of the thoughts and ideas of such projects can be integrated into CSS to make it better, but they will be integrated into CSS. I would propose the author take this system and roll it into Grunt, or similar, where it would be much more useful as opposed to client side. You should see from my other comments on this topic that the majority of my objection is that it is a client-side solution which I think is the wrong approach.
The few past submissions on writing CSS in JS didn't seem to have picked up discussions. I'm glad this one at least does.
I'm gonna go ahead and avoid repeating what's already mentioned in vjeux's presentation (https://speakerdeck.com/vjeux/react-css-in-js). Instead I'll focus on defending against the common "shortfalls" people tend to immediately point out with this approach.
Designers will be uncomfortable with learning this: React's JSX has shown that (surprise surprise) designers can bear modifying markup with a little bit of code mingled in it. In this case, JS objects in their simplest form map very well to css declarations. I don't believe designers will be scared away by this at all.
"Atwood's law", "we already have CSS", "stop reinventing CSS": no one's reinventing the idea of CSS; we're reinventing the implementation of it. Declaratively specify your layout is really nice, but you do want the backing of a real language to do so. Merging two styles is just a `merge()`, Overriding a style is just `bla.color = newColor` (assuming you don't mind the mutation; otherwise clone it or use persistent collections), and (!) reusing, importing, exporting styles is already solved with commonJS since you're working with normal js objects.
We already have preprocessors: except preprocessors are there to solve the exact problem "CSS in JS" is solving. The difference is that the latter, again, uses a real, familiar language instead of inventing an ad-hoc new syntax like we've done countless times with HTML templates. And since preprocessors need to generate the final CSS beforehand, this limits lots of potentials such as looping more than, like, ten times.
On this last point, I hope that none of the critics here used React's virtual DOM before; If you did, and are still complaining about writing CSS in JS, then you should go back and re-learn why the virtual DOM came to be. CSS in JS is the "virtual styling" equivalent for CSS. The potentials are huge (runtime feature detection for example). And this new layer allows us to map the neat, declarative style to something else than CSS: say, webGL. This is platform-independent; if anything, it's a nice conceptual model.
Glad you did! I'm not entirely satisfied with my API but the idea's there, so very cool to see someone make something better out of it.
These kind of things will receive lots of oppositions at first, but once you know the basics are right (e.g. trivial mapping from js obj to css) and build on top of it, this is bound to take off one day like JSX did =).
I don't get JSX, especially now that 0.12 requires you to use createFactory (a big improvement over the old API) to encapsulate all the static JSX parts. With JSX, you're losing all the things that make having a proper programming language useful.
Having first class functions for creating DOM makes it much easier to keep your DOM state creation dry. It's more tedious if you use it just like JSX, but if you recognize where you are repeating yourself over and over again, it's trivially easy to write functions that encapsulate all the repetitive structures in your HTML.
Furthermore, you don't completely break all the tools out there like eslint and whatnot. The h-script blends really nicely with solutions like RCSS and JSS.
Linting has not been an issue for a looong time since you can just lint the output of the transform. And designers love JSX, and having designers feel confident working directly on components saves huge amount of time.
Amazing (: I like the '&:hover': { part. Take a look at rcss https://github.com/chenglou/RCSS
Your lib would be amazing to work with react.js. You would need to create the class names based on the contents instead of incrementing an id to make server side rendering faster. Take a look at rcss on how they do it.
82 comments
[ 5.2 ms ] story [ 192 ms ] threadSharing a single scoping system between JS, HTML and CSS removes the need for global symbols (classnames or ids) to link the two together.
Abstractions in preprocessors are implemented by means of macros, and can lead to large file sizes.
Proper usage of CSS preprocessors will result in much the same code that this tool will generate. Because in the end they both generate the same CSS.
Although it's not necessarily the main way the author is suggesting interacting with this library, it can be used as a tool to apply inline styles directly to elements, which gives you total control over the scope of your styles.
As I said elsewhere, if this were a system done on the back-end (or even in something like Grunt) so that it was part of a compiling process then it would have merit. But from what I'm seeing this appears to run only on the client side which I feel is a bad idea.
However, you're wrong that classnames and ids are always necessary. You can set the HTML "style" attribute directly when generating the view.
There are several different ways to handle CSS and each has their own pros and cons. But I'm assuming you're talking inline styles on the HTML elements directly? If so, while useful and I do it myself often, it is not optimum. If you're talking about injecting the styles on or before page load for that particular view, of course you can; but that doesn't mean anything different than what I've been saying at all. In the end it is still CSS and if it doesn't done properly in the beginning it will eventually cause problems.
It doesn't help that in most of the examples the Javascript implementation is more complex than the css implementation.
I agree on the complexity issue with the examples, I don't see how the 30% savings claim would hold up.
Preprocessors will generate bloated CSS if not coded properly, same as it's possible to hand-code bloated CSS.
There are libraries that generate vendor prefixes at run time. If prefixes are really a bother (they're not as much anymore) then preprocessors and other compiling tools have solutions for that as well. Which will be more efficient for the browser.
2. I know code reuse technics in css, they are mentioned in the presentation. Cascades do not work for component based development. Adding multiple classes to an element leads to awkward code and also will lead to namespace conflicts if you don't name everything very specifically.
3. Vendor prefixes are there and will be used for new features too. They will not go away. Precompilers can't avoid generating all prefixed variants.
The Cascade in CSS can be a real maintenance nightmare, and people seem to have very different ideas on how to handle encapsulation and modularization.
After a while with React, I thought it would be nice to define all styles for a component in the same location (inside my Component JavaScript). Setting the `top` property of a popup in JavaScript, but `width` or whatever in a CSS file just feels weird.
There's been some discussion about making this easier in React[1], but also resistance, so while waiting I wrote my own little library[2] (not React-specific), but it's not as feature rich as JSS.
I think that the fact that many projects[3] like this are popping up is validating the idea.
http://gridstylesheets.org/
If you're going to go to the trouble of writing a CSS processor, you could at least add in some really interesting ideas.
[1] http://blog.codinghorror.com/the-principle-of-least-power/
"This-is-not-what-I-am-used-to" objections notwithstanding, it's certainly an interesting approach to solve some CSS issues.
In the example provided, the problem is presented as a failure of cascading in CSS. But the problem as I see it, is in the structure of the HTML. The example is a component with a button inside a component with a button. Then global selectors are used which creates a result we don't want.
Slide 11 states global selectors are a problem. Which they can be, if used improperly just like every other tool we have access to.
So, the solution is to write Javascript that results in using classes. Which is what should have been done in the first place.
So, instead of creating a proper class structure in the HTML it is suggested to use Javascript to create classes, inject style sheets into the dom, and inject classes into the HTML elements on page load?
All to avoid using CSS properly?
I'm sure this is a wonderfully coded project, has interesting ideas, and may be useful to some, but as a front-end developer I seriously doubt I would ever use this nor recommend it. I would suggest just learning CSS, it's not that hard.
I would say that this type of project would be far more suited for a back-end library that generates stylesheets on the fly in an effort to maintain code efficiency. But doing all this in Javascript just seems to be about addressing people's attitude towards CSS and not about actual problems in CSS.
If this tool is the solution, that the CSS it generates is the best way to do things, then why not code the CSS that way in the first place?
EDIT: As I'm seeing elsewhere in this thread; why exactly is globals bad in CSS?
e.g.
The namespace can be a custom element name, a class or an ID.The problem with this approach is that you need to declare the namespace in DOM somehow, and depending on the project that can either be easy or rather difficult. I used this technique when I ported a stand-alone application with classes just like ".button" to be a single page in a larger application, and it worked fine.
Anyway, I do think that CSS should have a proper solution to modularization.
EDIT: Now that I could open the link (it didn't open for me previously), I now see that this approach doesn't solve the problem with the article, since it doesn't support nested namespaces. (Although a hacky solution would be a 'reset all rules' helper in the inner namespace).
As for your example not working with the approach, that's one of the problems as I see it with these solutions. The fancy, complicated approach apparently doesn't support one of the basics of CSS which would go a long way to fixing the problem as they see it.
I prefer to have a button class, for example in react that when instanced renders all the time the same. It boundles it's css within, just like this lib.
http://lesscss.org/features/#features-overview-feature-names...
I haven't personally used it, though.
Another solution would be have a "button.less" like this:
I have a hunch some consensus will evolve that will use Java/AS3 namespace prefixes to enable sharing, so instead of .button you'll have something like .com-github-dougmartin-button.
True, this is not something that happens often, and we can mostly get away with namespaces. But that's not the point. The point is that lexical scope is a tried and proven (by years of research, in multiple languages) solution to this problem which doesn't have any of these quirks. And JS has lexical scope.
There is nothing that this library can do that I cannot hand-code in CSS myself. Because it has to generate the CSS that the browser expects to get, which is not hard to do.
True, this is not something that happens often, and we can mostly get away with namespaces. But that's not the point. The point is that lexical scope is a tried and proven (by years of research, in multiple languages) solution to this problem which doesn't have any of these quirks. And JS has lexical scope.
True, this is not something that happens often, and we can mostly get away with namespaces. But that's not the point. The point is that lexical scope is a tried and proven (by years of research, in multiple languages) solution to this problem which doesn't have any of these quirks. And JS has lexical scope.
.default-button(){ // properties }
.component-a button { background-color: red; }
.component-b button { .default-button(); color: green; }
It can be done, it's just most examples of this type of thing is more along the lines of "I want to do it my way!", which is not always a proper way to go about things.
They decided to use the name `.calendar`. Was that safe? Nope, their user #3 had an "upcoming events" calendar using the same class name that totally breaks when the datepicker CSS is included on the page. Should they make sure to prefix all their class names with their name? What if someone else with the same name also decides to do this? What if they make a new alternate datepicker, must they add the version number/descriptor too?
This is probably one of the reasons why we don't yet have separate reusable components with minimal overridable styles for the web (instead we have only entire pre-styled frameworks)
If styles had scope and HTML had a way to import them, we could say `import calendar from "path/to/file"`, then use the calendar style on our component and be sure that there is no way its going to leak outside of outside its lexical scope. Web components will fix this (html imports, scoped stylesheets). But web components aren't ready yet.
Let me ask you a different question though: is there a reason for the "oh god, not JS" sentiment? The solution is potentially even simpler than CSS: styles are defined as variables containing JSON objects, they're exported as a module, and can be imported and used by any component and mixed freely. No cascading/selector rules, no priorities, no overrides. When HTML CSS and JS share scope, things become much simpler.
I used to hate CSS. I still think it is very flawed, just google how to center something and watch all the blogs pop up.
But rather than cursing it the rest of my dev days, I took the time to learn it and structure it properly. I now never spend longer than a few minutes trying to resolve a css bug.
Ideas like the OPs only procrastinate someone's true problem, which is they don't know how to properly work with the technology that they are forced to work with.
The reason I would say no to a JS solution is simply because you are adding yet another step to the render of the page, more code for the browser to parse, and in the end results in the same issues you started with as they are only masked. This is just an attempt to make something work in a fashion it was designed to do. I'd rather fix the problem at the source instead of adding another layer to the problems.
But in the end, no matter what fancy JS code that comes up it still has to render out the CSS exactly as the browser expects it to be. That means that whatever this thing generates, people who know CSS can hand-code the exact same thing. Any problems that exists for CSS exists in this as well, it just masked so it's not readily apparent.
See font-awesome for an example of what I mean by library (yes, they prefix everything with `fa-` which is fine until the bootstrap team comes up with a FizzActivity widget in bootstrap, which you wont be able to use together with fontawesome)
What happens if two developers namespace their class in the same way in JS? Well, with CommonJS this is pretty much impossible (import by path), and even without CommonJS there is no incentive to do it as you can easily pick a huge namespace without it affecting anyone. Just adding `var shortName = long.namespace.containing.shortName;` fixes the long name without that short name having effects anywhere else in the code or any of the inner functions (components) you may call, because... lexical scope.
And sure, we can hand-code everything in assembly too - after all thats what compilers do anyway. But that doesn't mean that the higher level language has all the problems that assembly has. A tool like this can do a lot of the job for you, by generating unique names and letting you refer to them via any (variable) name you like.
It seems to me your main problem is how do you have people who don't know what they are doing perform like an experienced developer/designer.
Example 1:
<div class="component-a"><button></button><div class="component-b"><button></button></div></div>
Example 2:
<div class="component-b"><button></button></div>
Result:
The <button> wrapped in div.component-b for both above examples will render exactly the same, ignoring html structure.
The problem this tries to address is the problem of maintainability when the entirety of the codebase doesn't fit in your head (because you have many people committing CSS at a fast pace, or a lot of junior devs, or because the codebase is large, or old, or the deadline is too tight, or any other number of reasons)
There's a world of difference between Facebook with its hundreds of devs commiting code to the same codebase over the span of many years, vs an agency where it's typical for one frontend person to own the entirety of the CSS codebase for a month-long project. In the latter case, you usually don't need the ability to scale the team (or can get away with enforcing ad-hoc processes). In the former case, having tooling that enables non-clashing class names by default is worth the trade-offs.
I would be the first to agree that there are problems with CSS, I use it nearly every day and I run into these problems quite a lot. But moving to the JS to attempt to solve these problems is taking several steps backwards to me.
All the problems you list in your example I would say exist as potential problems in any other aspect of a large-scale project. In most of the examples I've seen the problem seems to be giving developers who don't know CSS access to CSS and then wonder why it eventually falls apart.
Scoped CSS[1] would have been a good start, but unfortunately it looks to be in trouble (removed from Chrome).[2]
[1] https://html.spec.whatwg.org/multipage/semantics.html#attr-s... [2] https://www.chromestatus.com/features/5374137958662144
You can't have proper modules that you just plugin in. I want a button styled a way... it will mix with some other default button. I have to create many button classes.
But you can have proper modules that you just plugin. If you plop in your button and it conflicts with someone else's button; then one of you did it wrong. The solution is to create multiple button classes as you say, but this Javascript solution does the exact same thing.
But with this lib I don't care about classes. I just put thing in, and I have 0 conflicts. I can do whatever I want and no conflicts. Try that in css. Also take a look at react.js this lib is perfect fit for that.
The most common answer I've seen is "because I don't want to learn CSS", which I don't feel is a good enough answer.
I can write CSS all day using classes that do not conflict in the manner described.
Personally, I agree that deviating from CSS syntax is not a viable solution for a large number of cases, and neither of those solutions is perfect. I just think it's cool that people are experimenting with different ways of creating collision-resistant styling tools, rather than sticking w/ the status quo.
LESS is Javascript but with certain limitations. If you don't like it, write your own. Or better yet, contribute.
I'm gonna go ahead and avoid repeating what's already mentioned in vjeux's presentation (https://speakerdeck.com/vjeux/react-css-in-js). Instead I'll focus on defending against the common "shortfalls" people tend to immediately point out with this approach.
Designers will be uncomfortable with learning this: React's JSX has shown that (surprise surprise) designers can bear modifying markup with a little bit of code mingled in it. In this case, JS objects in their simplest form map very well to css declarations. I don't believe designers will be scared away by this at all.
"Atwood's law", "we already have CSS", "stop reinventing CSS": no one's reinventing the idea of CSS; we're reinventing the implementation of it. Declaratively specify your layout is really nice, but you do want the backing of a real language to do so. Merging two styles is just a `merge()`, Overriding a style is just `bla.color = newColor` (assuming you don't mind the mutation; otherwise clone it or use persistent collections), and (!) reusing, importing, exporting styles is already solved with commonJS since you're working with normal js objects.
We already have preprocessors: except preprocessors are there to solve the exact problem "CSS in JS" is solving. The difference is that the latter, again, uses a real, familiar language instead of inventing an ad-hoc new syntax like we've done countless times with HTML templates. And since preprocessors need to generate the final CSS beforehand, this limits lots of potentials such as looping more than, like, ten times.
On this last point, I hope that none of the critics here used React's virtual DOM before; If you did, and are still complaining about writing CSS in JS, then you should go back and re-learn why the virtual DOM came to be. CSS in JS is the "virtual styling" equivalent for CSS. The potentials are huge (runtime feature detection for example). And this new layer allows us to map the neat, declarative style to something else than CSS: say, webGL. This is platform-independent; if anything, it's a nice conceptual model.
(Disclaimer: I made https://github.com/chenglou/RCSS)
Some people here assume that I am stupid and didn't learn the css basics. This is just funny.
These kind of things will receive lots of oppositions at first, but once you know the basics are right (e.g. trivial mapping from js obj to css) and build on top of it, this is bound to take off one day like JSX did =).
Have you given react-hyperscript a chance? https://github.com/mlmorg/react-hyperscript
Having first class functions for creating DOM makes it much easier to keep your DOM state creation dry. It's more tedious if you use it just like JSX, but if you recognize where you are repeating yourself over and over again, it's trivially easy to write functions that encapsulate all the repetitive structures in your HTML.
Furthermore, you don't completely break all the tools out there like eslint and whatnot. The h-script blends really nicely with solutions like RCSS and JSS.