css

CSS selectors: Ότι πρέπει να ξέρετε! (μέρος 3ο - CSS3)

12/12/2015

Σημείωση: Το παρακάτω άρθρο γράφτηκε τον Σεπτέμβριο του 2009 (πριν 6 χρόνια!) για το CSS3.gr.

Καλώς ήρθατε στο τρίτο και τελευταίο μέρος του άρθρου “CSS selectors: Ότι πρέπει να ξέρετε”! Με αυτό το μέρος ολοκληρώνεται η σειρά των άρθρων που παρουσιάζουν όλους τους CSS selectors, μέχρι τουλάχιστον να εμφανιστεί το CSS4 (που πιστέψτε με, θα αργήσει πολύ ακόμα). Σε αυτό το τελευταίο μέρος του άρθρου, παρουσιάζεται ότι πιο καινούργιο έχει να επιδείξει το CSS - σε επίπεδο selectors πάντα - οπότε εάν δεν είστε ήδη πολύ έμπειρος στο θέμα, καλό θα είναι να ρίξετε μια ματιά στο πρώτο και δεύτερο μέρος του άρθρου, έτσι ώστε να ξεκινήσετε με τα πιο βασικά.

CSS3 selectors

Πριν βιαστείτε να χρησιμοποιήσετε τους ολοκαίνουριους CSS3 selectors, έχετε υπ’ όψη σας πως πολλοί (οι περισσότεροι μάλλον) δε θα δουλέψουν σε παλιότερους browsers και συσκευές. Οι νεότεροι browsers θα τα καταφέρουν πολύ καλύτερα, ωστόσο έχετε υπ’ όψη σας πως εάν ο browser δεν καταλάβει τον selector, τότε δεν θα προσθέσει κανένα style πάνω του, με αποτέλεσμα να χαλάσει το όμορφο site σας. Κοιτάμε μπροστά λοιπόν, αλλά πάντοτε με προσοχή, και ελπίζουμε όλοι οι κατασκευαστές να φτάσουν γρήγορα σε ένα ικανοποιητικό επίπεδο έτσι ώστε να μπορέσουμε να χρησιμοποιήσουμε τους παρακάτω selectors όσο πιο γρήγορα γίνεται. Τέλος, γι’ αυτούς που δεν θυμούνται ή δυσκολεύονται να καταλάβουν κάτι στα patterns του κάθε selector, ας ρίξουν μια ματιά στην εισαγωγή του πρώτου μέρους, και ξεκινάμε!

Attribute selectors

Στο CSS3 προστίθενται ακόμα 3 attribute selectors που προσθέτουν επιπλέον δυνατότητες και έλεγχο στους υπάρχοντες CSS2 attribute selectors.

  1. Στον πρώτο selector λοιπόν, επιλέγουμε το element (Ε), όπου περιέχει την attribute “att” η οποία ξεκινάει με την τιμή “val”.
  2. Στον δεύτερο selector ισχύει το ακριβώς ανάποδο, δηλαδή επιλέγουμε το element (Ε), όπου περιέχει την attribute “att” η οποία τελειώνει με την τιμή “val”.
  3. Τέλος στο CSS3 κάνει την εμφάνιση του και ένας πιο “μπαλαντέρ” selector, ο οποίος επιλέγει το element (Ε), που περιέχει την attribute “att” η οποία περιέχει σε οποιοδήποτε σημείο της το string “val”.

Ρίξτε μια ματιά στα παραδείγματα, μιας και η θεωρία είναι λίγο δυσνόητη στους συγκεκριμένους selectors.

Patterns

  1. E[att^=“val”]
  2. E[att$=“val”]
  3. E[att*=“val”]

Παραδείγματα

a[href^="mailto:"] {
  padding-right: 18px;
  background: url(icons/email.png) no-repeat right;
}

a[href$=".mov"] {
  padding-right: 18px;
  background: url(icons/video.png) no-repeat right;
}

a[href*="username"] {
  padding-right: 18px;
  background: url(icons/star.png) no-repeat right;
}

Pseudo-classes

