Quan­tity-spe­cific lay­outs

Ahmed Abuel­gasim ex­plores how it’s pos­si­ble to change styles and al­ter lay­outs to make them more adap­tive based on the quan­tity of el­e­ments us­ing just pure CSS

net magazine - - CONTENTS - Ahmed Abuel­gasim hun­gryphilo­math.com Front- end devel­oper, Potato Lon­don

Ahmed Abuel­gasim ex­plores how to adapt lay­outs based on the quan­tity of el­e­ments

In this tu­to­rial we will take a look at ways of chang­ing the CSS styles of el­e­ments, as well as seem­ingly styling their par­ents, depend­ing on the num­ber of el­e­ments. We will also see how to change the lay­out of el­e­ments based on their quan­tity, cre­at­ing more adap­tive lay­outs that make bet­ter use of space. Lastly we will cover the use of CSS coun­ters to dis­play an el­e­ment’s in­dex within a set in­side it, as well as dis­play­ing the to­tal count in­side the par­ent. All of this will be achieved with pure CSS only, with­out the need for JavaScript or frame­works, lead­ing to sim­ple and more ef­fi­cient code.

Sin­gle el­e­ment se­lec­tors

CSS3 only has a sin­gle pair of se­lec­tors that can de­ter­mine the quan­tity of el­e­ments, namely the :on­ly­child and :only-of-type se­lec­tors. Hav­ing said this, they are re­ally only able to de­ter­mine whether an el­e­ment is on its own or has sib­lings. The :only-child se­lec­tor matches el­e­ments that are the only child of their par­ent, while :only-of-type matches el­e­ments that are the only ones of their type. Un­for­tu­nately, that’s as far as sin­gle se­lec­tors go but there are a few other se­lec­tors that can tar­get el­e­ments based on their or­der in a set of sim­i­lar el­e­ments. These are :nth-child,

“Com­bin­ing these with other se­lec­tors al­lows us to build com­plex chains that tar­get el­e­ments based on quan­tity”

:nth-of-type, nth-last-child and nth-last-of-type, which are typ­i­cally used to tar­get el­e­ments based on their or­der in a set of sim­i­lar el­e­ments. The :nth-last-child and nth-last-of-type se­lec­tors are used to de­ter­mine the or­der of el­e­ments count­ing back­wards from the last el­e­ment to the first. Com­bin­ing these with other se­lec­tors en­ables us to build more com­plex chains that tar­get spe­cific el­e­ments based on their quan­tity.

Quan­tity-spe­cific se­lec­tor chains

Of the four afore­men­tioned se­lec­tors, the main one we will be us­ing in this tu­to­rial is nth-last-of-type. The dif­fer­ence be­tween this and the nth-last-child se­lec­tor is that the lat­ter in­cludes all the el­e­ments’ sib­lings in the set, while the for­mer only in­cludes el­e­ments of the same HTML type and is there­fore more se­lec­tive. For the re­main­der of this tu­to­rial we will use the -of-type se­lec­tors, how­ever the -child vari­ants are equally valid.

The nth-last-of-type can be used along with the more pop­u­lar first-of-type se­lec­tors to cre­ate a chain that tar­gets the first el­e­ment in a set of a de­sired quan­tity. For ex­am­ple, we can use :first-of-type:nth-last-

of-type(3) to tar­get el­e­ments that are both the first and the third from the end of their type or, in other words, the first of a set of three. We can then ex­tend this with the gen­eral sib­ling com­bi­na­tor ~ to select all sib­lings that fol­low the first of a set of three. Com­bin­ing these two se­lec­tor chains, we can cre­ate a com­plex se­lec­tor that tar­gets el­e­ments that are the first of three and all el­e­ments of the same type that fol­low it, thereby se­lect­ing all el­e­ments in a set of three. . box: first- of-type: nth- last- of-type( 3), . box: first- of-type: nth- last- of-type( 3) ~ . box This se­lec­tor chain not only works for a spe­cific num­ber of el­e­ments but can even be mod­i­fied to tar­get a range of quan­ti­ties. If we want to tar­get el­e­ments in a set with a quan­tity more than or less than a par­tic­u­lar value m, we can use the chain with the (n+m) and (-n+m) tech­niques re­spec­tively. For in­stance, to tar­get all el­e­ments in a set of two or more el­e­ments we can use: . box: first- of-type: nth- last- of-type(n+2), . box: first- of-type: nth- last- of-type(n+2) ~ . box Sim­i­larly, we can tar­get all el­e­ments in a set of two or less el­e­ments us­ing: . box: first- of-type: nth- last- of-type(- n+2), . box: first- of-type: nth- last- of-type(- n+2) ~ . box

As you can see this is a pow­er­ful se­lec­tor chain that en­ables us to achieve very in­ter­est­ing and useful things with­out the need for JavaScript or other frame­works. It is es­pe­cially useful when it comes to cre­at­ing adap­tive lay­outs that change based on the num­ber of el­e­ments.

Dy­namic, quan­tity-spe­cific lay­outs

Let’s say we want to dis­play a group of boxes that show the re­sults of a search or an API call in a twocol­umn, grid lay­out. The prob­lem lies in the fact that the re­sults come from an ex­ter­nal source and we have no way of know­ing the num­ber of re­sults that will be re­turned, there­fore we don’t know how many boxes will be cre­ated. While the grid looks great for an even num­ber of boxes, when ap­plied to an odd num­ber the last box sits on a row alone and looks… well, kind of odd.

This is es­pe­cially prob­lem­atic when us­ing flexbox items with flex-grow ap­plied to them as it causes the last el­e­ment to grow into the empty space on the row, thereby tak­ing up the full width. One way of pre­vent­ing this could be to make the first of an odd num­ber of boxes take up a full row by ap­ply­ing a width of 100% to first boxes that are also an odd num­ber of boxes from the end, us­ing :first-child:nth

last-of-type(odd). This pro­vides a bet­ter lay­out as it gives the first and there­fore most rel­e­vant or re­cent re­sult more sig­nif­i­cance than the last one.

We can even add a spe­cial case for when the quan­tity is di­vis­i­ble by three us­ing :first-child :nth-last

of-type(3n) to trans­form the grid into a three-col­umn lay­out by ap­ply­ing a width of 33% to first boxes in a set with a quan­tity di­vis­i­ble by three and all boxes that fol­low it. . box { width: 50%; } . box: first- child: nth- last- of-type(odd) { width: 100%; } . box: first- child: nth- last- of-type( 3n), . box: first- child: nth- last- of-type( 3n) ~ . box { width: 33%; }

Con­clu­sion

As we have seen, CSS se­lec­tors can be chained to­gether in a va­ri­ety of in­ter­est­ing ways in or­der to ap­ply styles and adap­tive lay­outs that change based on the quan­tity of el­e­ments. The se­lec­tor chains can also be used to seem­ingly ap­ply styles to the par­ent of a set of el­e­ments of a cer­tain quan­tity, by us­ing ::be­fore or ::af­ter pseu­doele­ments that are po­si­tioned to take up the full size of the par­ent. Com­bined with CSS coun­ters, these pseu­doele­ments can be used to dis­play the to­tal num­ber of de­scen­dants in a par­ent el­e­ment, as well as text that changes depend­ing on the quan­tity of de­scen­dants.

These tech­niques of­fer a valu­able way of cre­at­ing dy­namic, quan­tity-based styles and lay­outs that are useful when han­dling an un­known num­ber of el­e­ments, which is of­ten the case when deal­ing with APIs.

“These tech­niques of­fer a valu­able way of cre­at­ing dy­namic, quan­tity-based styles and lay­outs”

Above Se­lec­tor :first-of-type:nth-last-of-type(3) and the gen­eral sib­ling com­bi­na­tor ~ can be com­bined to tar­get the first of three and all its sib­lings, hence all in a set of three

Above Se­lec­tors nth-last-of-type(n+2) and :nth-last-of-type(-n+2) can be used to tar­get el­e­ments in sets of more than and less than two re­spec­tively

Above Quan­tity-based lay­out: lay­outs can be changed based on the num­ber of el­e­ments just by us­ing CSS se­lec­tor chains

Above Odd one out: for an even num­ber of el­e­ments grid lay­outs look great, but not so much for odd num­bers

Newspapers in English

Newspapers from Australia

© PressReader. All rights reserved.