Also see a full web rendering engine (modern HTML + CSS + the whole layout engine) made in pure Python, that can export to PDFs: https://github.com/Kozea/WeasyPrint
They even support a lot of properties that aren't in Gecko/WebKit/Blink, like the @page rules.
My main gripe with CSS is that rules are selectors only. Classes can't compose or inherit (or, if they can, I don't know about it and would welcome a correction).
For example, let's say I use a third-party css library (materializecss, or similar) that provides a class `btn-warning` and `warning-text`, which sets say 10 fields (colors, elevation, etc) on the former and `text-transform` on the latter.
I just want to write one new class that inherits fields from both the existing classes.
I can't specify a new class `my-btn-warning` that inherits all the fields from `btn-warning` and `warning-text`.
I can't create a new class `my-btn-warning` that is composed of `btn-warning` and `warning-text`.
My only option (open to correction) is to copy-and-paste the existing `btn-warning` and `warning-text` fields into my new `my-btn-warning` class.
There's simply no reusability here.
If I want reusability, I need to go outside the spec i.e. have a build step. Not just any build step, but one that exactly matches the upstream library. Which is impossible if there are two upstream libraries, or if my existing build step is different.
This project looks nice but it combines all the disadvantages of writing CSS with all the disadvantages of a build step and adds the extra downside of not being compatible with anyone else's (including mine) build step.
To me, this is the worst of all worlds, with no redeeming advantage at all.
It sounds like you're blaming CSS for the shortcomings of the library you're using.
CSS cascades, embrace it rather than fighting it.
Have a .btn rule that styles all your buttons. Have a .warning one that makes it yellow. Then instead of `<button class="btn-warning">` use `<button class="btn warning">`.
> It sounds like you're blaming CSS for the shortcomings of the library you're using.
...
> Or just use Sass instead!
Maybe I was unclear: my gripe is that this functionality is such a necessary thing to have, that external non-spec third-party tools have to be used to get this functionality.
It is a shortcoming of CSS, because CSS is not providing this functionality that users want.
The fact that everyone is using a third party tool to get this functionality only reinforces my point: if everyone is doing it, then it's a shortcoming.
> Have a .btn rule that styles all your buttons. Have a .warning one that makes it yellow. Then instead of `<button class="btn-warning">` use `<button class="btn warning">`.
I do this, but it ends up being `class="<godawful number of named classes?"` and is prone to breakage when you need to update or modify a theme.
You're composing in the wrong abstration layer, you just use the both classes and if you need any extra stuff you want, then you just create a selector for `.btn-warning.warning-text.my-btn` and as the selector is more specific than the classes that is uses then you can override the functionality it inherits.
After dealing with the current state of affairs regarding the front end, I think this is pretty interesting. I've been writing Go web apps with templ and htmx. I've punted on dealing with CSS using a cdn and bulma. I did get Tailwind and friends working, but it required a lot of work being outside a React/JS framework like next.js. It also felt really weird using npm to install CSS.
The nice thing about this is that you can get a tailwind Go lib to programmatically build into your binary. There are no extra files, one build step, and one binary output. After trying out Fly and Vercel, I went to running things with docker on a VM, and a single binary in a container makes things much simpler IMO.
This looks pretty cool and I look forward to seeing folks do interesting things with it.
I do this too. Using a hot reload server and having live reload in the browser as I'm changing tailwind classes, go files or templ files is a very efficient workflow.
Then for the actual build, everything is built and embedded in a single binary by conditionally using embed with build tags.
I think that live feedback development cycle is probably the most satisfying way to code something by oneself.
It did need quite a bit of messing around with tooling and my Makefiles are pretty big but at least I can reuse that in every new project.
I use the standard library html/template package for generating CSS dynamically, it's got pretty good CSS support. I've found it useful for things like custom themes and UI preferences.
That is essentially what Elm proposes and it works fine.
They even support a lot of properties that aren't in Gecko/WebKit/Blink, like the @page rules.
Even the historic browser vendors with lots of manpower struggle with implementing it and they don't even agree on the implementation details.
Deleted Comment
For example, let's say I use a third-party css library (materializecss, or similar) that provides a class `btn-warning` and `warning-text`, which sets say 10 fields (colors, elevation, etc) on the former and `text-transform` on the latter.
I just want to write one new class that inherits fields from both the existing classes.
I can't specify a new class `my-btn-warning` that inherits all the fields from `btn-warning` and `warning-text`.
I can't create a new class `my-btn-warning` that is composed of `btn-warning` and `warning-text`.
My only option (open to correction) is to copy-and-paste the existing `btn-warning` and `warning-text` fields into my new `my-btn-warning` class.
There's simply no reusability here.
If I want reusability, I need to go outside the spec i.e. have a build step. Not just any build step, but one that exactly matches the upstream library. Which is impossible if there are two upstream libraries, or if my existing build step is different.
This project looks nice but it combines all the disadvantages of writing CSS with all the disadvantages of a build step and adds the extra downside of not being compatible with anyone else's (including mine) build step.
To me, this is the worst of all worlds, with no redeeming advantage at all.
CSS cascades, embrace it rather than fighting it.
Have a .btn rule that styles all your buttons. Have a .warning one that makes it yellow. Then instead of `<button class="btn-warning">` use `<button class="btn warning">`.
Or just use Sass instead!
...
> Or just use Sass instead!
Maybe I was unclear: my gripe is that this functionality is such a necessary thing to have, that external non-spec third-party tools have to be used to get this functionality.
It is a shortcoming of CSS, because CSS is not providing this functionality that users want.
The fact that everyone is using a third party tool to get this functionality only reinforces my point: if everyone is doing it, then it's a shortcoming.
> Have a .btn rule that styles all your buttons. Have a .warning one that makes it yellow. Then instead of `<button class="btn-warning">` use `<button class="btn warning">`.
I do this, but it ends up being `class="<godawful number of named classes?"` and is prone to breakage when you need to update or modify a theme.
Deleted Comment
I want to define a button that inherits from a library like tailwind (define button by using tailwind classes).
You can look at CSS Modules (not supported by browser) which has class inheritance.
(Not a parser, a renderer, a query engine, etc)
The nice thing about this is that you can get a tailwind Go lib to programmatically build into your binary. There are no extra files, one build step, and one binary output. After trying out Fly and Vercel, I went to running things with docker on a VM, and a single binary in a container makes things much simpler IMO.
This looks pretty cool and I look forward to seeing folks do interesting things with it.
Then for the actual build, everything is built and embedded in a single binary by conditionally using embed with build tags.
I think that live feedback development cycle is probably the most satisfying way to code something by oneself.
It did need quite a bit of messing around with tooling and my Makefiles are pretty big but at least I can reuse that in every new project.
And what about "embed with build tags."? I embed every build now.
So I would like to try something like this too. Integration with templ for local CSS components would be nice.
Also agree to the single binary, wrote here https://www.inkmi.com/blog/simplicity-of-golang-systemd-depl... (with systemd instead of a container)
https://dev.to/thormeier/dont-try-this-at-home-css-as-the-ba...