Οι περισσότερες προσθήκες selectors στο CSS3 έχουν γίνει στις ψευδοκλάσεις, μιας και εμφανίζονται 12 - ναι καλά διαβάσατε - ολοκαίνουριες από αυτές. Προς το παρόν, λίγοι είναι browsers που τις υποστηρίζουν, ωστόσο όπως καταλαβαίνετε οι συγκεκριμένοι selectors είναι το βαρύ πυροβολικό στο CSS3. Ας τις δούμε όμως μία-μία ξεχωριστά.

  1. Επιλέγει το root element του document, που στην περίπτωση μας είναι πάντα το . Όπως καταλαβαίνετε ο συγκεκριμένος selector δεν έχει πολύ νόημα στα (X)HTML document, αλλά είναι πολύ πρακτικός σε άλλους τύπους document, όπως XML.
  2. Η επόμενη ψευδοκλάση είναι ίσως η πιο σημαντική προσθήκη στο CSS3. Με αυτήν μπορούμε να επιλέξουμε το νιοστό (n) child element. Οι παράμετροι που μπορεί να πάρει ο συγκεκριμένος selector είναι πολλοί, γι αυτόν τον λόγο άλλωστε είναι και πανίσχυρος, και μπορεί να είναι αριθμητικές (πχ. 2n+1, όπου θα επιλέξει όλα τα μονά στοιχεία), λέξεις κλειδιά (πχ. odd, οπού θα κάνει ακριβώς το ίδιο) ή κατευθείαν κάποιον αριθμό (πχ. 1, όπου θα επιλέξει το πρώτο child element). Ρίξτε μια ματιά στα παραδείγματα και θα καταλάβετε αμέσως τι δύναμη κρύβει ο συγκεκριμένος selector.
  3. Ακριβώς η ίδια ψευδοκλάση με την παραπάνω (ίδιο συντακτικό, παραμέτρους, κτλ.), με την διαφορά πως αρχίζει το μέτρημα από το τελευταίο και όχι το πρώτο element. Ίσως το W3C να το παραέκανε κάπως, ωστόσο ποτέ δεν ξέρεις που θα σου χρειαστεί κάποιος selector!
  4. Ακόμα μία πολύ χρήσιμη ψευδοκλάση. Με αυτήν μπορούμε να επιλέξουμε το νιοστό (n) child element ενός συγκεκριμένου τύπου, όπως για παράδειγμα ενός γραφικού (img). Οι παράμετροι που μπορεί να δεχθεί είναι ακριβώς οι ίδιοι με τους 2 παραπάνω selectors, δηλαδή αριθμητικές τιμές (πχ. 2n+1, όπου θα επιλέξει όλα τα μονά στοιχεία), λέξεις κλειδιά (πχ. odd, οπού θα κάνει ακριβώς το ίδιο) ή κατευθείαν κάποιον αριθμό (πχ. 1, όπου θα επιλέξει το πρώτο child element).
  5. Ακριβώς η ίδια ψευδοκλάση με την παραπάνω (ίδιο συντακτικό, παραμέτρους, κτλ.), με την διαφορά πως αρχίζει το μέτρημα από το τελευταίο και όχι το πρώτο element.
  6. Και ερχόμαστε επιτέλους σε πιο εύκολες ψευδοκλάσεις οι οποίες υποστηρίζονται και από αρκετούς μοντέρνους browsers. Με την last-child ψευδοκλάση λοιπόν, επιλέγουμε το τελευταίο child element. Αξιοσημείωτο είναι πως ο ανάποδος selector (E:first-child) είχε κάνει την εμφάνιση του στο CSS2!
  7. Επιλέγει το πρώτο child element ενός συγκεκριμένου τύπου, όπως για παράδειγμα γραφικού (img).
  8. Επιλέγει το τελευταίο child element ενός συγκεκριμένου τύπου.
  9. Επιλέγει το μοναδικό child element (δηλαδή το element δεν έχει siblings).
  10. Επιλέγει το μοναδικό child element ενός συγκεκριμένου τύπου (δηλαδή το element δεν έχει άλλα siblings ίδιου τύπου).
  11. Επιλέγει το element το οποίο δεν έχει ούτε child nodes, ούτε text nodes (με άλλα λόγια εμφανίζεται τελείως καινό στο DOM).
  12. Επιλέγει το element, το οποίο είναι ο στόχος κάποιου URI. Όλοι μας έχουμε χρησιμοποιήσει την id ιδιότητα έτσι ώστε να στείλουμε κάποιο link στο συγκεκριμένο σημείο (χρησιμοποιώντας στο τέλος του URL το σύμβολο #). Η συγκεκριμένη ψευδοκλάση λοιπόν αναλαμβάνει να επιλέξει αυτά τα elements.

Patterns

  1. E:root
  2. E:nth-child(n)
  3. E:nth-last-child(n)
  4. E:nth-of-type(n)
  5. E:nth-last-of-type(n)
  6. E:last-child
  7. E:first-of-type
  8. E:last-of-type
  9. E:only-child
  10. E:only-of-type
  11. E:empty
  12. E:target

Παραδείγματα

:root {
  color: red;
}

tr:nth-child(2n+1) /* επιλέγει όλες τις μονές σειρές ενός πίνακα */
tr:nth-child(odd) /* επιλέγει όλες τις μονές σειρές ενός πίνακα, χρησιμοποιώντας την λέξη κλειδί odd  */
tr:nth-child(2n) /* επιλέγει όλες τις ζυγές σειρές ενός πίνακα */
tr:nth-child(even) /* επιλέγει όλες τις ζυγές σειρές ενός πίνακα, χρησιμοποιώντας την λέξη κλειδί even */
li:nth-child(1) /* επιλέγει το πρώτο list item */
tr:nth-last-child(1) /* επιλέγει την τελευταία σειρά ενός πίνακα */

img:nth-of-type(2n+1) {
  float: right;
} /* επιλέγει όλα τα μονά images */

img:nth-of-type(2n) {
  float: left;
} /* επιλέγει όλα τα ζυγά images */

img:nth-last-of-type(1) {
  border-bottom: 1px solid #000;
} /* To τελευταίο image θα έχει border */

li:last-child {
  color: red;
} /* To τελευταίο list item θα έχει κόκκινο χρώμα */

img:first-of-type {
  padding: 10px;
  border: 1px solid #000;
} /* To πρώτο image θα έχει padding και border */

p:last-of-type {
  font-size: 1.2em;
} /* Η τελευταία παράγραφος θα έχει μεγαλύτερο font */

li:only-child {
  list-style-type: square;
} /* Σε μία λίστα με ένα και μοναδικό list item, το list item θα έχει τετραγωνάκι για τύπο λίστας */

img:only-of-type {
  padding: 10px;
  border: 1px solid #000;
} /* Το image που δεν έχει άλλα siblings ίδιου τύπου (images - img tags), θα έχει padding και border */

p:empty {
  display: none;
} /* Οι παράγραφοι που δεν έχουν child και text nodes δεν θα εμφανίζονται */

h2:target {
  color: red;
} /* Επιλέγει τους h2 τίτλους που είναι στόχοι κάποιου URI */

UI element states pseudo-classes

Στο CSS3 εμφανίζονται για πρώτη φορά και κάποιες - 3 για την ακρίβεια - User Interface ψευδοκλάσεις. Αυτές χρησιμοποιούνται κυρίως στις φόρμες (τουλάχιστον έτσι έχω καταλάβει, διορθώστε με εάν κάνω λάθος) και λειτουργούν ανάλογα με την κατάσταση του user interface του browser.

  1. Πιο συγκεκριμένα, με την ψευδοκλάση :enabled, επιλέγουμε το στοιχείο του περιβάλλοντος χρήσης το οποίο βρίσκεται σε ενεργοποιημένη κατάσταση στον browser.
  2. Αντίθετα με την ψευδοκλάση :disabled, επιλέγουμε το στοιχείο του περιβάλλοντος χρήσης το οποίο βρίσκεται σε απενεργοποιημένη κατάσταση στον browser.
  3. Τέλος υπάρχει και η ψευδοκλάση :checked η οποία επιλέγει τα radio και checkbox elements εάν είναι επιλεγμένα.

Patterns

  1. E:enabled
  2. E:disabled
  3. E:checked

Παραδείγματα

input:enabled {
  background: red;
}

input:disabled {
  padding: 5px;
  border: 1px solid red;
}

input[type="checkbox"]:checked {
  background: red;
}

Negation pseudo-class

Μια πολύ σημαντική προσθήκη στο CSS3 ήταν και η πολυσυζητημένη negation ψευδοκλάση, που εξαιρεί τα elements που βρίσκονται μέσα στην παρένθεση. Μέσα στην παρένθεση μπορούμε να προσθέσουμε οποιονδήποτε απλό selector έτσι ώστε να εξαιρεθούν τα συγκεκριμένα elements από τον selector μας (λειτουργεί κατά κάποιον τρόπο σαν μια function που παίρνει για arguments απλούς selectors).

Pattern

  1. E:not(s)

Παράδειγμα

*:not(h1) {
  padding: 0;
  margin: 0;
}

General sibling combinator

Τέλος στο CSS3 προστέθηκε και ακόμα ένας πιο γενικός sibling combinator selector. Με το σύμβολο ~ λοιπόν, επιλέγουμε το δεύτερο element F (το element που εμφανίζεται δεξιά από το σύμβολο ~), το οποίο έχει κοινό γονιό (parent) με το το πρώτο element E (αυτό που βρίσκεται αριστερά από το σύμβολο ~) και εμφανίζεται στο DOM μετά από αυτό. Επειδή ίσως σας μπέρδεψα λίγο, ας δούμε μαζί το παρακάτω παράδειγμα. Στο παρακάτω παράδειγμα λοιπόν, το δεύτερο heading (h2) θα έχει κόκκινο χρώμα, μόνο εάν έχει κοινό γονιό με το h1 και εμφανίζεται στο DOM μετά από αυτό. Η διαφορά του με τον Adjacent sibling combinator (E + E) (που εμφανίστηκε στο CSS2 και παρουσιάστηκε στο προηγούμενο μέρος του άρθρου), είναι πως ο συγκεκριμένος κανόνας επιλέγει το δεύτερο element (το element που εμφανίζεται δεξιά από το σύμβολο +), έχει κοινό γονιό (parent) με το το πρώτο element (αυτό που βρίσκεται αριστερά από το σύμβολο +) και εμφανίζεται στο DOM ακριβώς μετά από αυτό (και όχι απλά μετά από αυτό).

Pattern

  1. E ~ F

Παράδειγμα

h1 ~ h2 { color: red; } /* ο δεύτερος header (h2) θα έχει κόκκινο χρώμα, στην παρακάτω markup. */

<h1>H1 Header</h1>
<p>Intro paragraph</p>
<h2>H2 Header</h2>

Επίλογος

Φτάσαμε επιτέλους στο τέλος της παρουσίασης όλων των επίσημων W3C selectors που υπάρχουν αυτήν την στιγμή στo CSS. Οι παραπάνω selectors είναι ότι πιο καινούργιο έχει να επιδείξει το CSS σε επίπεδο selector, και αν και πολλοί browsers - ιδιαίτερα παλιότεροι - δεν τους υποστηρίζουν, καλό θα είναι να τους έχετε υπόψη σας. Επίσης καλό θα είναι να ρίξετε μια ματιά στο πρώτο και δεύτερο μέρος του άρθρου, μιας και πολλές φορές βλέπω αξιόλογους web designers να ξέρουν αρκετούς CSS κανόνες (rules), αλλά να μην μπορούν να τους εφαρμόζουν στο έγγραφο εάν δεν το γεμίζουν με περιττά ids και κλάσεις…

Τέλος το CSS εξελίσσεται συνέχεια, και πιστεύω πως γρήγορα θα καταφέρει να γίνει και ένα πολύ καλό και web standard υποκατάστατο του Flash, οπότε όσο πιο πολλά γνωρίζετε γι’ αυτό, τόσο πιο εύκολα θα μπορέσετε να συνεχίσετε προς αυτήν την κατεύθυνση.