Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-cascade-6] @base statement or base() function for relative urls in @sheet. #11680

Open
romainmenke opened this issue Feb 9, 2025 · 7 comments

Comments

@romainmenke
Copy link
Member

romainmenke commented Feb 9, 2025

See:

CSS authors often structure their source files in various sub directories.
Other assets (fonts, images, ...) are often described as relative urls.

It helps CSS authors if these relative urls actually make sense in their source code so that they can use IDE features to jump to those files, check that they actually exist, ...

It should be up to tools rewrite those urls so that they still make sense when bundling.

Simply inline stylesheets would alter the outcome of relative urls and even the behavior when custom props are used. (typed vs. untyped custom props for <url> have distinct behavior)

index.css

@import url("./something/styles/green.css");

something/styles/green.css

.box {
	background-image: url("../images/green.png");
}

This must be inlined as:

@sheet green {
  .box {
    background-image: url("something/images/green.png");
  }
}

@import green;

While that example is possible to support in tools, there is one that is impossible. When there are assignments to untyped custom props it can't be known statically what the urls should be rewritten to.

index.css

@import url("./styles/green.css");

.box {
	--background-image: url(./green.png);
}

styles/green.css

.box {
	background-image: var(--background-image);
}

Image location is : styles/green.png


Maybe we should have a way of describing the base url that should be used to resolve relative urls in Stylesheets.

@sheet sheet1 {
  @base url("https://example.com/styles/");

  .box {
    background-image: var(--background-image);
  }
}

@import sheet1;

.box {
	--background-image: url(./green.png);
}

Or through a function as suggested by @keithamus

@sheet sheet1 base("https://example.com/styles/") {
  .box {
    background-image: var(--background-image);
  }
}

@import sheet1;

.box {
	--background-image: url(./green.png);
}

Image location is : styles/green.png

@keithamus
Copy link
Member

One concern with an independant @base rule is that it could potentially appear anywhere within the rule, which means resources are unknown until the full @sheet rule has - at the very least - been tokenized, but more likely fully parsed. It also raises questions around multiple @base rules appearing. Additionally it becomes unclear what should happen with OM interaction, e.g. does sheet.insertRule('@base url("https://example.com/")') require resources to be re-fetched?

One potential way around these issues is to adjust the syntax to become something like:

@sheet foo base("https://example.com") {
 ...
}

Having the function within @sheets prelude means we can:

  • Limit the grammar of the prelude so it only occurs once.
  • Enforce the base to be resolved as early in the sheets declaration as possible, not locking us out of speculative preperation of subresources.
  • Restrict modifications in the CSSOM; the base can be readonly meaning the only way to change it would be to delete the rule or re-serialize it into a new sheet.

@romainmenke
Copy link
Member Author

Yup, seems like a better syntax to define this.
Thank you for suggesting that!

@romainmenke romainmenke changed the title [css-cascade-6] @base statement for relative urls in @sheet. [css-cascade-6] @base statement or base() function for relative urls in @sheet. Feb 9, 2025
@ziadkh0
Copy link

ziadkh0 commented Feb 10, 2025

Can the base URL be relative to the file it is in?

@keithamus
Copy link
Member

It would be if base was omitted but sometimes that might not be desired.

@romainmenke
Copy link
Member Author

@zaygraveyard like this?

@sheet sheet1 base("./styles/") {
  .box {
    background-image: var(--background-image);
  }
}

@ziadkh0
Copy link

ziadkh0 commented Feb 10, 2025

@romainmenke correct 👍

@romainmenke
Copy link
Member Author

I would also like it to work like this.
Makes it easier to have one host for local dev and another for previews, production (CDN domain?), ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants