Why is it that this works, and yields the :before
and it says "changed"
:root {
--namevar: "fallback";
}
.in[name] {
--namevar: "changed";
}
.in dd:first-of-type:before {
font-weight: bold;
display: block;
content: var(--namevar);
}
But if you change it to this, the :before
is lost?
.in[name] {
--namevar: attr(name);
}
Nor do either of these work:
.in dd:first-of-type:before {
content: attr(name, inherit);
}
.in[name] dd {
name: inherit;
}
The HTML would look something like:
<div class="in" name="this">
<dd>one</dd>
<dd>two</dd>
<dd>three</dd>
</div>
What am I missing here?
The use of --namevar: attr(name);
works fine but you need to understand how it's working.
Example:
:root {
--namevar: "fallback";
}
.in dd:before {
font-weight: bold;
content: var(--namevar);
}
.in[name] {
--namevar: attr(name);
}
<div class="in" name="this">
<dd>one</dd>
<dd name="ok ">two</dd>
<dd>three</dd>
</div>
Notice how in the second case we show "Ok" and nothing for the others because they don't have name attribute. When using .in[name] {--namevar: attr(name);}
it doesn't mean get the value of the name attribute that belong to .in
and store it inside the variable. It means that the value of the variable is attr(name)
nothing more. We only resolve the value when the variable is used and in your case it's used inside dd
so we consider the attribute name (if it exists) of dd
.
In other words, you cannot use CSS variables to store a value of an element attribute and use it later inside any child element. What you can do is keeping your initial example and instead of attribute you consider CSS variable like below:
:root {
--namevar: "fallback";
}
.in dd:before {
font-weight: bold;
content: var(--namevar);
}
<div class="in" style="--namevar:'this '">
<dd>one</dd>
<dd name="ok">two</dd>
<dd>three</dd>
</div>