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-values] enable the use of counter() inside calc() #1026

Open
psylok opened this issue Feb 11, 2017 · 12 comments

Comments

Projects
None yet
@psylok
Copy link

commented Feb 11, 2017

Feature request.
It would be nice to be able to use the counter() function inside of calc() function.
That would enable new possibilities on layouts.

I copy here the link to a thread which proposed it last august.
https://lists.w3.org/Archives/Public/www-style/2016Aug/0073.html

@AmeliaBR

This comment has been minimized.

Copy link
Contributor

commented Feb 11, 2017

Relevant section of the spec, which includes an inline issue discussing possible use cases. But getting an issue on GitHub will hopefully provide an easier forum for other people to mention their use cases and/or possible implementation issues.

@MelSumner

This comment has been minimized.

Copy link

commented Feb 26, 2017

Hi, ran into a case today where this would have helped, so posting a comment here.

I'm setting up some CSS for an image/logo slider. While I know right now that there are 8 images, I don't know how many there will be in the future (nor do I wish to have to know). I'm using only CSS to animate it, and it would be useful to be able to say "for each one of the items that exist (, increment this property by x."
I ended up using sass to do something like this:

@for $i from 1 through 8 {  
    &:nth-of-type(#{$i}) {
        $delay: calc(5s * #{$i});
	animation: slideIn 45s linear $delay infinite;
    }
}

@fantasai fantasai changed the title [css-functions] enable the use of counter() inside calc() [css-values] enable the use of counter() inside calc() Mar 30, 2017

@Loirooriol

This comment has been minimized.

Copy link
Collaborator

commented Oct 15, 2017

The problem with this proposal is that counter() returns a <string>, but calc() does not work with strings. For example, counter(id, upper-latin) might be 'A'. How exactly is calc() supposed to know that this means 1?

So I think we need some way to get the numeric value of a counter, either by adding some parameter to counter() or a new function. This should be allowed to appear anywhere an integer is expected, including (but not necessarily in) calc(). I wrote my thoughts in #1871.

@Crissov

This comment has been minimized.

Copy link
Contributor

commented Oct 16, 2017

JFTR, I would hate to see int() or str2num() in CSS.

@tabatkins

This comment has been minimized.

Copy link
Member

commented Oct 18, 2017

Yeah, an explicit parsing function is probably bad. No real need for it. But having something that can retrieve a counter value as a number (rather than going to the extra effort of formatting it as a string) would work. (Same as how attr() has functionality to parse the attr value as a number or dimension.)

@upsuper

This comment has been minimized.

Copy link
Member

commented Nov 2, 2017

Wouldn't allowing counter() in calc() either ruin any attempt to parallelize styling, or make us need to delay calculating of every numeric value to used-value time?

@Loirooriol

This comment has been minimized.

Copy link
Collaborator

commented Nov 2, 2017

@upsuper Fair point, counter values are inherited from the immediately preceding element in document order instead of from the parent element as usual. So maybe it would be better to add a sibling-index() function as Tab Atkins proposed in #1869 (comment); it would be less powerful but I think it would cover most usecases.

However, note that the CSS Lists draft currently allows counter() anywhere a <string> is expected, doesn't this have the same problem? If it's possible to use a counter value as a string, it should also be possible to use it as an integer.

@upsuper

This comment has been minimized.

Copy link
Member

commented Nov 3, 2017

However, note that the CSS Lists draft currently allows counter() anywhere a <string> is expected, doesn't this have the same problem? If it's possible to use a counter value as a string, it should also be possible to use it as an integer.

Firstly, there are a lot fewer places where <string> is accepted, and they are usually relatively less complicated than <length> and its friends when it comes to layout, so expanding them in used-value time (like what is currently done for content property) may not be as bad.

Also, allowing counter() anywhere <string> is allowed is something new. counter() functions are listed as independent item of content property in CSS2. And I'm not aware of any browser who has implemented that anywhere outside content. That means, its feasibility may also be questioned, and my argument above can potentially be apply to that as well.

@upsuper

This comment has been minimized.

Copy link
Member

commented Nov 3, 2017

Firstly, there are a lot fewer places where <string> is accepted, and they are usually relatively less complicated than <length> and its friends when it comes to layout, so expanding them in used-value time (like what is currently done for content property) may not be as bad.

It may not be as bad, but it could still be very bad. One issue comes to my mind is that <family-name> can be a <string>, and font-family is inherited, so you may really want to make counter() be expanded in computed-value time (rather than in used-value time like what we do now for content), otherwise it can lead to some funny behavior. This is some case which seems to be neither useful nor easy to implement, which would be a native consequence if we allow counter() be in anywhere <string> is allowed.

I guess we should start this topic in a separate issue, now.

@kizu

This comment has been minimized.

Copy link

commented Jan 15, 2018

I would really, really love to have counter's value available inside calc(). The syntax I'd propose could be something like counter-value() that would return the counter's value as an integer. Other than the use-cases for sibling-index, this could be used for a lot more cases (not only experimental ones). While I understand that that can be non-trivial to implement, the possibilities it would unlock would be tremendous.

@LeaVerou

This comment has been minimized.

Copy link
Contributor

commented Apr 29, 2018

Two more use cases:

  • Staggered animations by using it in animation-delay
  • Reversing the z-index order by using it in z-index

Regarding syntax, I like @tabatkins's proposal for a new formatting argument, if an explicit syntax is required.
Although IMO ideally it would be nice if we could auto cast number-like strings to numbers in calc() akin to how many programming languages do it (including JS). It's not like strings actually do anything in calc(), so there's no disambiguation problem.

@jonjohnjohnson

This comment has been minimized.

Copy link

commented Apr 29, 2018

My sad excuse of a utility without this feature...

...
.count--3 { --count: 3 }
.count--4 { --count: 4 }
.count--5 { --count: 5 }
...
.count > :nth-child(1) { --count-current: 1 }
.count > :nth-child(2) { --count-current: 2 }
.count > :nth-child(3) { --count-current: 3 }
...
.el {
  animation-delay: calc((var(--count, 0) - var(--count-current, 0)) * 0.1s);
} 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.