-
Notifications
You must be signed in to change notification settings - Fork 240
Description
I want to use tailwind for CSS with cargo-leptos and i hit an issue with the generated CSS.
I first thought it is a cargo-leptos issue so I filed this ticket: leptos-rs/cargo-leptos#599
Anyway, I will repeat the important things here again, so you don't have to read two tickets!
setup
- Started with https://github.com/leptos-rs/cargo-leptos?tab=readme-ov-file#features from a https://github.com/leptos-rs/start-axum-workspace
- by default this uses sass and i updated the Cargo.toml with:
# The tailwind input file.
#
# Optional, Activates the tailwind build
tailwind-input-file = "style/style.css"
# The tailwind config file.
#
# Optional, defaults to "tailwind.config.js" which if is not present
# is generated for you
tailwind-config-file = "tailwind.config.js"The files like style/style.css and tailwind.config.js are in place and valid and I can run the tailwindcss command by hand without any issues.
style/style.css
@tailwind base;
@tailwind components;
@tailwind utilities;
/* https://stackoverflow.com/questions/5110833/css-how-to-print-a-table-with-background-color-without-print-settings-changes */
body{
-webkit-print-color-adjust:exact !important;
print-color-adjust:exact !important;
}tailwind.config.js
const colors = require("tailwindcss/colors");
const homedir = require("os").homedir();
const path = require("path");
module.exports = {
content: ["./frontend/src/**/*.rs"],
plugins: [
require("@tailwindcss/forms"),
require("@tailwindcss/typography"),
require("@tailwindplus/elements"),
],
theme: {
},
};The command is:
tailwindcss --input style/style.css --config tailwind.config.js --output /home/nixos/planicus/target/tmp/tailwind.css
This is usually executed by cargo-leptos automatically.
using cargo leptos serve
now i want to develop with this setup and so i call a trunk like software:
cargo leptos serve- it calls various things and then
tailwindcss --input style/style.css --config tailwind.config.js --output /home/nixos/planicus/target/tmp/tailwind.css - after tailwindcss has finished, cargo-leptos reads /home/nixos/planicus/target/tmp/tailwind.css and puts it into the
StyleSheet::parse(&source, ParserOptions::default()).unwrap();to later minify it.
But it turns out that lightningcss fails with parsing the css in test_tailwind_css, I've extended tests/test_custom_parser.rs, see below:
I assume this is valid CSS as it is produced by the tailwind binary I also used with trunk before I tried to convert my code-base to cargo-leptos with SSR.
generated tailwind.css
Here is some lines from the generated tailwind.css file:
.filter {
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.transition {
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
.\[--anchor-gap\:--spacing\(3\)\] {
--anchor-gap: var(--spacing(3));
}
.\[appearance\:textfield\] {
-webkit-appearance: textfield;
-moz-appearance: textfield;
appearance: textfield;
}
/* https://stackoverflow.com/questions/5110833/css-how-to-print-a-table-with-background-color-without-print-settings-changes */
body{
-webkit-print-color-adjust:exact !important;
print-color-adjust:exact !important;
}
.time-grid {
display: grid;
grid-template-columns: 60px repeat(7, 1fr);
grid-template-rows: 40px repeat(15, 60px);
/* header + 15 hours */
}test to reproduce it
fn test_parse(source: &str) {
let mut stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
assert_eq!(1,2);
}
#[test]
fn test_tailwind_css() {
test_parse(
r#"
.\[--anchor-gap\:--spacing\(3\)\] {
--anchor-gap: var(--spacing(3));
}
"#
)
}test test_tailwind_css ... FAILED
failures:
---- test_tailwind_css stdout ----
thread 'test_tailwind_css' panicked at tests/test_custom_parser.rs:12:77:
called `Result::unwrap()` on an `Err` value: Error { kind: UnexpectedToken(Function("--spacing")), loc: Some(ErrorLocation { filename: "", line: 2, column: 25 }) }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
test_tailwind_css
test result: FAILED. 2 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
related
cargo-leptos vs. trunk
it seems that both projects are using lightningcss:
cargo-leptos: lightningcss = { version = "1.0.0-alpha.67", features = ["browserslist"] }
trunk: lightningcss = "=1.0.0-alpha.65" (this is used by minify-html = "0.15.0")
after some trunk source code reading this was discovered:
- trunk src/pipelines/mod.rs calls src/processing/minify.rs for minimizing the css in
minify_css(bytes: Vec<u8>) -> Vec<u8>returns the bytes uncompressed if compression failed or compressed. there is a warning and i have to check if there was a warning printed somewhere.
seems trunk executed the minify_css successfully as https://planicus.eu/style-3798f67b665eb67.css is minified and it contains the gap\:--spacing\(3\)\] sequence.
a plausible explanation is this:
Running trunk serve -v --release in the old setup would let tailwindcss do the:
tailwindcss args args=["--input", "/home/nixos/planicus_wip/src/style.css", "--output", "/home/nixos/planicus_wip/dist/.stage/style.css", "--minify"]
gpt4 says
This is valid in Tailwind CSS (for arbitrary properties/selectors), but not normal/valid CSS syntax. Here, you're encoding the actual property name and its value (--anchor-gap: --spacing(3)) into the selector using backslash escapes.
Why the Error Occurs
lightningcss's parser expects a valid CSS selector, where class names are "normal" identifiers, possibly allowing some escaping.
Tailwind's arbitrary selectors use a syntax (like .\[--anchor-gap\:--spacing\(3\)\]) that pushes the boundaries of CSS parsing.
When parsing, lightningcss encounters --spacing(3) inside the class selector, and interprets this as a "function token" instead of part of a (strange) class name.