Open Bug 435426 Opened 16 years ago Updated 3 months ago

[meta] Implement CSS Values 5 extensions to attr()

Categories

(Core :: CSS Parsing and Computation, enhancement, P3)

enhancement

Tracking

()

People

(Reporter: zwol, Unassigned)

References

(Depends on 12 open bugs, Blocks 2 open bugs, )

Details

(Keywords: dev-doc-needed, DevAdvocacy, meta, Whiteboard: [DevRel:P2])

We should implement css3-values' extensions to the attr() function:
http://www.w3.org/TR/css3-values/#attr
Severity: normal → enhancement
OS: Linux → All
Hardware: PC → All
Version: unspecified → Trunk
URL is now http://www.w3.org/TR/css3-values/#attribute
Summary: implement css3-values attr() → implement css3-values extensions to attr()
Blocks: css-values-3
Blocks: css3test
No plan to support this? CSS Variables is supported by Gecko but not attr(), it's little strange for me...Is it is more complex ?
Please do not use "+1" comments to indicate support for a bug, which cause a bunch of emails to be sent; use votes instead.
The MDN article already describes the CSS3 syntax.
https://developer.mozilla.org/en-US/docs/Web/CSS/attr

I'd like to see this implemented, so inline styles, that need to be marked as "unsafe" in CSP directives, can be replaced with data attributes.
Switched back to ddn: that way, when this bug is resolved, we will be notified, update the compat data in the article, add it to Fx XY for developers.

Rule of thumb: never set ddc on a non-RESOLVED bug.

