svelte: CSS container queries "@container" breaks parser

Describe the bug

With CSS container queries on the way I wanted to flag this early

Currently using @container throws “RightParenthesis is expected”

Reproduction

https://svelte.dev/repl/c660c23146364ec3910534a89363801b?version=3

Logs

[!] (plugin svelte) ParseError: RightParenthesis is expected
src\views\album.svelte
156:     }
157:
158:     @container (min-width: 400px) {
                              ^
159:         .details {
160:             outline: 3px solid lime;
ParseError: RightParenthesis is expected
    at error (C:\git-projects\ample\node_modules\svelte\src\compiler\utils\error.ts:25:16)
    at Parser$1.error (C:\git-projects\ample\node_modules\svelte\src\compiler\parse\index.ts:101:3)
    at Object.read_style [as read] (C:\git-projects\ample\node_modules\svelte\src\compiler\parse\read\style.ts:31:11)
    at tag (C:\git-projects\ample\node_modules\svelte\src\compiler\parse\state\tag.ts:189:27)
    at new Parser$1 (C:\git-projects\ample\node_modules\svelte\src\compiler\parse\index.ts:53:12)
    at parse (C:\git-projects\ample\node_modules\svelte\src\compiler\parse\index.ts:218:17)
    at compile (C:\git-projects\ample\node_modules\svelte\src\compiler\compile\index.ts:93:14)
    at Object.transform (C:\git-projects\ample\node_modules\rollup-plugin-svelte\index.js:111:21)
    at ModuleLoader.addModuleSource (C:\git-projects\ample\node_modules\rollup\dist\shared\rollup.js:19504:30)
    at ModuleLoader.fetchModule (C:\git-projects\ample\node_modules\rollup\dist\shared\rollup.js:19560:9)

System Info

System:
    OS: Windows 10 10.0.19042
    CPU: (8) x64 AMD Ryzen 7 3700X 8-Core Processor
    Memory: 9.25 GB / 16.00 GB
  Binaries:
    Node: 14.13.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.5 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
    npm: 6.14.8 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Spartan (44.19041.1266.0), Chromium (96.0.1054.34)
    Internet Explorer: 11.0.19041.1202
  npmPackages:
    rollup: ^2.52.3 => 2.52.3
    svelte: ^3.42.5 => 3.42.5

Severity

annoyance

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 14
  • Comments: 28 (15 by maintainers)

Commits related to this issue

Most upvoted comments

An update on the PR. Given the follow on discussion in the PR I have added single value CSS function support to the associated PR supporting the usage of calc, clamp, min, max in container queries. This allows you to write query rules like:

@container test-container (calc(400px + 1px) <= width < calc(500px + 1px)) {}

As described above you can test out this functionality now as I have a temporary fork of Svelte w/ this PR available with this NPM package. You can load it in a Svelte project with the following in package.json:

"overrides": {
   "svelte": "npm:@typhonjs-svelte/svelte@3.55.1-cq2"
},

Waiting on Svelte maintainers for review / merge.

any update on this? Would be nice to utilize @container in sveltekit now that it is production ready

The maintainer of css-tree is working on at-rule / queries updates currently. It is a bigger refactor including query range support for media queries and a few other things I imagine besides just container query support. There is a branch of css-tree / queries where the work is being done w/ last commit ~4 days ago.

I’ve already offered lending a hand for any testing or anything else that could help in the related css-tree issue, but haven’t heard anything, so it’s a bit of a waiting game.

I gather the core Svelte maintainers, can’t speak for them, will want to wait for the css-tree official mainline update as it should be a simple version bump and minor one line change to support things in svelte.

Container queries are amazing and really help making compound / complex components. I’ve developed a very advanced color picker w/ my CQ Svelte fork.

Hi @benmccann / @tanhauhau

I’d like to continue discussion on a solution that I have just implemented for container query (CQ) support that I believe will be palatable to Svelte maintainers. The last correspondence from Roman Dvornov was December 5th in the linked css-tree issue filed. The queries branch where presumably official container query support is being added to css-tree has stalled at December 15th. Chrome has had support since ~August '22 and Firefox 110 is releasing on Feb 14th w/ CQ support. At this time further waiting for css-tree to catch up is entering what I consider not ideal timing.

I made a hard fork of css-tree and implemented CQ support early December and verified that it is trivial to enable support in svelte. It is not of course ideal to depend on my hard fork. However, I just implemented css-tree extension through the mechanism brought up by Roman in this post: https://github.com/csstree/csstree/issues/174#issuecomment-1337001937. I was able to take the css-tree node extensions from my hard fork and implement them directly in the svelte repo using the css-tree fork capability. My CQ implementation does full parsing and verification of @container prelude and is 100% working and tested in non-trivial CQ usage in my separate UI framework. I have not added tests yet to svelte, but would like either of you to be involved in a code review.

Changes

src/compiler/parse/read/style.ts: Switch to locally forked css-tree w/ CQ support.

src/compiler/parse/read/css-tree-cq/css_tree_parse.ts: fork css-tree w/ local extension.

src/compiler/parse/read/css-tree-cq/node: css-tree new CQ nodes.

src/compiler/compile/css/Stylesheet.ts: Trivial one line change to enable CQ support in Svelte.

You can view a diff of my changes here: https://github.com/sveltejs/svelte/compare/master...typhonjs-svelte:svelte:master

Impact

No downsides that I’m aware of regarding these changes. Simply that Svelte can now ship 3.56.0 w/ CQ support. I have thoroughly tested the code and would be glad to add specific tests to the svelte repo. I updated to the latest css-tree version 2.3.1. Because I’m using the fork capability of css-tree to extend it the css-tree version can keep being bumped if new versions come out without CQ support. However, when CQ support is added my local extensions can be removed and an easy swap back to the official css-tree parse capability is trivial.

On my side I’m releasing the next version of my UI framework imminently and there is non-trivial CQ usage for a complex color picker component. It would really be great to have a version of Svelte out that supports CQ.

As indicated above the PR is in and waiting on review + merge. #8275.

Yet another minor update… The PR is up to date w/ mainline Svelte as of this message. A new external version of Svelte ~3.56.0~ now 3.57.0 w/ the container query PR applied is available here with this NPM Package. You can load it in a Svelte project with the following in package.json:

"overrides": {
   "svelte": "npm:@typhonjs-svelte/svelte@3.57.0-cq"
},

Still waiting on Svelte maintainers to take a look.

Awesome… Re: two confirmations above. I’m working on a PR later today to hopefully get this mainlined! 😄

I have written a first pass at adding container queries to csstree and have verified that things easily can be enabled in Svelte with a single line modification once support is officially released in csstree. I’m going to work w/ the csstree maintainer and try and get this going ASAP as it’s blocking my Svelte UI framework development.

You can see my extensive comment detailing the parser support I’ve added to my csstree fork here: https://github.com/csstree/csstree/issues/174#issuecomment-1328320710


I have a temporary release of a fork of Svelte 3.53.1 w/ container query support that you can install as a dependency in package.json as follows: "svelte": "github:typhonjs-svelte/svelte#3.53.1-cq"

Hopefully I’ll be able to reach the maintainer of csstree in a timely manner to finish off mainline support, but otherwise I’ll publish my Svelte fork on NPM in the coming couple of weeks and keep it updated w/ the mainline Svelte releases until csstree can be updated.

That’s an option, for sure. I’d definitely miss the idea of co-locating the CQ with the Svelte file in question though.

I’ve been playing around with this pattern: https://svelte.dev/repl/1a52f9bfad9c41729338200a5d552ef2?version=3.46.6. It works well, but is jumping through hoops just because the CSS can’t be parsed, which is frustrating! But super cool to have CQs working in a component with a simple action.

Thanks @mitchray, @rob-balfre, and @finnhvman for the nod! I’m certainly excited to now ship some advanced CQ components. IMHO it is a massive game changer for responsive component design.

Even better, now that the CQ PR is merged and I can rely on the Svelte maintainers being OK w/ how the solution is implemented I was able to refactor the css-tree extension to add single value function support and range syntax support to media queries reusing the code between CQ / MQ bringing the media query support up to date. This is a follow up PR that brings home modern query syntax to Svelte. Hopefully that PR is merged as well.

The MQ PR is here: #8430 The associated MQ issue that it closes is here: #5876

Really hope this gets implemented into mainline Svelte soon…

My workaround is to have container queries in separate CSS files, and bring them in with svelte:head

https://github.com/mitchray/ample/blob/b37d70e73be00b7fd506fd73274371bdae52bfe4/src/views/album.svelte#L27

Hm, Svelte 4.2.8 and it seems that using @container (){} breaks all the following CSSes. Is this a regression or did I do something weird with my code?

If you can work up an example in the Svelte REPL that is helpful. Though I don’t believe @container (){} is valid as there is no condition; at least from reading the specification.

It could be a situation where the custom parsing for @container can generate a better error or warning instead of possibly exhibiting the symptoms described.

Hm, Svelte 4.2.8 and it seems that using @container (){} breaks all the following CSSes. Is this a regression or did I do something weird with my code?

EDIT: I’ve been mistaken obviously and the reason was me not fully understanding what setting an element as container does to the layout. Sorry!

Thank you! This has been released in 3.58.0.

You can try out CQ support in Svelte by removing svelte from dependencies in package.json

and adding an overrides section like this:

  "overrides": {
    "svelte": "npm:@typhonjs-svelte/svelte@3.55.1-cq"
  },

For me the solution was to simply set your release as the svelte version in the devDependencies and I’m using SvelteKit. Here’s my full devDependencies for reference:

	"devDependencies": {
		"@sveltejs/adapter-static": "2.0.0",
		"@sveltejs/kit": "1.5.0",
		"@typescript-eslint/eslint-plugin": "5.51.0",
		"@typescript-eslint/parser": "5.51.0",
		"eslint": "8.33.0",
		"eslint-plugin-svelte3": "4.0.0",
		"svelte": "npm:@typhonjs-svelte/svelte@3.55.1-cq",
		"svelte-check": "3.0.3",
		"tslib": "2.5.0",
		"typescript": "4.9.5",
		"vite": "4.1.1"
	},

Anyways, thanks for this special release, it really helps! 🙏

You can try out CQ support in Svelte by removing svelte from dependencies in package.json

and adding an overrides section like this:

  "overrides": {
    "svelte": "npm:@typhonjs-svelte/svelte@3.55.1-cq"
  },

I’ve tested the override in my Svelte project and can confirm it works!

Out of interest, Svelte is currently using css-tree@v1.1.2, and yet the latest release is v2.1.0. Is there any guidance from the Svelte maintainers about whether support for @container syntax, when added to csstree, would be easy to pull in to Svelte?

Follow-up question - is anyone aware of a hack to get Container Query syntax working in Svelte at the moment? I’d ideally drop in the de-facto polyfill and do something in either a preprocessor or an action to bypass csstree for now. Any thoughts?