Is it possible to use the nth-child value as a parameter in a property? (and how)

落花浮王杯 提交于 2019-11-29 19:06:22

问题


Short description (tl;dr;)

Is there a "pure CSS" way (not Less/Sass) of using the value of the nth-child inside the CSS properties? Something like this:

span.anim:nth-child(N) { animation-delay: N * 0.5s; }

If there is, how can I do it? If there is not, how could I mimic it in a clean way? (I'm sure that I'm over-complicating things here)


Long description

I was creating a simple animation in which letters fade in while rotating. For that, I was using a combination of javascript (with jQuery) and CSS, but that created some problems (see below); so I tried to move to a CSS-only solution, and that ended in a large amount of rules.

This (simplified) CSS is common to both solutions:

span.anim {
    font-size:30px;
    opacity:0;
    animation: anim 1s;
    animation-fill-mode: forwards;
}

@keyframes anim {
    from {
        transform: rotate(0deg);
        opacity:0;
    }
    to {
        transform: rotate(360deg);
        opacity:1;
    }
}

Using JavaScript + CSS

My JavaScript code looks like this:

var aux = $("#animate").text();
$("#animate").text("");

for (var x = 0; x < aux.length; x++) {
    setTimeout('$("#animate").append("<span class=\'anim\'>' + aux[x] + '</span>")', 500 * x);
}

This works great... unless the user moves to a different tab, then the animation messes up, and the result is unexpected. You can see it on this JSFiddle: http://jsfiddle.net/e7b9ygk4/ (run the script, move to a different tab, and go back after a few seconds).

Using only CSS

I can achieve the same effect by breaking the element in smaller elements (this is the part I feel I'm over-complicating), and then applying the animation to each element with a different delay:

span.anim:nth-child(1) { -webkit-animation-delay:0.5s; }
span.anim:nth-child(2) { -webkit-animation-delay:1.0s; }
span.anim:nth-child(3) { -webkit-animation-delay:1.5s; }
span.anim:nth-child(4) { -webkit-animation-delay:2.0s; }
span.anim:nth-child(5) { -webkit-animation-delay:2.5s; }
span.anim:nth-child(6) { -webkit-animation-delay:3.0s; }
span.anim:nth-child(7) { -webkit-animation-delay:3.5s; }
span.anim:nth-child(8) { -webkit-animation-delay:4.0s; }
span.anim:nth-child(9) { -webkit-animation-delay:4.5s; }
span.anim:nth-child(10) { -webkit-animation-delay:5.0s; }
span.anim:nth-child(11) { -webkit-animation-delay:5.5s; }
span.anim:nth-child(12) { -webkit-animation-delay:6.0s; }
span.anim:nth-child(13) { -webkit-animation-delay:6.5s; }
span.anim:nth-child(14) { -webkit-animation-delay:7.0s; }
span.anim:nth-child(15) { -webkit-animation-delay:7.5s; }
span.anim:nth-child(16) { -webkit-animation-delay:8.0s; }

This works great, even if the user moves to a different tab, but it results in a lot of unnecessary code (both HTML and CSS, although it could be simplified using JavaScript). You can see it working on this JSFiddle: http://jsfiddle.net/f5my3sm1/.

My gut tells me that this could be achieved using Sass/Less, but I want to know if there is a simple "pure CSS" way of doing this, something that could be achieved (hopefully) with a single rule like:

span.anim:nth-child(N) { animation-delay: N * 0.5s; }

回答1:


CSS variables have almost universal support on all modern browsers and can achieve virtually the same desired effect as @GreatBlake's answer using attr plus more. Instead of defining data in a user-defined attribute, you can define it as a custom property in the style attribute and get the value of those custom properties using the var() function:

<span class="anim" style="--n: 0"></span>
<span class="anim" style="--n: 1"></span>
<span class="anim" style="--n: 2"></span>
<span class="anim" style="--n: 3"></span>
<span class="anim" style="--n: 4"></span>
span.anim {
  animation-delay: calc(var(--n) * 0.5s);
}



回答2:


There is a very experimental CSS function for using attributes as properties for an element. Currently it only works on pseudo elements, so you'd have to consider coming up with some kind of clever re-working of your markup in this use case.

You could put the offset in a data-attribute on your markup (or with JS), and then use something like the following:

/* attr(name, units, fallback) */
span.anim {animation-delay: attr(offset, 1) * 0.5s;}
<span class="anim" offset="0"></span>
<span class="anim" offset="1"></span>
<span class="anim" offset="2"></span>
<span class="anim" offset="3"></span>
<span class="anim" offset="4"></span>

Please keep in mind that this is still a ways off from being widely accepted, and like I mentioned before, the above syntax wouldn't work currently because it would need to use pseudo elements like :after.

At the very least, it's something fun to think about.



来源:https://stackoverflow.com/questions/28989708/is-it-possible-to-use-the-nth-child-value-as-a-parameter-in-a-property-and-how

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!