Sorry for the spam.
(In reply to yair even or from comment #14)
> There is nothing small about this feature!!! it has the potential for
> amazing things for the web! I've been waiting for this for long years, so
> much could have been done smarter using such ability. It hurts me that you
> don't understand the greatness and how hugely important it is.

One thing that may not be obvious from the outside: *browser* developers are not necessarily very good *web* developers.  Speaking personally, I understand what the attr() extensions in CSS3 Values *do*, but I haven't ever encountered a situation where I *needed* them for something.

I said that there was no good place to raise the issue, and that's true in the narrow sense that complaining here will not change anyone's priorities, and complaining on Mozilla's development mailing lists won't help either.  But here's something constructive you *could* do: write an essay, on your own blog or similar venue, in which you demonstrate that this is a valuable thing to have.  Give a bunch of examples of things you either can't do or that require a lot of tedious working-around in the absence of this feature.  That will help us and others understand why you want it.
There is a famous blog post that explain this situation by telling a nice story - http://www.thegrumpyprogrammer.com/2014/11/its-users-stupid.html
(In reply to yair even or from comment #16)
> There is a famous blog post that explain this situation by telling a nice
> story - http://www.thegrumpyprogrammer.com/2014/11/its-users-stupid.html

That is a great anecdote, and let me explain why it means you should write that essay on your own blog like I suggested.

Situation 1: Imagine that you are the LibreOffice developers, in the anecdote, and someone comes to you and says "we want to do iterative calculations in our spreadsheets" - but they don't tell you why.

Now situation 2: you're still the LibreOffice developers, but now someone comes and says "we want to do iterative calculations because look, here is this library of spreadsheets that solve mechanical engineering problems for us in Excel and if only they also worked in LibO we could run them on our supercomputer."

You'd be a lot more sympathetic to the request in the second case, wouldn't you?

It's the same deal with attr() extensions.  We're currently in situation 1, and you could move us to situation 2 if you wrote that essay.
I think the main use cases for this were actually around the goal of being able to explain all of HTML's presentational behavior using CSS, something that's become less of a goal lately now that HTML5 has added a lot more behavior that would be harder to explain.  So the use cases that I remember from when it was added appear, today, rather weak.  Seeing other real use cases would be helpful, although filling up this bug too much will make the bug unreadable.

It's also worth pointing out that this is a pretty large change; I would say it most likely is substantially larger than CSS Variables, and probably imposes more architectural constraints on the engine, although maybe there are clever ways to do parts of it that I haven't thought of.
David Walsh had a small post about it here: http://davidwalsh.name/css-content-attr

Then, there's Lea Verou's own blog, which has a much more detailed coverage on attr(): http://lea.verou.me/2010/09/on-attr-and-calc/

The best "implementation" I found was a polyfill, which simulates the attr() property. You can find the polyfill here: http://codepen.io/FWeinb/pen/Dsdkr

As a simple google search shows, there are already a number of people wanting it, and talking about it, for quite some time now.
Here's an example from a css specification showcasing a situation where numerical information present in the markup (and correctly so, as it is semantic information, not merely presentational) would be useful to access from css via the extended attr() syntax.

http://dev.w3.org/csswg/css-egg/#celestial-css
One use case is the ability to achieve parity between custom HTML elements and some replaced elements.  For instance, <video>, <img>, <iframe>, <object>, <canvas> and others all allow specifying `height` and `width` as attributes.  Mimicking this is difficult with a custom HTML element, but could be made simpler with these extensions to attr():

    my-customelement {
        width: attr(width px, 300px);
        height: attr(height px, 150px);
    }
The progress bar use case in Lea's blog post (linked in comment #21) is made more compelling when you consider that a strict Content Security Policy makes the inline `style="width: X%"` alternative unusable.
Example: https://github.com/twbs/bootstrap/issues/17785
dev-doc seems to be there: https://developer.mozilla.org/en/docs/Web/CSS/attr
But unfortunately using it doesn't work on other properties than content.
<div class="hero" data-image-src="images/photosliderpicture.png"></div>
.hero {
  background-image: attr(data-image-src url);
}
Yes, as written in the page you linked (see Browser compatibility) and as the topic of this non-resolved bug is.
Completely agreeing with Lea's statement in comment 18, here's still a simple use case:
Adjust the width of an input field according to its max-length.

The code for may look like this:

data:text/html,<input maxlength="5" style="box-sizing:content-box;width:attr(maxlength ch, 10ch);">

Sebastian
Keywords: DevAdvocacy
This would be very useful in combination with CSS Shapes. 

Here's an example: 
  http://labs.jensimmons.com/examples/shapes-5.html
or the same example on CodePen
  http://codepen.io/jensimmons/pen/bedqqQ?editors=1100

by using 

    img {
      shape-outside: attr(src url);
    }

an author can control a shape by referencing the image that content should be floated around. This will make it very easy to use Shapes in the context of a Content Management System.
Whiteboard: [DevRel:P2]
Flags: platform-rel?
platform-rel: --- → ?
Priority: -- → P3
Blocks: 1265343
No longer blocks: shape-outside
platform-rel: ? → ---
Another use-case would be setting (default) values for CSS variables via attributes:

    <div class="card" data-size="24">…</div>
    <div class="card" data-size="16">…</div>

    .card {
      --size: attr(data-size, 32);
      width: var(--size) * 1px;
      height: var(--size) * 1px;
    }

This way, we wouldn't have to set CSS vars via style attributes in the markup, which I wouldn't consider a good pattern.

At least I imagine that this could work?
No longer blocks: 1265343
Is there a decent chance that Servo could fix this?
At the moment we’re shipping two style systems and we try to avoid behavior differences between them. Adding attr() support everywhere should be easier after we ship Stylo on every platform and remove the old style system.
(In reply to Simon Sapin (:SimonSapin) from comment #33)
> At the moment we’re shipping two style systems and we try to avoid behavior
> differences between them. Adding attr() support everywhere should be easier
> after we ship Stylo on every platform and remove the old style system.

Setting dependency accordingly
Depends on: stylo-everywhere
I'm here with about the same usecase as comment 25. It would definitely be a boon to have this available.

In my particular case writing code for a CMS module, the module's files include CSS for most of the styling of the pages it adds to a site. In some cases, images are used, which are of course bundled in with the module itself. The precise locations for the images depend on where the CMS is installed within the web directory (somewhere within htdocs), which eliminates hardcoding absolute URLs that start with '/') and certain elements appear at pages with various depths, which means relative paths starting with '../' won't work either.

So without the ability to do something like 

    input[type=submit]#my-element {
        background: none;
        background-image: attr(data-submit-icon url)
    }

I may be stuck building workarounds or integrating something like Compass (or some other CSS-generator) all for a minor sprinkling of icons.

It looks like there's some forward momentum on this again but there's my two cents anyhow. Cheers.
Be aware this could easily leak passwords through CSS, because lost of JS frameworks are (mis/ab)-using DOM properties.

e.g. accounts.google.com

input[data-initial-value]{
content:attr(data-initial-value url);
}
This will send a request to domain/password: password ending up in server logs in clear text.
janghou raises a good point... I would argue that because there's so many types to support that this should be a tracking ticket, and each type be a different bug.  For instance, the url type will have a different level of security risk than the integer type, and will thus require a different amount of scrutiny.

Gradual, partial and documented implementation is better than no implementation at all.

On the other hand, janghou:  isn't leaking passwords in frameworks an evangelization problem?  Sure, we're stuck with it...
I think there are way more use cases for integer / length / percentage values than there is for the url values. Combining with the higher security scrutiny needed for url values, Alex's point about implementing the value types separately makes a lot of sense to me.
I appreciate the security difficulties in implementing secure URL values but I hope that it is still high on the agenda when implementing attr(), since the most needed use case, IMO, is to get the control/power one gets with background-image without explicitly setting it in the CSS but rather on the HTML element. This is currently not possible without background-image: attr(data-* url); or using JavaScript.
Depends on: 1448248
Depends on: 1448250
I've started filing separate bugs for each part of the new syntax. Please let me know if there's something wrong with them.

Sebastian
Keywords: meta
Summary: implement css3-values extensions to attr() → [meta] Implement CSS Values 3 extensions to attr()
Depends on: 1448251
Depends on: 1448252
I think, unless you plan on implementing, filing (more) bugs is premature... after all, the implementer(s) will be doing the actual planning.  We're still waiting on Stylo-everywhere (bug 1395112), and this bug's been around for ten years.  We've waited this long.  Let's be patient, folks:  until development work actually starts on CSS attr(), every comment we've made so far is peanut-gallery noise, sent to dozens of people, and I'm guilty of enough bugspam from those audience seats to know that it distracts from current work.

Now, if you are actually planning to do part of the implementation, ignore everything I'm saying in this comment and feel free to start, with the blessings of the entire community.

If I had the time, I would definitely pick up one of the types and work on it.  I've done this kind of cutting-edge ticket before (bug 525816, bug 332148, bug 1383630), and this one's really interesting to me (being a really good excuse to learn both Rust and how layout works).  But I'm also buried with a full-time job and university studies, so if it's me, you're probably going to wait another year or two.
I've been wanting to work on this for a while now, but I'm not sure where to start. I'd really appreciate if someone can make time to pair with / mentor a dev new to the Stylo code base. (Is there a better place to ask?)
(In reply to seanlinsley from comment #44)
> I've been wanting to work on this for a while now, but I'm not sure where to
> start. I'd really appreciate if someone can make time to pair with / mentor
> a dev new to the Stylo code base. (Is there a better place to ask?)

It's not particularly trivial, but not impossible, I can try to help I guess.

The basic version where attribute references are unparsed values should probably mimic the custom properties code, and be a matter of resolving attr references the same way we keep track of property declarations that have variable references in:

  https://searchfox.org/mozilla-central/rev/de5c4376b89c3603341d226a65acea12f8851ec5/servo/components/style/properties/properties.mako.rs#255, and storing the attributes we're referencing so we can invalidate style properly.

Also, this should probably keep track of a PrecomputedHashSet<Atom> (or maybe (Namespace, Atom)?) to see which attributes are referenced from the style of the element, in order to recompute the element's style when that attribute changes...

It's probably easier to implement this first for Servo only, then plug that into Firefox. Please open an issue in https://github.com/servo/servo to track that work if you want to tackle this, and feel free to cc me (I'm @emilio on GitHub as well) or ask questions there.
(In reply to Emilio Cobos Álvarez [:emilio] from comment #45)
> should probably mimic the custom properties code

I haven’t thought through all of the implementation implications, but I think that attr() is more similar to calc() than to var(): it can only be used in places where some "types" of values are expected, not at arbitrary tokens.
(In reply to Simon Sapin (:SimonSapin) from comment #46)
> (In reply to Emilio Cobos Álvarez [:emilio] from comment #45)
> > should probably mimic the custom properties code
> 
> I haven’t thought through all of the implementation implications, but I
> think that attr() is more similar to calc() than to var(): it can only be
> used in places where some "types" of values are expected, not at arbitrary
> tokens.

Ah, I see. Reading the spec more carefully it seems to be the case indeed. Then it's probably better to make it work like a regular specified value.
See Also: → 1481150
Blocks: 1493962
No longer blocks: 1493962
With work on bug 1395112 now being essentially finished, it doesn’t seem like there are any more major blockers for this, so I’ve filed https://github.com/servo/servo/issues/22265 in the Servo repository in hope that this might finally get implemented.

This could make a huge difference for CSS layout, completely replacing grid systems…

[data-layout] {
  grid-area: attr(data-layout custom-ident, auto / 1 / auto / -1);
}

(In reply to miriam from comment #49)

This could make a huge difference for CSS layout, completely replacing grid systems…

[data-layout] {
  grid-area: attr(data-layout custom-ident, auto / 1 / auto / -1);
}

That wouldn't be valid, as far as I can tell, as auto / 1 / auto / -1 wouldn't parse as a custom-ident.

I think that'd work if attr() was defined more like env() or var(), except then you couldn't write things like attr(foo)px.

I wouldn't expect attr(foo)px to work anyway. The spec mentions attr(foo px) as the syntax for converting the value to a specific unit.

But my idea may also fail because custom-ident is not an actual option in the spec list <type-or-unit> keywords. I was being very idealistic in my hope for this feature. Even a less dreamy grid-area: attr(data-area, main); might not be supported by the current spec.

The spec link these days is this, I think:
https://drafts.csswg.org/css-values-4/

shoud summary change to refllect this?

Level 4 adds several mathematics capabilities over Level 3, including several functions beyond calc() and definitions on methods for combining terms together when they affect the same property value. However, I don't see a substantial difference in substance between Level 3's and Level 4's definition of attr(), just significantly more words to arrive at the same place. And Firefox isn't even there yet, though it's getting there.

Since this feature is part of Level 3, this bug blocks bug 741643, which is the metabug for implementing all of Level 3. If you feel strongly, you could file a new bug and say that it blocks bug 1531237, which is the metabug for implementing all of Level 4, but I wouldn't be surprised if it gets duped back to this one anyway.

(In reply to Andrew Cook from comment #54)

Level 4 adds several mathematics capabilities over Level 3,
...
Since this feature is part of Level 3, this bug blocks bug 741643, which is the metabug for implementing all of Level 3. If you feel strongly, ...

I don't feel strongly in any way, just noted that Chromium intends to ship this:

CSS Level 4 has made substantial revisions to attr() compared to Level 3 to ease the implementation. We'll follow CSS4.

https://groups.google.com/a/chromium.org/forum/m/#!topic/blink-dev/FGCgsKmylhw

Severity: normal → S3

For people wondering what the uses of this is, one good use (one that I would like to use for my forum software) would be to have javacscript-less user-definable colors for text.

In my case, users can use classic bbtext [color=#ff44aa]text here[/color] and such in their forum posts. However, a strict CSP and requiring full-feature fallback in the event there's no javascript available means that inline colors/sizes are right out- as a result I actually need to embed a CSS script with a calculated CSP nonce in the page with a generated ID for each custom color/size that appears in any post on the page. This is very heavy-weight (relatively speaking) to do on the backend for a forum software that's trying to be incredibly light-weight, and which could be easily solved with a single generic .user-color style and a data attribute on the generated HTML if this feature worked. It would also have the advantage of requiring no javascript (which would be the 'traditional' solution for this) which also reduces it's footprint, and browser requirements.

To note, there are unfiled blocking bugs for other/more types:

  • ident
  • number
  • percentage
  • length, angle, time, frequency (unimpl), flex
  • <dimension-unit>
No longer blocks: css-values-3

Please note this was deferred until Level 5, so updated URL and blocking bugs.

Summary: [meta] Implement CSS Values 3 extensions to attr() → [meta] Implement CSS Values 5 extensions to attr()

Why this is important in my opinion:
-allows to set the calculations only in JS
-allows to set the markup only in HTML (attribute is updated from JS)
-allows to use data which updates with user's interaction, without setting the style from JS (or inline in HTML)

Obviously you could set a custom variable from JS but in doing so the final product is harder to read and maintain.

This CSS value, when not being taken as string only, allows for more flexibility while keeping things clear and organized.

As a string only it is useless, as a string value could only be used in pseudo-elements' content. There's not really much to gain from doing so.

Example:
I would like to track the mouse movement to set styles based on the X and Y position.

I can set an eventlistener which track the mouse movement in JS. This would get me X and Y numeric values.
Then the JS's values are set as the attributes' (X and Y) values in HTML.
Then these numeric values could be used in CSS thanks to attr()

This cannot be done currently as the default value is a string, and it cannot be set to a number, or a pixel value or anything else.

It would be a replacement for TailwindCSS.

For example if I wanted to put a dynamic size to a text with TailwindCSS it would be done this way:

<span class="text-base">Im not the king</span>.

But using attributes you could dispense with external JS libraries so that changing the text size could be done like this.

<span class="text-size" data-text-size="1.0"></span>

In the stylesheet there would be something like this:

.text-size {
font-size: attr(data-text-size, rem, 1);
}

For colors with TailwindCSS it would look something like this:

<span class="text-base text-blue-600">Im not the king</span>

Dispensing with the external JS library, we would do it like this:

<span class="text-size text-color" data-text-size="1.0" data-text-color="2563eb">Im not the king</span>

In the stylesheet there would be something like this:

.text-size {
font-size: attr(data-text-size, rem, 1);
color: attr(data-text-color, color, 000000);
}

Depends on: 1871815
Depends on: 1871816
Depends on: 1871817
Depends on: 1871818
Depends on: 1871819
Depends on: 1871820
Depends on: 1871821
Depends on: 1871822
Depends on: 1871823

(In reply to Oliver Medhurst [:canadahonk] from comment #58)

To note, there are unfiled blocking bugs for other/more types:

  • ident
  • number
  • percentage
  • length, angle, time, frequency (unimpl), flex
  • <dimension-unit>

I've created individual blocking bugs for them, now. Though I assume that the majority of types can be implemented together. So they might be merged once implementation begins.

Sebastian

You need to log in before you can comment on or make changes to this bug.