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

a:hover {} is invalid css #147

Open
simbleau opened this issue Nov 1, 2023 · 5 comments
Open

a:hover {} is invalid css #147

simbleau opened this issue Nov 1, 2023 · 5 comments

Comments

@simbleau
Copy link
Contributor

simbleau commented Nov 1, 2023

I get a cryptic message with the following:

css! {
    a:hover {
        color: white;
    }
}

Error: unexpected end of input, AttributeValue: unexpected end of input

If you change a:hover to anything else it works.

@jsievenpiper
Copy link

@simbleau should the css! macro be invoked in a function-like way? e.g. css!() instead of css!{}?

I've also found that stylist's ability to use bare css doesn't work in all cases: sometimes you'll need to switch to a stringified style ala:

css!(r#"
  a:hover {
    color: white;
  }
#")

@simbleau
Copy link
Contributor Author

simbleau commented Nov 1, 2023

@simbleau should the css! macro be invoked in a function-like way? e.g. css!() instead of css!{}?

I've also found that stylist's ability to use bare css doesn't work in all cases: sometimes you'll need to switch to a stringified style ala:

css!(r#"
  a:hover {
    color: white;
  }
#")

AFAIK there is no difference between macro!{}, macro!() and macro![]

And yes, the stringify way works, but isn't addressing the problem.

@jsievenpiper
Copy link

jsievenpiper commented Nov 6, 2023

AFAIK there is no difference between macro!{}, macro!() and macro![]

TIL these are interchangeable!

For further context, things like parameter substitution don't work without stringifying it either. I had stumbled into stylist (sometimes) correctly parsing unquoted css like you're trying, but I don't see anywhere in the docs (at least skimming the surface level stuff) implying it's supported at all.

EDIT: Turns out I was completely wrong here -- diving in a bit deeper, this is totally supposed to be supported!
https://docs.rs/stylist/latest/stylist/macros/index.html#example-2

Apologies for the confusion!

@WorldSEnder
Copy link
Collaborator

WorldSEnder commented Nov 11, 2023

The parsing code in

if next_input.maybe_to_attribute_name().is_some() {
// peek another token to see if it's colon
let maybe_colon = component_peek.peek();
if let Some(Ok(ComponentValue::Token(PreservedToken::Punct(p)))) = maybe_colon {
if p.as_char() == ':' {
let attr = input.parse()?;
return Ok(Self::Attribute(attr));
}
}
}
erroneously? assumes that a : hover is (the start of) an attribute declaration, not the block qualifier that is should be parsed as. Note that {} blocks are considered a potentially valid part of an attribute value, too. 1 Hence, the whole thing is parsed as one attribute, with a missing terminating semicolon at the end.

The correct decision probably needs to reparse a potentially unbounded part of the input; Both <attr-name> : <attr-value> ; and <element-name> : <pseudo-class-rule> { } allow for arbitrarily complex token sequences (as attr-value and pseudo-class-rule) before breaking the tie by either observing a semicolon ; or an open brace {. Hence I'm a bit conflicted how to address this. Introducing unbounded backtracking into the parser isn't something I fancy.

You can, with probably good enough browser support, rewrite this as

:is(a):hover {
}

Note that generating class names tries to encourage you to not depend on the element type of the annotated element - hence why such an example is not shown. I suppose, in this case, you are trying to fix some global browser dictated style for <a> elements, instead of trying to introduce this declaration for a specific component?

Footnotes

  1. https://www.w3.org/TR/css-syntax-3/#declaration-diagram

@simbleau
Copy link
Contributor Author

I suppose, in this case, you are trying to fix some global browser dictated style for <a> elements, instead of trying to introduce this declaration for a specific component?

Yes, in my case, this is the website's (global) style.

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