Gabin Aureche[Il faut être] capable de comprendre les besoins, d’en saisir les enjeux pour formuler une solution adéquate. Des réponses qui sont bien différentes s’il s’agit de développer une boîte email, un réseau social ou un site vitrine.
Le code n’est pour ainsi dire que le cadet des soucis d’un développeur. La vraie complexité se situe dans la proposition d’une solution pertinente, efficace et fiable en connaissance des différents enjeux.
Réactivité : les requêtes media
Introduction
Ils sont là, parmi nous, partout. Qui ? Les écrans bien sûr. Du PC 24" du bureau qui sert aussi de télé au smartphone 4,5" en passant par les ultrabooks 13" ou les portables de gamer 17", nous passons des heures par jours devant des écrans de toutes dimensions, connectés quasiment en permanence à Internet.
Cette grande variété de supports oblige à concevoir des sites web réactifs, capable de s'adapter instantanément aux changements de dimension d'écran (par exemple quand on tourne le smartphone) et aux supports les plus variés (y compris l'impression papier ou les synthétiseurs vocaux).
Dans le jargon du webdesigner, on parle de responsive design. Et ce n'est plus optionnel, puisque les smartphones représentent désormais (11/2018) près de 40% du trafic internet en Europe (50% dans le monde).
La réponse à cette nouvelle problématique tient en deux mots : media queries. Les « requêtes media » permettent de spécifier que telle ou telle règle CSS ne s'applique que lorsque le support possède certaines caractéristiques (taille d'écran par exemple).
Cependant, avant de se lancer dans les requêtes media, il convient déjà de s'assurer qu'on a pris quelques bonnes habitudes de « responsive web developer » :
-
Utiliser des conteneurs flexibles : flex ou grid.
En utilisant la propriété flex-wrap: wrap des Flexbox, on peut obtenir facilement une mise en page qui s'adapte à la taille de l'écran — du moins dans les cas simples.
- Éviter lorsque c'est possible de donner les dimensions en pixels, car cela rigidifie le design. Utiliser plutôt des unités flexibles, comme em qui s'adapte à la taille de police, ou des unités relatives (%, vw, vh).
Voici un exemple d'une page réactive simple, basée sur une Flexbox, et qui n'utilise pas de requête media (redimensionnez la page pour voir l'adaptation) :
La même page (code HTML/CSS identique) en changeant la largeur de l'iframe :
Si cela peut suffire lorsque le design reste très simple, les requêtes media se révèlent rapidement indispensables dès que la mise en page devient un peu plus élaborée.
La notion de viewport
Le viewport correspond à l'espace disponible sur la page entière, en pixels.
Cette notion semble simple à priori mais (il y a toujours un « mais » en CSS !) il y a certains points importants à souligner :
- Le viewport s'adapte en temps réel aux dimensions de la fenêtre. (Sur un écran de PC, cela se produit généralement lorsqu'on redimensionne la fenêtre avec la souris ; sur un smartphone, lorsqu'on change son orientation).
- Un iframe possède son propre viewport (qui correspond à ses dimensions au sein de la page hôte).
- Les navigateurs trichent ! Sur smartphone, les navigateurs déclarent un viewport souvent très supérieur aux dimensions réelles de l'écran. La raison est simple : beaucoup de sites web ne sont pas optimisés pour les smartphones. En déclarant un viewport comparable à celui d'un ordinateur de bureau, cela permet d'afficher en entier (en tout petit certes) un site web non prévu pour smartphone.
Le dernier point est très important ! Si notre site web est optimisé pour les smartphones, il faut impérativement le dire au navigateur, en lui interdisant de tricher sur les dimensions de l'écran.
On utilise pour cela la balise meta name="viewport".
Si votre site web est réactif, vous devez donc le préciser en ajoutant dans l'entête de votre fichier HTML la ligne suivante :
<meta name="viewport" content="width=device-width, initial-scale=1"/>
Explications :
- width=device-width indique que l'on prend comme largeur de viewport la taille réelle de l'écran (ou du moins, celle déclarée par le système d'exploitation)
- initial-scale=1 indique que par défaut, le coefficient de zoom est 1 (pas de zoom)
Régler correctement le viewport est primordial, car pour construire un site web réactif nous ferons sans cesse référence au viewport par la suite.
Remarques :
- à l'avenir, la définition du viewport devrait se faire directement dans les fichiers CSS à l'aide de la directive @viewport, mais à l'heure actuelle (2018) celle-ci n'est pas encore supportée par les navigateurs.
- D'autres paramètres d'affichage peuvent être définis via le viewport, plus de détails ici par exemple.
Une fois le viewport correctement réglé, nous allons pouvoir préciser quelles règles CSS doivent s'appliquer en fonction du support, en utilisant les fameuses « requêtes média ».
Syntaxe des requêtes média
Écrire une requête directement dans le CSS
Dans un fichier CSS, une requête media commence par @media suivi d'une condition.
Par exemple :
@media screen and (max-width: 640px)
Dans cet exemple, on indique qu'on cible un média ayant un écran (par opposition à l'impression ou la synthèse vocale), dont la largeur maximale est 640px.
On indique que certaines règles ne s'appliqueront que dans ce cas :
@media screen and (max-width: 640px) {
nav>ul {
flex-direction: column;
}
nav>ul>li {
margin: 0px 20px;
}
}
Autres possibilités
On peut aussi créer une feuille de style spécifique pour certaines catégories de média, et ne les charger que si les conditions sont remplies. Deux méthodes existent :
- On peut lier cette feuille de style à une page HTML sous conditions :
<link rel="stylesheet" media="screen and (max-width: 640px)" href="smallscreen.css" type="text/css" />
- On peut réaliser un import conditionnel de cette feuille de style au tout début de la feuille de style principale.
@import url('smallscreen.css') screen and (max-width: 640px);
Types de média
On peut spécifier dans une requête média les types de média suivants :
- print : impression
- screen : affichage à l'écran
- speech : synthèse vocale
Par défaut, le type de média est all.
Propriétés courantes
Les nouvelles spécifications (Media Queries Level 4 et 5) proposent de nombreuses propriétés... pas forcément encore implémentées dans les navigateurs. Nous nous limiterons ici à quelques propriétés classiques parmi les plus utiles, qui sont bien supportées par tous les navigateurs modernes.
- width : largeur du viewport en pixels ;
- height : hauteur du viewport en pixels ;
- orientation : landscape (paysage) ou portrait ;
- resolution : résolution de l'écran (densité de pixel) en dpi (dot per inch) ;
- aspect-ratio : fraction représentant le rapport largeur/hauteur du viewport.
Pour écrire des inégalités, il faut préfixer les propriétés avec min- et max-. Par exemple, (min-width: 400px) signifie
width >= 400px
. Cette dernière écriture est d'ailleurs été ajoutée récemment aux standards CSS, mais n'est en 2018 pas encore supportée par les navigateurs.
Dans une requête média, le couple (propriété: valeur) doit impérativement être encadré par des parenthèses.
Quelques exemples :
- (min-width: 400px) and (min-height: 300px) : on sélectionne les supports ayant une largeur d'au moins 400px et une hauteur d'au moins 300px ;
- (min-resolution: 50dpi) and (max-resolution: 100dpi) : on sélectionne les supports ayant une résolution comprise entre 50 et 100 dpi (inclus) ;
- (min-aspect-ratio: 16/9) and (max-aspect-ratio: 4/3) : on sélectionne les supports ayant un rapport largeur/hauteur compris entre 16/9 et 4/3.
Comme on le voit ci-dessus, l'opérateur booléen and permet de réaliser des encadrements.
On peut lister plusieurs condition séparées par une virgule ; dans ce cas il suffit qu'une des conditions soit remplie. La virgule joue donc le rôle du
OU
.
L'opérateur booléen not existe mais a un fonctionnement un peu particulier : il doit être au début de la requête et il s'applique à toute la requête (il permet donc d'effectuer la requête contraire).
Plus d'informations sur les media queries...
Quelle requête média permet de sélectionner les supports ayant une résolution d'au moins 150dpi et une hauteur d'écran comprise entre 500 et 800px, sauf si le ratio largeur/hauteur est inférieure à 16/9, ou alors l'impression en mode paysage?
Un exemple récapitulatif
Voici un exemple de page réactive, affichée sur un écran de 600 pixels de large.

La même page, sur un écran de 1000 pixels de large :

- Testez par vous-même en ouvrant cette page et en redimensionnant la fenêtre. Quelles stratégies ont été utilisées pour s'adapter ?
- Adaptez vos pages web précédentes pour rendre votre site web réactif, c'est-à-dire agréable à lire en particulier sur smartphone. Pour faire les tests, vous pouvez simplement
redimensionner la fenêtre de votre navigateur, et regarder le rendu de votre site. La mise en page doit s'adapter sans que des barres de défilement horizontal apparaissent en bas de la page !
Vous pouvez aussi tester en faisant apparaître votre site dans une iframe dont vous fixerez les dimensions à 600*800 pixels par exemple (idem : il ne doit pas y avoir de barres de défilement horizontal).
Les variables CSS
Lorsque l'on crée un site web réactif, il est pratique de pouvoir créer des paramètres, qui en changeant de valeur permettront par exemple de modifier toutes les couleurs en une fois.
On peut par exemple proposer un mode « jour » et un mode « nuit » avec des palettes de couleurs adaptées. (À l'avenir, la propriété light-level devrait permettre de proposer facilement sur smartphone une feuille de style adaptée en fonction de la luminosité ambiante).
Les variables CSS vont nous permettre cela, mais nous allons voir qu'elles sont assez différentes des variables utilisées en programmation.
De manière générale, l'utilisation de variables CSS permet de rendre le code plus lisible (à condition de leur donner des noms parlants) et surtout plus évolutif (cela aide à conserver par exemple une charte graphique unifiée, en permettant de remplacer en une ligne une couleur par une autre dans tout le document).
Définir une variable CSS
Pour définir une variable CSS, on utilise la syntaxe suivante :
--ma-variable: mavaleur;
Autrement dit, on déclare une variable CSS comme si on définissait une propriété CSS normale, mais en la préfixant avec deux tirets : --.
Utiliser une variable CSS
On lit la valeur d'une variable CSS en utilisant la syntaxe suivante :
propriete_css: var(--ma-variable);
La propriété propriete_css prendra alors comme valeur celle de --ma-variable.
Variables CSS et héritages
Les variables CSS sont locales : elles ne sont pas définies pour tout le document, mais pour un ou plusieurs éléments donnés, selon le sélecteur utilisé. Elles se propagent ensuite par héritage à tous les descendants, mais jamais aux parents ni aux frères.
Un fils ne peut donc pas modifier le comportement d'un parent.
Supposons maintenant qu'on ait défini une variable
--var1
pour un élément
parent
. Que se passe-t-il si l'on définit une variable de même nom l'élément
enfant
, fils de parent ? En procédant ainsi, on définit en fait une nouvelle variable, complètement indépendante de la première, et qui va se propager aux descendants de
enfant
. Cela n'aura donc aucune incidence sur parent.
Lorsqu'on veut déclarer une variable globale (c'est-à-dire qui sera définie pour tous le document), on utilise généralement la pseudo-classe :root (on pourrait utiliser aussi html comme sélecteur voire même body) :
:root {
--couleur-principale: orange;
--indentation: 2em;
}
Démonstration
Prenons une page web classique, comme celle-ci :
<body>
<h1>Mon site web</h1>
<main>
<p>Ceci est un texte d'introduction.</p>
<section>
<h2>Première partie</h2>
<p>Blablabla...</p>
</section>
<section>
<h2>Deuxième partie</h2>
<p>Blablabla...</p>
</section>
</main>
</body>
Nous allons définir une variable CSS --couleur-principale qui s'appliquera à toute le document, pour pouvoir facilement changer cette couleur par la suite :
/* On aurait pu aussi utiliser « :root » à la place de « html ». */
html {
--couleur-principale: SandyBrown;
}
h1 {
background-color: var(--couleur-principale);
color: white;
}
p {
border-left: 5px solid var(--couleur-principale);
}
h2 {
color: var(--couleur-principale);
}
Avec un peu de mise en forme, voici le résultat :
En rajoutant un peu de Javascript, on peut très facilement obtenir une page web possédant plusieurs thèmes au choix.
Dans l'exemple suivant, utilisez le menu déroulant (en haut à droite de la page) pour changer dynamiquement le thème.
Mais que fait la police ?
Hey, what the font !?
Vous aviez intégralement réalisé votre site web avec cette magnifique police choisie avec soin (non pas celle-ci !)... mais au moment de visualiser votre site sur le PC d'un ami, catastrophe ! Une vieille police par défaut s'affiche à la place, et toute votre mise en page est cassée...
Première remarque : votre site web doit être réactif (voir partie précédente !).
Posez-vous toujours la question suivante : que se passe-t-il si ma police ne se charge pas ?
- Évitez lorsque c'est possible de coder en dur (c-à-d. en pixels) les dimensions. N'hésitez pas à utiliser des unités « souples » comme em qui s'adapte à la taille de la police.
- Faites des tests ! Changez la police et regardez le rendu de votre site. Il y a toujours un risque, même avec les méthodes que nous verrons ci-dessous, que la police souhaitée ne s'affiche pas pour une raison X ou Y.
Ceci étant dit, le choix d'une police à la fois élégante et adaptée participe de manière non négligeable à l'esthétique et à la lisibilité d'un site web. Comment utiliser une police non disponible à priori sur l'ordinateur du client ?
Intégrer sa police au site web
La règle @font-face permet d'intégrer une police personnalisée dans un site web.
Sa syntaxe est la suivante :
@font-face {
/* On donne un nom à la police : */
font-family: "Ma police";
/* On indique son emplacement sur le serveur : */
src: url("fonts/ma_police.otf");
}
On l'utilise ensuite comme n'importe quelle police.
body {
/* On reprend le nom défini dans @font-face : */
font-family: "Ma police";
}
Il est vivement conseillé de fournir au moins une famille de police de repli en cas de problème.
/*
Ici, on indique d'utiliser si possible "Ma police", sinon la police "Times",
ou au pire n'importe quelle police de type "serif" (police à empattement).
*/
body {
font-family: "Ma police", "Times", serif;
}
C'est l'occasion de rappeler qu'il existe 5 grandes familles de polices de caractères.
- serif : police avec empattement (petites « pattes » sur les lettres, en rouge ci-dessous).
Souvent plus lisible à l'impression.
- sans-serif : police sans empattement. Souvent plus lisible à l'écran.
- monospace : police de chasse fixe, c-à-d. que toutes les lettres font la même largeur. Pratique pour afficher du code.
- cursive : police imitant l'écriture manuscrite.
- fantasy : police décorative ou inclassable.
Voir aussi la classification des polices usuelles sur Wikipédia...
Esthétiquement parlant, il est conseillé d'utiliser une même police sur tout le site, sauf pour quelques éléments particuliers (titres par exemple) où l'on peut utiliser une police qui tranche franchement sur le reste.
- Quelles familles de police sont utilisées sur cette page web, et où ?
- Utilisez au moins une police personnalisée pour les titres principaux de vos TD.
Pensez à regrouper tous vos polices dans un même dossier de votre site web, par exemple web/fonts/.
Quelques remarques importantes :
- Tous les navigateurs et tous les systèmes d'exploitation ne supportent pas toutes les types de police. Il est conseillé d'utiliser une police au format WOFF, supportée par tous les navigateurs récents (des convertisseurs existent). Dans tous les cas, faites des tests en variant les plateformes et les navigateurs !
- Ce n'est pas parce que vous réussissez à télécharger une police sur Internet, ou même que vous l'aviez d'origine sur votre ordinateur, qu'elle est forcément libre de droits ! Lorsque vous développez un site internet, particulièrement dans un milieu professionnel, il faut vérifier qu'une police que vous choisissez d'embarquer est libre, ou que vous avez acquis les droits pour l'inclure dans une page web (et pas seulement l'utiliser à titre personnel).
- Les fichiers de police peuvent parfois peser très lourd. Un élément à prendre en compte, car cela peut ralentir l'affichage de votre page web la première fois. Et la 4G n'est pas disponible partout !
À noter qu'il existe également des générateurs de code CSS pour les polices, qui peuvent assurer également la conversion automatique d'un format à un autre.
Utiliser l'API GoogleFont
Google met à disposition un catalogue de polices, utilisable gratuitement sur n'importe quel site.
Il suffit ensuite de lier la feuille de style de Google à son site. Par exemple :
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet"/>
C'est une solution simple à mettre en œuvre et qui résout également les problèmes juridiques éventuels.
Le revers de la médaille, c'est que cela rend évidemment le site dépendant de Google. (En particulier, Google peut très bien décider de suspendre le service ou de rendre l'API payante à l'avenir. Après tout, le cas s'est déjà produit pour d'autres services Google...)
Dégradés et motifs
Utiliser une image de fond
On utiliser la propriété background-image pour afficher une image de fond dans une boîte.
Comme pour la couleur de fond, l'image de fond s'arrêtera à la bordure de la boîte (autrement dit, elle remplira la marge intérieure (padding) mais pas la marge extérieure (margin)).
Il est possible d'utiliser tous les types d'images supportés, en particulier JPG et PNG pour des images matricielles (bitmap), par exemple des photos, et SVG pour des images vectorielles, par exemples des motifs ou un dessin fait par ordinateur.
Les différents types de dégradés
Principe général
Pour créer un dégradé, on spécifie une couleur de début et une couleur de fin. L'ordinateur effectue alors une interpolation linéaire entre ces deux couleurs.
Il est possible de spécifier un ou plusieurs points d'arrêt intermédiaires, ce qui revient en fait à enchaîner plusieurs dégradés. Les positions de ces points d'arrêts sont spécifiées en pourcentage (0% correspondant au point de départ et 100% au point d'arrivée).
En CSS, les dégradés se définissent à l'aide de la propriété background-image (et non background-color).
Les dégradés linéaires
On utilise la fonction linear-gradient().
Il faut au minimum préciser une couleur de départ (couleur de gauche par défaut) et une couleur d'arrivée (couleur de droite par défaut).
div {
background-image: linear-gradient(red, yellow);
}
Par défaut, le dégradé est vertical (de haut en bas), mais on peut préciser son angle :
div {
background-image: linear-gradient(45deg, red, yellow);
}
Il est aussi possible de rajouter des points d'arrêt intermédiaires, en précisant leur position :
div {
background-image: linear-gradient(45deg, red, yellow 70%, orange);
}
Par défaut, les points d'arrêt sont espacés régulièrement :
div {
background-image: linear-gradient(45deg, indigo, blue, green, yellow, orange, red);
}
Remarque : le vert semble ici dominer sur le jaune, malgré l'espacement régulier. Une interpolation régulière n'apparaît pas toujours ainsi à l'œil ; la manière dont le cerveau humain analyse les couleurs est en effet assez complexe.
Il est aussi possible de jouer sur la transparence. D'ailleurs, transparent peut-être utilisé à la place d'une couleur.
div {
background-image: linear-gradient(180deg, orange, transparent);
}
En glissant une image par dessous, on obtient ceci :
Les dégradés radiaux
Un dégradé radial est un dégradé de forme circulaire ou plus généralement elliptique.
On utilise la propriété radial-gradient().
Comme pour les dégradés linéaires, il faut au minimum préciser une couleur de départ (couleur de gauche par défaut) et une couleur d'arrivée (couleur de droite par défaut).
div {
background-image: radial-gradient(yellow, blue);
}
Par défaut, le dégradé a une forme elliptique et son centre est celui de la boîte.
On peut imposer au dégradé une forme circulaire même si la boîte n'est pas carrée.
div {
background-image: radial-gradient(circle, yellow, blue);
}
Par défaut, le centre du dégradé correspond au centre du bloc, mais on peut choisir un autre centre :
div {
background-image: radial-gradient(circle at bottom right, yellow, blue);
}
On peut évidemment ajouter des points d'arrêt intermédiaires :
div {
background-image: radial-gradient(circle at 200px 100px, white, yellow 10%, orange 15%, blue 40%, darkblue 60%, black);
}
Plus d'informations sur les différentes possibilités...
Éditeur en ligne
Vous pouvez également utiliser un éditeur en ligne de dégradés, par exemple celui-ci.
Pour aller plus loin : paramétrage fin du fond
Qu'on utilise une image, des dégradés ou une couleur unie pour le fond, il existe ensuite de nombreux paramètres permettant d'affiner son fonctionnement.
Par défaut, les propriétés s'appliquant au fond possèdent les valeurs suivantes :
background-image: none;
background-position: 0% 0%;
background-size: auto auto;
background-repeat: repeat;
background-origin: padding-box;
background-clip: border-box;
background-attachment: scroll;
background-color: transparent;
Détaillons ces différents paramètres :
Propriété | Exemples de valeurs | Détails |
---|---|---|
background-image |
url('img/pic.png') linear-gradient(#e66465, #9198e5) radial-gradient(#e66465, #9198e5) |
Adresse d'une image de fond ou dégradé. |
background-position |
décalage_horizontal décalage_vertical center top bottom 50px right 100px ... |
|
background-size |
largeur hauteur cover contain |
|
background-repeat |
repeat repeat-x repeat-y no-repeat |
Si l'image est plus petite que le fond, précise si l'image doit être répétée.
|
background-clip |
border-box padding-box content-box |
Précise jusqu'où le fond s'étend :
|
background-attachment | scroll fixed |
|
background-color | #ccc #a1bde5 rgba(100, 200, 40, .5) red | Toute couleur valide en CSS. Pensez à jouer sur l'opacité éventuellement. |
Créer des motifs complexes
Il est possible de combiner plusieurs fonds, en les séparant par une virgule, par exemple :
p {
background-image: url('img/fond1.png'),
url('img/fond2.png'),
linear-gradient(red, orange);
background-color: orange;
}
Le navigateur dessinera, dans cet ordre :
- la couleur de fond (background-color, ici orange), qui s'affichera donc tout en dessous,
- le dernier fond de la liste des fonds (background-image, ici linear-gradient(red, orange))
- l'avant-dernier fond (ici fond2.png)
- ...
- le premier fond de la liste, qui s'affichera donc au dessus de tous les autres (ici fond1.png).
Pour que cela ait un intérêt, il faut évidemment qu'au moins une partie des fonds supérieurs soient transparents (sinon on ne verra que le premier fond de la liste puisqu'il s'affiche par dessus les autres !)
Dans cet exemple, on a défini une couleur blanc translucide, et on affiche deux dégradés successifs par dessus la couleur de fond, pour créer un motif à pois :
/*
On définit un blanc translucide (opacité 0,2) :
*/
--col: rgba(255, 255, 255, .2);
/*
On crée un fond bleu :
*/
background-color: cornflowerblue;
/*
Nos deux dégradés radiaux : un petit rond blanc translucide et un grand, avec un fond transparent.
*/
background-image: radial-gradient(var(--col), var(--col) 10%, transparent 12%, transparent),
radial-gradient(var(--col), var(--col) 20%, transparent 22%, transparent);
/*
On répète le motifs (et donc les cercles) tous les 50 pixels.
*/
background-size: 50px 50px, 50px 50px;
/*
On décale le 2e motif, pour éviter que grand rond et petit rond se superposent !
*/
background-position: 0 0, 25px 25px;
Les motifs suivants sont obtenus simplement en jouant sur la transparence :
Les fonction repeating-linear-gradient() (voir ici) et repeating-radial-gradient (voir ici) permettent également de créer facilement des motifs dégradés qui se répètent.
Si vous souhaitez réaliser des motifs complexes en pur CSS, je vous conseille cet article de Lea Verou (traduit en français).
À partir d'un certain niveau de complexité, il vaut cependant mieux créer des motifs en SVG et les appliquer ensuite comme image de fond. N'importe quel bon logiciel de dessin vectoriel est capable de générer du SVG. En logiciel libre (et gratuit), la référence est Inkscape, qui est à la fois puissant et ergonomique (disponible sous Windows/Linux/MacOs).
Transformations et animations
Bravo !
Vous avez suivi semaine après semaine tous ces TD sans ciller et assimilé au moins les grands principes de CSS. Après l'effort le réconfort ! Les transformations et animations ne sont pas des éléments essentiels d'un site web ; utilisées avec parcimonie, elles permettent cependant de lui donner cette petite touche finale qui peut faire la différence. Et puis, avouons-le, c'est aussi l'occasion de se faire plaisir ! :)
Les transformations CSS
Principales transformations 2D
La propriété CSS transform permet d'appliquer une transformation à une boîte. Par défaut, cette transformation est statique ; nous verrons dans la dernière partie comment animer nos transformations.
Pour l'instant, répertorions les transformations 2D les plus courantes :
Transformation | Syntaxe |
---|---|
Rotation | rotate(20deg) |
Translation | translate(70px, 30px) |
Agrandissement | scale(2, 0.5) |
Cisaillement | skew(20px, 10px) |
Rotation
Translations
Agrandissements
Cisaillements
On peut également directement rentrer la matrice de la transformation...
Composer des transformations
Pour appliquer successivement plusieurs transformations, il suffit de les écrire les unes à la suite des autres.
transform: rotate(20deg) translate(10px, 20px);
Attention, les transformations géométriques ne sont pas commutatives !
L'ordre dans lequel on applique les transformations est important :
Lorsqu'on écrit plusieurs transformations à la suite, la dernière est appliquée en premier (comme pour la notation g∘f en mathématiques).
Exemple :
transform: rotate(20deg) translate(10px, 20px);
On applique la translation, puis la rotation.
Définir l'origine
Par défaut, lorqu'on applique une transformation sur un élément, c'est le centre de l'élément qui joue le rôle de centre du repère.
Par exemple, une rotation s'effectue par rapport au centre de l'élément.
La propriété transform-origin permet de modifier le centre du repère :
transform-origin: left bottom;
Dans l'exemple ci-dessous, la même rotation de 45 degré est appliquée avec différentes origines :
Transformez cette page HTML pour obtenir le résultat suivant :

Cette image a été créée uniquement avec du code HTML+CSS :

Saurez-vous la reproduire simplement en ajoutant des règles CSS au code HTML suivant ?
<body>
<!-- Le main fera le ciel -->
<main>
<div id="voiture">
<!-- Le haut de la voiture -->
<div id="haut">
<!-- Les séparations des vitres -->
<div></div>
<div></div>
</div>
<!-- Le bas de la voiture -->
<div id="bas"></div>
<!-- Les deux roues -->
<div class="roue" id="r1">✴</div>
<div class="roue" id="r2">✴</div>
</div>
</main>
<!-- Le footer peut servir à faire les bandes blanches de la route -->
<footer></footer>
</body>
Animer vos pages
Créer des transitions simples
La propriété transition-duration permet de créer facilement une transition d'un état à un autre.
Il faut au préalable indiquer à quelles propriétés (background-color, width, transform...) s'appliquent cette transition à l'aide de la propriété transition-property :
div {
background-color: red;
/*
Les transitions se feront sur la couleur de fond et la transformation (rotation ici).
*/
transition-property: background-color transform;
transition-duration: 1s;
}
div:hover {
transform: rotate(180deg);
background-color: blue;
}
Passez le pointeur de la souris sur le carré pour voir l'animation de transition :
On peut affiner le comportement de l'animation de transition dans le temps à l'aide de la propriété transition-timing-function. Plus d'informations ici...
Déclarer une animation complexe (@keyframes)
Pour créer des animations plus complexes, on détaille les différentes étapes de l'animation à l'aide de la propriété @keyframes, et on lui donne un nom
.La syntaxe de base est la suivante :
/*
On donne un nom à l'animation pour pouvoir l'utiliser ensuite.
Ici, elle s'appelera simplement « mon_animation ».
*/
@keyframes mon_animation {
from {
/* Valeur de départ de la propriété. */
propriete: valeur;
...
}
to {
/* Valeur d'arrivée de la propriété. */
propriete: valeur;
...
}
}
La grande différence entre ces animations et les transitions simples vues précédemment, c'est qu'on peut définir des étapes intermédiaires, ce qui permet de créer des animations complexes :
/*
On donne un nom à l'animation pour pouvoir l'utiliser ensuite.
Ici, elle s'appelera simplement « mon_animation ».
*/
@keyframes mon_animation {
from {
/* Valeur de départ de la propriété. */
propriete: valeur;
...
}
25% {
/* Valeur de la propriété au bout de 25% du temps. */
propriete: valeur;
...
}
to {
/* Valeur d'arrivée de la propriété. */
propriete: valeur;
...
}
}
Appliquer une animation
La propriété animation-name permet d'appliquer une animation définie par @keyframes à un élément.
Il faut également préciser la durée totale de l'animation à l'aide de la propriété animation-duration.
Voici un premier exemple complet :
div {
height: 100px;
width: 100px;
background-color: red;
animation-name: mon_animation;
animation-duration: 5s;
}
@keyframes mon_animation {
from {
margin-left: 100%;
margin-top: 0px;
background-color: lightgreen;
}
75% {
margin-left: 40%;
margin-top: 200px;
transform: rotate(180deg);
background-color:orange;
}
to {
margin-left: 0%;
transform: rotate(360deg);
}
}
Dans l'animation ci-dessus, on a rajouté les règles animation-iteration-count: infinite et animation-direction: alternate pour répéter l'animation à l'infini dans un mouvement de va-et-vient.
Principales propriétés d'une animation
Propriété | Exemples de valeurs | Détails |
---|---|---|
animation-delay |
|
Délai avant le démarrage de l'animation |
animation-direction |
|
|
animation-duration |
|
Durée totale de l'animation (hors répétitions éventuelles) |
animation-iteration-count |
|
Nombre d'itérations, c'est-à-dire nombre de fois où l'animation sera jouée. |
animation-name | mon_animation | Le nom qui a été utilisé pour créer l'animation avec @keyframes |
animation-play-state |
paused running |
|
animation-timing-function |
|
|
animation-fill-mode |
|
Définit l'état de l'élément à la fin de l'animation :
|
Dans l'exemple suivant, l'animation se met en pause (animation-play-state: paused) dès que le pointeur de la souris passe sur l'image :
Plus de détails sur MDN web docs...
Animez le CSS suivant :
Le résultat doit ressembler à ceci :
Recréez l'animation suivante (sans regarder la solution !) :
Les transformations 3D
Si vous souhaitez aller plus loin, vous pouvez lire par exemple ce tutoriel sur les transformations et animations 3D en CSS.
Et après ?
Dans le cadre de ce TD, nous nous sommes limités à du pur CSS.
Le CSS n'est pas un langage de programmation, mais un langage de présentation ; en particulier, il n'est pas possible de mémoriser un état en CSS. Pour pouvoir changer de feuille de style selon les préférences de l'utilisateur, par exemple, il faudra utiliser un peu de Javascript en complément.
Le CSS est également assez verbeux : il manque notamment la notion de sous-classe, et les variables CSS sont assez limitées. On peut dépasser ces limitations en utilisant un préprocesseur CSS : on écrit les feuiles de styles dans un langage étendant les fonctionnalités de CSS. Ces feuilles de styles étendues sont alors compilées soit de manière statique (avant de publier la page web), soit de manière dynamique sur l'ordinateur de l'utilisateur en utilisant Javascript. Les principaux préprocesseurs CSS sont LESS et Sass.
Il existe également des Frameworks permettant de créer plus facilement des sites webs sans avoir à s'occuper de la compatibilité des différents navigateurs, ni avoir à gérer directement la réactivité du site (support des smartphones notamment). Parmi les plus connus, citons Bootstrap et Foundation.
Mentionnons enfin les CMS (Wordpress, Drupal, Plone, Sharepoint, Mediawiki... pour n'en citer que quelques uns) qui permettent de créer des sites web dynamiques sans mettre les mains dans le code ou presque...