Bloc englobant et empilements

CSS

Au programme

  1. Bloc englobant (position absolute, relative, etc.)
  2. Contexte d'empilement (z-index)

Le Bloc Englobant

où vais-je me placer dans mon parent ?

référent pour le placement des boîtes

.enfant
.parent

Le Bloc Englobant

Les éléments dans le flux (propriété position qui vaut static ou relative) se placent dans la zone de Content, par défaut le plus en haut à gauche

cas des éléments dans le flux

.enfant
.parent
.parent {
  display: block;
}
.enfant {
  display: block;
}

Le Bloc Englobant

Le Bloc Englobant des éléments positionnés en absolute est la zone de padding de l'ancêtre le plus proche dont la valeur de position est différente de static (fixed, absolute, relative ou sticky).

cas des éléments absolute

.enfant
.parent
.grand-parent {
  display: block;
}
.parent {
  display: block;
}
.enfant {
  display: block;
}
.grand-parent

Le Bloc Englobant

Le Bloc Englobant des éléments positionnés en absolute est la zone de padding de l'ancêtre le plus proche dont la valeur de position est différente de static (fixed, absolute, relative ou sticky).

cas des éléments absolute

.enfant
.parent
.grand-parent {
  display: block;
}
.parent {
  display: block;
}
.enfant {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
}
.ancetre
.grand-parent

Le Bloc Englobant

Le Bloc Englobant des éléments positionnés en absolute est la zone de padding de l'ancêtre le plus proche dont la valeur de position est différente de static (fixed, absolute, relative ou sticky).

cas des éléments absolute

.enfant
.parent
.grand-parent {
  display: block;
  position: relative;
}
.parent {
  display: block;
}
.enfant {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
}
.grand-parent

Le Bloc Englobant

Le Bloc Englobant des éléments positionnés en absolute est la zone de padding de l'ancêtre le plus proche dont la valeur de position est différente de static (fixed, absolute, relative ou sticky).

cas des éléments absolute

.enfant
.parent
.grand-parent {
  display: block;
  position: relative;
}
.parent {
  display: block;
  position: relative;
}
.enfant {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
}
.grand-parent

Le Bloc Englobant

Le Bloc Englobant des éléments positionnés en fixed est le Viewport (zone d'affichage de la fenêtre)

cas des éléments fixed

.enfant
.parent
.grand-parent {
  display: block;
  position: relative;
}
.parent {
  display: block;
  position: relative;
}
.enfant {
  display: block;
  position: fixed;
  top: 0;
  left: 0;
}
.ancetre
.grand-parent

Le Bloc Englobant

Le Bloc Englobant des éléments positionnés en absolute ou fixed peut aussi être l'ancêtre ayant :

  • une propriété transform ou perspective,
  • une propriété will-change qui vaut transform ou perspective
  • une propriété filter différente de none
  • une propriété contain qui vaut paint.

cas particuliers

.ancetre {
  display: block;
  position: relative;
}
.parent {
  display: block;
  transform: translate(0);
}
.enfant {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
}
.enfant
.parent
.ancetre

Exercice !

bloc englobant

Le Contexte d'empilement

Hello z-index: 9999, my old friend

z-index (n.f. Propriété CSS qui ne fonctionne jamais)
Inventée par le Démon pour répandre le mal dans le monde du Web et souvent évoquée dans certaines incantations de magie noire.

z-index

mais... pourquoi faire ?

un Menu déroulant

une Tooltip

une Modale

un Bandeau cookies

un Datepicker

z-index

pour briller en société...

Plus grande valeur possible ?

Pas de limite dans les spécifications CSS mais en pratique valeur signée de 32 bits (soit une plage de −2147483648 à +2147483647)... ou calc(infinity) qui vaut 3.40282e+38

1

Valeurs les plus utilisées ?

Les dix valeurs les plus utilisées au monde sont : 1, 2, 10, 0, 100, 1000, 9999, -1, 999 et 3.

2

Conventions de nommage ?

Les trois conventions les plus utilisées sont :
1- $zindex-modal, $zindex-tooltip (sémantique à la Bootstrap)
2- z-20, z-30 (utilitaire à la Tailwind)
3- z-null, z-lowest, z-low.

3

Valeur par défaut ?

La valeur par défaut n'est pas un nombre, mais la valeur "auto".

4

Mais pourquoi le nom "z-index" ?

Le W3C reconnaît qu'il aurait dû nommer la propriété "z-order" plutôt (source)

5

OK super, et donc comment est créé un Contexte ?

Stacking Context

Contexte d'Empilement

Périmètre permettant d'organiser l'empilement des éléments qui y sont situés

Stacking Order

Niveau d'Empilement

Niveau d'empilement sur l'axe Z au sein d'un Contexte d'Empilement

Principe de base : les éléments sont systématiquement empilés selon leur Niveau d'Empilement et uniquement au sein d'un même Contexte d'empilement.

D'accord j'ai compris, mais comment modifier l'Ordre ?

Stacking Order

Niveau d'Empilement

Stacking Order

en résumé

Trois règles définissent le niveau d'empilement d'un élément en cas de superposition sur l'axe de la profondeur (z)

Selon une croyance ancestrale, seule la propriété z-index permet de modifier l'ordre d'empilement sur l'axe Z.
C'est faux.

Stacking Order

(Niveau d'Empilement)

Cas des Éléments "non positionnés"

Les éléments non positionnés se placent (et s'empilent) dans leur ordre d'apparition dans le HTML (DOM)

1

Règles

Stacking order

1) Éléments non positionnés

couche racine (élément <html>)
<html>
  <div #1>
  <div #2>
</html>

#1

élément non positionné

#2

élément non positionné

Les éléments non positionnés se placent (et s'empilent) dans leur ordre d'apparition dans le HTML (DOM)

#2 {
  margin-top: -100px;
}

Cas des Éléments "positionnés"

Les éléments positionnés (ou transformés), se placent au-dessus des éléments non positionnés.

2

Cas des Éléments "non positionnés"

Les éléments non positionnés se placent (et s'empilent) dans leur ordre d'apparition dans le HTML (DOM)

1

Stacking Order

(Niveau d'Empilement)

Règles

Stacking order

2) Éléments positionnés et non positionnés

couche racine (élément <html>)
<html>
  <div #1>
  <div #2>
</html>

#1

élément positionné

#2

élément non positionné

Les éléments positionnés (ou transformés), se placent au-dessus des éléments non positionnés.

#1 {
  position: relative;
}

Cas des Éléments ayant un z-index

La propriété z-index modifie l'ordre d'empilement des éléments positionnés selon sa valeur. Plus la valeur est grosse, plus l'élément est au-dessus de la pile.

3

Cas des Éléments "positionnés"

Les éléments positionnés (ou transformés), se placent au-dessus des éléments non positionnés.

2

Cas des Éléments "non positionnés"

Les éléments non positionnés se placent (et s'empilent) dans leur ordre d'apparition dans le HTML (DOM)

1

Stacking Order

(Niveau d'Empilement)

Règles

Stacking order

3) Éléments positionnés et z-index

couche racine (élément <html>)
<html>
  <div #1>
  <div #2>
  <div #3>
</html>

#1

z-index: 1;

#2

z-index: 2;

La propriété z-index modifie l'ordre d'empilement des éléments positionnés (au sein du Contexte d'Empilement en cours).

#2

z-index: -1;
#1 {
  z-index: 1;
}
#2 {
  z-index: 2;
}
#3 {
  z-index: -1;
}

Qui peut bénéficier de z-index ?

aparté

Élément positionné :
un élément dont la propriété CSS position a pour valeur relative, absolute, fixed ou sticky.
Par défaut, les éléments d'une page ne sont pas positionnés (ils sont en position: static).

1

Flex item ou Grid item:
un élément enfant direct d'un flex-container ou d'un grid-container

2

Seuls deux types d'éléments peuvent avoir un z-index.

Stacking order

récapitulatif

Trois règles définissent le niveau d'empilement :

1

z-index modifie le niveau d'empilement :
plus la valeur est grosse, plus l'élément est au-dessus de la pile.

2

z-index ne s'applique pas à tout le monde :
l'élément doit être positionné, ou être flex-item ou grid-item.
c'est tout. vraiment.

3

  1. élément non positionné
  2. élément positionné (ou transformé) 
  3. élément avec z-index

Stacking context

Contexte d'empilement

Stacking context

en résumé

Le Contexte d'Empilement définit le périmètre des règles d'empilement qu'on vient de voir.

Un élément peut créer un Contexte d'Empilement pour gérer l'empilement de ses descendants.

Pour bien nous embrouiller, z-index modifie l'Ordre d'Empilement... mais crée également un nouveau Contexte d'Empilement. Et c'est pas tout...

(oui, fallait suivre un peu)

Un Contexte d'Empilement s'applique à un conteneur pour gérer l'empilement de ses descendants

1

z-index (mais pas que lui) définit l'Ordre d'Empilement des éléments au sein d'un Contexte d'Empilement

2

Certaines propriétés CSS créent un nouveau Contexte d'Empilement

4

L'élément <html> constitue le premier Contexte d'Empilement

3

Stacking context

(contexte d'empilement)

parent de classe .container
<div .container>
  <div #1>
  <div #2>
  <div #3>
</div>

#1

z-index: 1;

#2

z-index: 2;

La portée de z-index est celle de son Contexte d'Empilement
(Ici, le parent .container ne crée pas de Contexte d'Empilement et div#3 se place en dessous)

#3

z-index: -1;
#1 {
  z-index: 1;
}
#2 {
  z-index: 2;
}
#3 {
  z-index: -1;
}

Stacking context

(contexte d'empilement)

<div .container>
  <div #1>
  <div #2>
  <div #3>
</div>

La portée de z-index est celle de son Contexte d'Empilement
(Ici, le parent .container crée un Contexte d'Empilement)

.container {
  z-index: 1;
}
#1 {
  z-index: 1;
}
#2 {
  z-index: 2;
}
#3 {
  z-index: -1;
}

