简体   繁体   中英

How to generate ABBAABBA… sequence with PHP and CSS nth-child

I have a two column layout with this disposition of elements:

AB
BA
AB
BA

A and B elements have content from different origins and also different styles. So, I'm trying to find an expression to generate this ABBAABBA … sequence both in PHP and CSS nth-child.

This is what I'm doing to generate the layout:

/* $post_ids is an Array of ID's */

$count = count( $post_ids );

for ( $i = 0; $i < $count; $i++ ) {
    $classes = ['teaser', 'lg-6', 'md-6', 'sm-12'];
    if ( ( 2 * $i ) % 2 == 0 ) { // This is wrong. Always true!
        $classes[] = 'a-element';
    } else {
        $classes[] = 'b-element';
    }
    insert_post( $post_ids[ $i ], $classes ); // This is a custom function
}

And this is my CSS:

.teaser:nth-child(2n) { // Also wrong
    /* Styles for A items */
}

I know once I got the correct PHP sequence I could replace my CSS with:

.a-element {…}
.b-element {…}

But I'd like to know if this could be also done with nth-child ...

I guess it can't be that hard, but I'm kinda stuck with this... Any hint or help will be much appreciated!


Edit: After @axiac's answer and some research , I've learned that nth-child only allows:

  • a number - any positive integer (1,2,3,20, etc.)
  • a keyword - even or odd
  • an expression - in the form of an+b (a, b being integers)

So, I guess what I want can't be done with CSS's nth-child . Thank you guys!

The PHP code you need is:

if ((int)(($i + 1) / 2) % 2 == 0 ) {
    $classes[] = 'a-element';
} else {
    $classes[] = 'b-element';
}

Update

At OP's request, this is how I produced the code above. The desired outcome is:

A B B A A B B A ..
  • after the initial A each symbol repeats twice. We use a for (;;) loop to iterate from 0 to some $n greater than zero;
  • the alternation is provided by the modulo operation ( % 2 );
  • grouping the values can be done by finding a common property for consecutive numbers. The integer result of division by the desired group size is such a property. If you need to output 5 A s followed by 5 B s then you just notice that any positive integer number can be written as 5 * k + r where r is one of 0, 1, 2, 3, 4 (this is how the division of integer numbers works). There are exactly 5 consecutive integer numbers that divided by 5 produce the same integer result (and different remainders);
  • given that the PHP division always produce real numbers, the conversion of the result to int (by type casting the result to (int) ) is needed;
  • the + 1 offset is needed to "push" one A before the first 2 B s. 0 and 1 produce the same result ( 0 ) when divided by 2 (they make the first group), 2 and 3 produce 1 and make the second group and so on.

Generalization

If you need to produce N different types of blocks ( A , B , C , D aso), each of them appear M consecutive times ( AAABBBCCCDDD ... , M is 3 here) then the formula is:

(int)(($i + $k) / M) % N

The value produced by this formula is one of 0 , 1 ... N - 1 and it tells what symbol to use ( A , B aso). Without + $k this formula generates M instances of A followed by M instances of B , M instances of C and so on until the last symbol. It prints M * N symbols in total then it starts over with A .

The value of $k is one of 0 .. M * N - 1 and it allows the sequence to start from any point inside the sequence. It represents the number of symbols to skip from the start of the sequence.

If I understand correctly the problem is with:

(2 * $i) % 2 == 0 

this will return true for all iterations (2 * $i) is always even

try:

$i % 2 == 0

instead

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM