Ερωτήσεις για το στυλ του κοντέινερ

Κόμβος πηγής: 1765194

Έγραψα μερικά πρώιμες σκέψεις σχετικά με ερωτήματα στυλ κοντέινερ λίγο πριν. Είναι ακόμη νωρίς. Έχουν ήδη καθοριστεί στο Προδιαγραφή CSS Containment Module Level 1 (αυτή τη στιγμή βρίσκεται σε κατάσταση Πρόχειρου Συντάκτη), αλλά υπάρχουν ακόμα μερικές εκκρεμείς συζητήσεις που γίνονται.

Η βασική ιδέα είναι ότι μπορούμε να ορίσουμε ένα κοντέινερ και στη συνέχεια να εφαρμόσουμε στυλ υπό όρους στους απογόνους του με βάση το υπολογισμένο στυλ του.

@container ?  {
  /* conditional styles */
}

Το καλύτερο παράδειγμα που έχω δει μέχρι τώρα είναι η αφαίρεση πλάγιων γραμμάτων από κάτι παρόμοιο , , να όταν χρησιμοποιούνται σε ένα περιβάλλον όπου το περιεχόμενο είναι ήδη πλάγιο:

em, i, q {
  font-style: italic; /* default UA behavior */
}

/* When the container's font-style is italic, remove italics from these elements. */
@container style(font-style: italic) {
  em, i, q {
    font-style: normal;
  }
}

Αυτή είναι η γενική ιδέα. Αλλά αν δεν το ξέρατε, η Miriam Suzanne, η οποία είναι συντάκτρια των προδιαγραφών, διατηρεί ένα συνεχές και εμπεριστατωμένο σύνολο προσωπικές σημειώσεις για ερωτήματα στυλ κοντέινερ που είναι δημόσια διαθέσιμη. Ενημερώθηκε τις προάλλες και πέρασα λίγο χρόνο εκεί προσπαθώντας να τυλίξω το κεφάλι μου γύρω από πιο λεπτές πτυχές των ερωτημάτων στυλ. Είναι ανεπίσημα πράγματα, αλλά σκέφτηκα να σημειώσω κάποια πράγματα που μου ξεχώρισαν. Ποιός ξέρει? Ίσως είναι πράγματα που μπορούμε τελικά να περιμένουμε με ανυπομονησία!

Κάθε στοιχείο είναι ένα δοχείο στυλ

Δεν χρειάζεται καν να εκχωρήσουμε ρητά ένα container-name or container-type για να ορίσετε ένα κοντέινερ στυλ επειδή όλα είναι κοντέινερ στυλ από προεπιλογή.

Λοιπόν, βλέπετε το παραπάνω παράδειγμα που αφαιρεί τους πλάγιους χαρακτήρες; Σημειώστε ότι δεν προσδιορίζει ένα κοντέινερ. Μεταβαίνει απευθείας στο ερώτημα χρησιμοποιώντας το style() λειτουργία. Λοιπόν, ποιο κοντέινερ είναι υπό έρευνα; Θα είναι το άμεσος γονέας των στοιχείων λήψη των εφαρμοζόμενων στυλ. Και αν όχι αυτό, τότε είναι το επόμενο πλησιέστερο συγγενικό δοχείο που έχει προτεραιότητα.

Μου αρεσει αυτο. Είναι πολύ CSS-y για το ερώτημα να αναζητά μια αντιστοίχιση και, στη συνέχεια, να συνεχίζει να δημιουργεί φυσαλίδες μέχρι να βρει μια συνθήκη που ταιριάζει.

Ήταν δύσκολο για τον μικρό μου εγκέφαλο να καταλάβει γιατί μπορούμε να ξεφύγουμε από ένα σιωπηρό κοντέινερ που βασίζεται σε στυλ, αλλά όχι τόσο όταν έχουμε να κάνουμε με ερωτήματα διαστάσεων, όπως π.χ. size και inline-size. Η Miriam το εξηγεί όμορφα:

Τα ερωτήματα διαστάσεων απαιτούν css περιορισμός σχετικά με το μέγεθος, τη διάταξη και το στυλ του κοντέινερ, προκειμένου να αποφευχθούν οι βρόχοι διάταξης. Ο περιορισμός είναι ένα επεμβατικό πράγμα που εφαρμόζεται ευρέως, επομένως ήταν σημαντικό οι συγγραφείς να έχουν προσεκτικό έλεγχο σχετικά με τα στοιχεία που είναι (ή δεν είναι) μεγέθους δοχεία.

Τα ερωτήματα που βασίζονται σε στυλ δεν έχουν τον ίδιο περιορισμό. Δεν υπάρχει ήδη κανένας τρόπος στο CSS για τα στυλ απόγονος να έχουν αντίκτυπο στα υπολογισμένα στυλ ενός προγόνου. Επομένως, δεν απαιτείται περιορισμός και δεν υπάρχουν επεμβατικές ή απροσδόκητες παρενέργειες στην καθιέρωση ενός στοιχείου ως κοντέινερ ερωτήματος στυλ.

(Η υπογράμμιση δική μου)

Όλα καταλήγουν σε συνέπειες — από τις οποίες δεν υπάρχει καμία, δεδομένου ότι τα πάντα είναι ένα κοντέινερ ερωτήματος στυλ ακριβώς έξω από το κουτί.

  • Εάν βρεθεί ένα κοντέινερ: οι συνθήκες επιλύονται σε αυτό το δοχείο.
  • Εάν ταιριάζουν πολλά κοντέινερ: το πλησιέστερο σχετικό κοντέινερ έχει προτεραιότητα.
  • Εάν δεν βρεθούν αντιστοιχίες: unknown Επέστρεψαν.

Αυτό είναι το ίδιο «συγχωρητικό» πνεύμα όπως και το υπόλοιπο CSS.

Ένα κοντέινερ μπορεί να υποστηρίξει ερωτήματα διαστάσεων και στυλ

Ας υποθέσουμε ότι θέλουμε να ορίσουμε ένα ερώτημα στυλ χωρίς ρητή container-name:

@container style(font-style: italic) {
  em {
    font-style: normal;
  }
}

Αυτό λειτουργεί γιατί όλα τα στοιχεία είναι δοχεία στυλ, ανεξάρτητα από το container-type. Αυτό είναι που μας επιτρέπει να ρωτάμε έμμεσα τα στυλ και να βασιζόμαστε στην πλησιέστερη αντιστοίχιση. Και αυτό είναι απολύτως εντάξει, καθώς, και πάλι, δεν υπάρχουν αρνητικές παρενέργειες κατά τη δημιουργία δοχείων στυλ.

Πρέπει να χρησιμοποιήσουμε μια ρητή container-type για ερωτήματα διαστάσεων, αλλά όχι τόσο για ερωτήματα στυλ, καθώς κάθε στοιχείο είναι ένα ερώτημα στυλ. Αυτό σημαίνει επίσης ότι αυτό το δοχείο είναι και ένα στυλ και διαστατικό ερώτημα:

.card-container {
  container: card / inline-size; /* implictly a style query container as well */
}

Εξαίρεση ενός κοντέινερ από το ερώτημα

Ίσως δεν θέλουμε ένα κοντέινερ να συμμετέχει στη διαδικασία αντιστοίχισης. Εκεί μπορεί να είναι δυνατό να ρυθμιστεί container-type: none σε ένα στοιχείο.

.some-element {
  container-type: none;
}

Τα κοντέινερ ερωτημάτων σαφούς στυλ προσφέρουν περισσότερο έλεγχο για το τι τίθεται στο ερώτημα

Αν, ας πούμε, γράφαμε ένα ερώτημα στυλ για padding , δεν υπάρχει αξιόπιστος τρόπος για τον προσδιορισμό του καλύτερου αντιστοιχισμένου κοντέινερ, ανεξάρτητα από το αν εργαζόμαστε με ένα κοντέινερ με ρητό όνομα ή με τον πλησιέστερο άμεσο γονέα. Αυτό επειδή padding δεν είναι κληρονομική περιουσία.

Έτσι, σε αυτές τις περιπτώσεις, θα πρέπει να χρησιμοποιήσουμε container-name να ενημερώσει ρητά το πρόγραμμα περιήγησης από ποια κοντέινερ μπορούν να αντλήσουν. Μπορούμε ακόμη και να δώσουμε σε ένα κοντέινερ πολλά ρητά ονόματα για να ταιριάζει με περισσότερες συνθήκες:

.card {
  container-name: card layout theme;
}

Ω, και container-name δέχεται οποιονδήποτε αριθμό προαιρετικών και επαναχρησιμοποιήσιμη ονόματα για ένα δοχείο! Αυτή είναι ακόμη μεγαλύτερη ευελιξία όταν πρόκειται να βοηθήσετε το πρόγραμμα περιήγησης να κάνει μια επιλογή κατά την αναζήτηση αντιστοιχιών.

.theme {
  container-name: theme;
}
.grid {
  container-name: layout;
}
.card {
  container-name: card layout theme;
}

Αναρωτιέμαι κάπως αν αυτό θα μπορούσε επίσης να θεωρηθεί ως "υποχώρηση" σε περίπτωση που περάσει ένα κοντέινερ.

Τα ερωτήματα στυλ μπορούν να συνδυαστούν

Η or και and Οι χειριστές μάς επιτρέπουν να συνδυάσουμε τους σταθμούς για να διατηρήσουμε τα πράγματα στεγνά:

@container bubble style(--arrow-position: start start) or style(--arrow-position: end start) {
  .bubble::after {
    border-block-end-color: inherit;
    inset-block-end: 100%;
  }
}

/* is the same as... */
@container bubble style(--arrow-position: start start) {
  /* etc. */
}
@container bubble style(--arrow-position: end start) {
  /* etc. */
}

Εναλλαγή στυλ

Υπάρχει μια μικρή επικάλυψη μεταξύ των ερωτημάτων στυλ κοντέινερ και εργασίες που γίνονται για τον ορισμό α toggle() λειτουργία. Για παράδειγμα, μπορούμε να περάσουμε από δύο font-style αξίες, ας πούμε italic και normal:

em, i, q {
  font-style: italic;
}

@container style(font-style: italic) {
  em, i, q {
    font-style: normal;
  }
}

Δροσερός. Αλλά η πρόταση για CSS Toggles προτείνει ότι το toggle() η λειτουργία θα ήταν μια απλούστερη προσέγγιση:

em, i, q {
  font-style: toggle(italic, normal);
}

Αλλά οτιδήποτε πέρα ​​από αυτό το είδος της περίπτωσης δυαδικής χρήσης βρίσκεται εκεί toggle() είναι λιγότερο κατάλληλο. Ωστόσο, οι ερωτήσεις σχετικά με το στυλ είναι καλές. Η Miriam προσδιορίζει τρεις περιπτώσεις όπου τα ερωτήματα στυλ είναι πιο κατάλληλα από το α toggle():

/* When font-style is italic, apply background color. */
/* Toggles can only handle one property at a time. */
@container style(font-style: italic) {
  em, i, q {
    background: lightpink;
  }
}

/* When font-style is italic and --color-mode equals light */
/* Toggles can only evaluate one condition at a time */
@container style((font-style: italic) and (--color-mode: light)) {
  em, i, q {
    background: lightpink;
  }
}

/* Apply the same query condition to multiple properties */
/* Toggles have to set each one individually as separate toggles */
@container style(font-style: italic) {
  em, i, q {
    /* clipped gradient text */
    background: var(--feature-gradient);
    background-clip: text;
    box-decoration-break: clone;
    color: transparent;
    text-shadow: none;
  }
}

Τα ερωτήματα στυλ λύνουν το "Προσαρμοσμένο παραβίαση εναλλαγής ιδιοκτησίας"

Παρατηρήστε ότι τα ερωτήματα στυλ είναι μια επίσημη λύση για το "Τέχνασμα εναλλαγής προσαρμοσμένης ιδιότητας CSS". Εκεί, ορίσαμε μια κενή προσαρμοσμένη ιδιότητα (--foo: ;) και χρησιμοποιήστε την εναλλακτική μέθοδο διαχωρισμένη με κόμματα για να "ενεργοποιήσετε" και να απενεργοποιήσετε τις ιδιότητες όταν στη συνέχεια η προσαρμοσμένη ιδιότητα οριστεί σε πραγματική τιμή.

button {
  --is-raised: ; /* off by default */
  
  border: 1px solid var(--is-raised, rgb(0 0 0 / 0.1));
  box-shadow: var(
    --is-raised,
    0 1px hsl(0 0% 100% / 0.8) inset,
    0 0.1em 0.1em -0.1em rgb(0 0 0 / 0.2)
  );
  text-shadow: var(--is-raised, 0 -1px 1px rgb(0 0 0 / 0.3));
}

button:active {
  box-shadow: var(--is-raised, 0 1px 0.2em black inset);
}

#foo {
  --is-raised: initial; /* turned on, all fallbacks take effect. */
}

Είναι πολύ ωραίο, επίσης η πολλή δουλειά που τα ερωτήματα για το στυλ κοντέινερ καθιστούν ασήμαντη.

Ερωτήματα στυλ και περιεχόμενο που δημιουργείται από CSS

Για περιεχόμενο που παράγεται από το content Ιδιοκτησία του ::before και ::after ψευδοστοιχεία, το αντίστοιχο κοντέινερ είναι το στοιχείο στο οποίο δημιουργείται το περιεχόμενο.

.bubble {
  --arrow-position: end end;
  container: bubble;
  border: medium solid green;
  position: relative;
}

.bubble::after {
  content: "";
  border: 1em solid transparent;
  position: absolute;
}

@container bubble style(--arrow-position: end end) {
  .bubble::after {
    border-block-start-color: inherit;
    inset-block-start: 100%;
    inset-inline-end: 1em;
  }
}

Ερωτήματα στυλ και στοιχεία ιστού

Μπορούμε να ορίσουμε ένα στοιχείο Ιστού ως κοντέινερ και να το ρωτήσουμε κατά στυλ. Πρώτον, έχουμε το του συστατικού:


  
… …

Στη συνέχεια χρησιμοποιούμε το :host ψευδοστοιχείο ως δοχείο για να ορίσετε α container-name, μια container-typeκαι μερικά χαρακτηριστικά υψηλού επιπέδου σε αυτό:

:host {
  container: media-host / inline-size;
  --media-location: before;
  --media-style: square;
  --theme: light;
}

Στοιχεία μέσα στο μπορεί να ρωτήσει τις παραμέτρους του στοιχείο:

@container media-host style(--media-style: round) {
  [part='img'] {
    border-radius: 100%;
  }
}

Ποιο είναι το επόμενο βήμα;

Και πάλι, όλα τα πράγματα που έχω σημειώσει εδώ βασίζονται στις σημειώσεις της Miriam και αυτές οι σημειώσεις δεν υποκαθιστούν τις επίσημες προδιαγραφές. Αλλά είναι μια ένδειξη του τι συζητείται και πού θα μπορούσαν να προσγειωθούν τα πράγματα στο μέλλον. Εκτιμώ ότι η Miriam συνέδεσε μια χούφτα εξαιρετικών συζητήσεων που γίνονται ακόμα και μπορούμε να παρακολουθήσουμε για να παραμείνουμε στην κορυφή των πραγμάτων:

Σφραγίδα ώρας:

Περισσότερα από Κόλπα CSS