Stacking context

(contexte d'empilement)

parent de classe .container

#1

z-index: 1;

#2

z-index: 2;

#3

z-index: -1;
<html>
  <div #1>
    <div #3>
  <div #2>
</html>

#1

z-index: 1;

#2

z-index: 2;

La portée de z-index est celle de son Contexte d'Empilement
(Ici, #3 est contenu dans #1 et chacun crée un Contexte d'Empilement)

#3

z-index: 1337;
#1 {
  z-index: 1;
}
#2 {
  z-index: 2;
}
#3 {
  z-index: 1337;
}
couche racine (élément <html>)

Stacking context

(contexte d'empilement)

Un Contexte d'Empilement s'applique à un conteneur pour gérer l'empilement de ses descendants

1

z-index définit l'Ordre d'Empilement des éléments au sein d'un Contexte d'Empilement

2

Certaines propriétés CSS créent un nouveau Contexte d'Empilement

4

L'élément <html> constitue le premier Contexte d'Empilement

3

Stacking context

(contexte d'empilement)

qui crée un Contexte d'Empilement ?

aparté

Un nouveau Contexte d'Empilement (Stacking Context) est créé pour chaque élément correspondant à l'un de ces critères : 

  • un élément racine <html>
  • un élément avec z-index  autre que auto
  • un élément en position fixed ou sticky
  • un élément avec opacity inférieur à 1
  • un élément avec transform autre que none
  • un élément avec filter autre que none
  • un élément avec will-change (de valeur transform ou filter)
  • un élément avec isolation (de valeur isolate)
  • un élément avec clip-path
  • un élément avec mask

Il existe 17 façons de créer un Stacking Context;
Il n'en existe aucune pour en annuler un.

(alors n'en mets pas partout au départ)

#1

élément

#2

élément

Exemples d'éléments :

  • z-index,
  • en fixed, en sticky,
  • transformé,
  • filter,
  • avec opacity <1,
  • avec isolation,
  • etc.

uniquement si positionné ou flex-item ou grid-item

Contexte d'Empilement
Ordre d'Empilement
  1. dans le Flux naturel
  2. élément positionné ou transformé
  3. z-index non auto

Récap général

t'as compris ?

.main
.header
.navigation
.nav-item
.nav-item
.nav-item
.header {
  position: relative;
}
.main {
  position: relative;
}

Hypothèse 1

.main
.header {
  position: relative;
}
.main {
  position: relative;
}
.subnav {
  position: absolute;
  z-index: 1337;
}
.header
.navigation
.nav-item
.nav-item
.nav-item
.subnav

?

Hypothèse 2

.main
.header {
  position: relative;
}
.main {
  position: relative;
}
.subnav {
  position: absolute;
  z-index: 1337;
}
.header
.navigation
.nav-item
.nav-item
.nav-item
.subnav

!

?

Réponse : 1 

.main
.header {
  position: relative;
}
.main {
  position: relative;
}
.subnav {
  position: absolute;
  z-index: 1337;
}
.header
.navigation
.nav-item
.nav-item
.nav-item
.subnav

!

  1. .header, .main et .subnav sont tous les 3 dans le même Contexte d'Empilement (html ?)
  2. L'Ordre d'Empilement est donc :
    .subnav (parce que z-index)
    .main (parce que positionné + 2e dans le DOM)
    .header (parce que positionné + 1er dans le DOM)

!

INTERLUDE

j'ai retenu des trucs ?

INTERLUDE

j'ai retenu des trucs ?

... relative est la valeur par défaut de position

Faux !

la valeur par défaut de position est static

vrai ou faux ?

span { position: relative; }

... permet d'appliquer un
z-index sur l'élément

Vrai !

z-index s'applique sur un élément positionné

vrai ou faux ?

span { position: relative; }

... change le niveau d'empilement

Vrai !

un élément positionné passe au-dessus des éléments non positionnés

vrai ou faux ?

span { position: relative; }

... crée un contexte d'empilement

Faux !

position: relative seul ne suffit pas à créer un stacking context (il faut ajouter z-index par exemple)

vrai ou faux ?

span { position: relative; }

... permet d'appliquer un
z-index sur l'élément

Faux !

z-index s'applique uniquement sur un élément positionné ou un flex-item / grid-item

vrai ou faux ?

span { opacity: 0.99; }

... crée un contexte d'empilement

Vrai !

opacity < 1 crée un stacking context.
donc opacity 0 et 0.99 créent un SC, mais pas opacity 1

vrai ou faux ?

span { opacity: 0.99; }

Faux !

le stacking order est modifié par les éléments positionnés, transformés ou ayant un z-index non auto

vrai ou faux ?

span { opacity: 0.99; }

... change le niveau d'empilement

Vrai !

vrai ou faux ?

j'ai mal à la tête

Project Wallace

z-index : combien et quelle valeur max ?

Fil rouge