国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Maison interface Web tutoriel CSS % CSS?: récupérer et exfiltrer des bits de données générées par le serveur intégrées dans un SVG animé

% CSS?: récupérer et exfiltrer des bits de données générées par le serveur intégrées dans un SVG animé

Jan 18, 2025 am 06:10 AM

Il s'agit d'un suivi direct de l'Obtention de données de réponse API 32 bits en CSS

En CSS, 16 bits de données de réponse, placés à la fois dans la largeur intrinsèque et dans la hauteur intrinsèque, constituaient une énorme amélioration par rapport à l'impossibilité d'obtenir du tout les données de réponse de l'API (sans JavaScript)...

Cependant, dans les jours qui ont suivi, mon esprit s'est penché dans une direction?:
Ce serait bien plus amusant si c'était 16 bits 32 fois au lieu de seulement deux fois.

Gif recording of a harsh terminal app setting several integer values to an array of variables one at a time

Emballer 512 bits dans un SVG pour l'exfiltration

Je méditais avant de me coucher et j'ai été frappé par une autre pensée inspirée -

"Et s'il était possible au document image lui-même d'animer sa propre taille intrinsèque ?"

La cha?ne habituelle de réalisations après une pensée inspirée, chacune a montré une compréhension de la fa?on dont cela pouvait être accompli... J'avais juste besoin de comprendre si un tel type d'image existait.

J'ai attrapé mon téléphone et j'ai cherché parmi tous les formats d'images animées que je connaissais, pour voir si l'un d'entre eux en était capable. svg, webp, apng, gif, peut-être des formats vidéo bizarres?? Je n'en ai pas trouvé.

Le matin, quelque chose en moi m'a dit de continuer à creuser sur SVG.

J'ai essayé le CSS intégré, les requêtes multimédias, les définitions utilisées, les définitions davantage utilisées, en plongeant dans les nombreux documents d'animation SVG, en essayant de les tromper et en lisant d'autres idées et propriétés liées à l'animation - rien ne pouvait me laisser définir la hauteur ou la largeur.

Mais ce dernier lien m'a fait réfléchir...

... et viewBox?? J'aurais d'autres obstacles à surmonter mais... Est-ce que possible d'animer ?

vvv
C'EST !!
^^^

Trier l’espace des solutions

Maintenant, le problème est que si vous ne définissez pas les attributs de largeur et de hauteur sur l'élément racine svg, puis essayez d'utiliser le svg comme contenu sur un pseudo, il restitue 0px x 0px car c'est un document vectoriel et n'a plus de taille intrinsèque.

J'ai donc recherché et ajouté préservationAspectRatio... Toujours 0x0... mais ensuite dans mon CSS, j'ai épinglé la largeur à 10px et laissé le rapport hauteur/largeur préservé de la viewBox déterminer la hauteur (que je peux modifier avec un animation intégrée dans le SVG) aaet... l'élément html le contenant a atteint la hauteur attendue.

:3

S'il n'y avait qu'une seule image, cela prenait mes 32 bits d'origine et les coupait en deux?; puisqu'une seule dimension peut être exfiltrée tandis que l'autre est statique.

MAIS ! Maintenant, ma 2ème dimension était le temps et la première est à la merci du temps, donc il y a plus qu'assez de données disponibles.

Comme c'est excitant?!

J'ai appris tout ce que je pouvais sur la fa?on de contr?ler l'animation dans les SVG et j'ai créé un script c?té serveur pour générer mon premier SVG animé?:

<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return $viewBoxXYWidth . ((string) ($val));
  }, $data, range(1, $datalen));

  $dur = $datalen * 0.33; // total seconds

  $keytimeStep = 1 / ($datalen); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $datalen - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>

(pourquoi php ?! - parce que j'avais déjà un serveur pour lequel je payais depuis des années, configuré pour exécuter php dès le départ.... Et même si j'ai gagné merveilleusement ma vie en connaissant JavaScript et node très bien, parfois c'est amusant de rechercher chaque fonction, opérateur et syntaxe pour progresser dans quelque chose que vous savez que vous pouvez faire sans conna?tre les détails. mdr)

Maintenant, passons à mon premier % CSS?: récupérer et exfiltrer des bits de données générées par le serveur intégrées dans un SVG animé de l'article précédent pour voir CSS répondre et changer de taille --vars au fur et à mesure que le SVG avance?:

Confirmé ! On peut lire le changement de taille. Comme dans l'article précédent, au final, il utilisera la technique de mesure view-timeline à la place de cette technique tan(atan2()).

Il cuit mon processeur, nous voudrons donc le supprimer du contenu une fois l'exfiltration terminée.

Conceptuellement, comment exfiltrer le temps 1D de manière procédurale

La démo ci-dessus n'est pas très utile en elle-même. Il rapporte une copie de la hauteur chaque fois qu'elle est là, mais nous devons la sauvegarder... et à quoi sert un tas de valeurs de 16 bits si vous ne savez pas et ne pouvez pas faire confiance à la commande??

Je sais que je peux accumuler des valeurs en CSS avec le CPU Hack et déterminer mathématiquement quel --var met à jour les valeurs entrantes au lieu de simplement conserver sa valeur précédente, donc je ne m'inquiéterai pas spécifiquement du CSS. Comment, de manière générale, pourrait-on exfiltrer 1D au fil du temps ?

Les valeurs Sentinelles à la rescousse !

La taille de la zone de mesure que nous utilisons ne DOIT pas être limitée à 16 bits même si je souhaite limiter les paquets de données eux-mêmes à 16 bits. Nous pouvons donc y emmener aussi des sentinelles. css-api-fetch est livré avec la capacité de gérer des valeurs allant jusqu'à 99999, ce qui est bien au-dessus de 65535 (le plafond de 16 bits).

Alors, que devons-nous savoir??

Quels problèmes pourrions-nous rencontrer??

Si deux valeurs de nos données sont identiques dos à dos, nous avons besoin d'une interruption pour savoir qu'il s'agit de deux paquets distincts. J'ai déjà décidé que nous visions 512 bits, nous avons donc besoin que l'animation du SVG ait un maximum de 32 images de données de 16 bits, avec des images sentinelles entre les deux...

Si le processeur semble lourd, l'animation SVG peut sembler ignorer entièrement des étapes discrètes. Cela signifie que nous avons besoin d’un moyen de toujours savoir à quelle étape nous nous trouvons. Ainsi, plut?t qu'une seule sentinelle ? entre les trames de données ?, utilisons l'index de données (basé sur 1 comme les sélecteurs CSS nth-*) comme valeur sentinelle, ce qui en fait sa propre étape discrète avant l'étape discrète affichant les données pour cet index.

Indice Sentinelle -> données -> indice sentinelle -> données...

Cela nous permet également de savoir quand il boucle, potentiellement lorsque nous atteignons la sentinelle 1.

Mais comment savoir qu'il n'est pas passé à une trame de données différente et nous a accidentellement fait l'enregistrer dans le mauvais emplacement ?

Nous devons le laisser boucler et continuer jusqu'à ce que ce soit correct, et la meilleure fa?on de savoir si les données sont correctes est une somme de contr?le?! Nous avons donc besoin d'une autre trame de données et d'une sentinelle pour cette valeur.

Création de l'algorithme de somme de contr?le

Je pourrais utiliser css-bin-bits pour XOR toutes les données, mais c'est assez lourd et n'est nécessaire nulle part ailleurs - optons pour une alternative simple à faire en CSS.

Mathématiquement, si vous prenez une valeur de 16 bits, la divisez par 256 (plancher en entier), et reprenez la valeur de 16 bits modulo par 256, vous obtenez les octets hauts et bas. Ajoutez ces valeurs de 8 bits ensemble et vous êtes à 9 bits. Cela semble être une approche de somme de contr?le raisonnable, revenons-y cependant.

Nous n'avons pas besoin de rester dans la plage de 16 bits pour calculer la somme de contr?le tant que la somme de contr?le finale est de 16 bits, alors résumons tout (jusqu'à) 32 valeurs.

Nous devons cependant faire attention aux écritures de stockage incorrectes dues à des images sautées, alors ajoutons les valeurs d'index paires deux fois pour qu'il y ait un semblant d'ordre.

Cette somme, 16 valeurs de bits, 32 fois, plus 16 fois supplémentaires, équivaut à environ 22 bits. Divisez et modulez 11 bits de chaque c?té en revenant à la pensée précédente, puis additionnez-les ensemble, donnant 12 bits comme réponse de somme de contr?le.

Cela semble raisonnable... Ce n'est pas complètement à l'abri des erreurs, mais le SVG devrait sauter plusieurs étapes pour le gacher de manière à PEUT-êTRE générer la même somme de contr?le maintenant... Dans tous les cas, renvoyons également les données length et incluez-le également dans la somme de contr?le, simplement en l'ajoutant comme dernière étape de notre somme de contr?le. La longueur maximale des données (nombre de valeurs de 16 bits que nous voulons gérer) n'est que de 32, donc l'ajout de la valeur de longueur aux 12 bits ne nous pousse pas loin de 16 bits. Ouais?!

spoiler?: c'est c'est ce que j'ai fait, mais CSS est devenu avec perte quelque part autour de 21 bits, donc je l'ai divisé et j'ai effectivement fait le même algorithme mais en plus petits morceaux à la fois. Le c?té serveur utilise l'alg exactement comme décrit.

Techniquement, avec la configuration que nous avons décrite, peu importe l'ordre dans l'animation tant que chaque sentinelle vous indique quel index l'image suivante est censée être dans le données.

Encore une chose, mettons la valeur de longueur des données en premier dans la réponse et ajoutons également une sentinelle pour cela (sentinelle dans l'animation SVG avant la valeur, comme pour le reste des données).

Cela fait 34 sentinelles. La hauteur de la viewBox SVG ne peut pas être 0 et CSS bénéficiera du fait de permettre à 0 de ne représenter aucune donnée en interne, alors disons que nous avons 35 sentinelles avec 0 délibérément inutilisé.

Toutes les trames de données sont désormais intégrées dans le SVG avec 35 ajoutées à leur valeur. Les valeurs des données de longueur et de somme de contr?le sont éGALEMENT ajoutées à 35 à la valeur de la bo?te de visualisation. Les hauteurs de viewBox dans l'animation SVG représentant les sentinelles auront des valeurs 0 à 34 (en sautant 0) et chacune nous indiquera exactement ce que représente l'image suivante dans l'animation SVG.

C?té CSS, on vérifie juste si la mesure brute est supérieure à 34, c'est de la donnée donc soustrayez-lui 35, si elle est inférieure à 35, c'est une sentinelle.

A meme picture of Charlie Day from It's Always Sunny in Philadelphia with a crazed look standing in front of a board covered in paper with red lines connecting them hectically

Commencer à exfiltrer les 512 bits avec CSS

Après avoir terminé le c?té PHP pour générer l'animation SVG comme détaillé, j'ai réfléchi à des manières spécifiques de commencer le CSS pour ce processus d'exfiltration.

Voici le code PHP !
<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return $viewBoxXYWidth . ((string) ($val));
  }, $data, range(1, $datalen));

  $dur = $datalen * 0.33; // total seconds

  $keytimeStep = 1 / ($datalen); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $datalen - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>

Il existe plusieurs fa?ons d'y parvenir en CSS et potentiellement bien d'autres à venir avec les ajouts récents de spécifications.

Ma première approche est conceptuellement la plus simple?: utiliser une chronologie de vue pour chaque élément de données et faire la même chose encore et encore. Cela fonctionnait mais je gémissais à travers mes progrès, mécontent de voir à quel point c'était dégo?tant. Cela fera près de 40 animations sur :root si je continue.

Alors je me suis endormi.

Quand je me suis réveillé, je suis resté allongé là plusieurs instants à regarder par la fenêtre en souriant avec ce sentiment de bourdonnement qui vient de se réveiller ou de méditer, puis un feu de pensées s'est précipité dans ma tête. Je me suis retourné, j'ai attrapé mon cahier et le stylo le plus proche, je me suis assis dans mon lit et j'ai commencé à écrire l'algorithme pour l'exfiltrer avec seulement 6 animations CSS.

my chicken scratch handwriting on a single piece of lined notebook paper with arrows pointing to a couple of nested boxes detailing the method described below

Littéralement résolu sur papier?; C’est EXACTEMENT comment il est mis en ?uvre.

Je me suis levé, j'ai ouvert mon ordinateur, j'ai ignoré mon travail précédent et j'ai ouvert un nouveau % CSS?: récupérer et exfiltrer des bits de données générées par le serveur intégrées dans un SVG animé.

J'y ai mis en place les 4 éléments html indiqués parmi les scratch de poulet, puis j'ai inondé le panneau CSS de notes autour de 4 sélecteurs de classes vides leur correspondant. Il ne sera plus sur :root maintenant mais nous pouvons placer tout ce qui en dépend à l'intérieur.

Aucune fonctionnalité n'a été ajoutée jusqu'à ce que les notes soient copiées à partir du papier et écrites de manière plus précise dans % CSS?: récupérer et exfiltrer des bits de données générées par le serveur intégrées dans un SVG animé.

Quand j'ai eu fini, j'ai juste lu les notes et j'ai commencé à mettre en ?uvre ce qu'elles disaient, jusqu'au résultat final.

(J'ai écrit "20" au lieu de "35" car j'allais tester avec 256 bits)

Je vais expliquer comment cela fonctionne. En raison de la vue-chronologie et de la portée de la chronologie, vous pouvez configurer les données pour qu'elles circulent sous la forme d'une bouteille de Klein si vous pouvez imaginer la surface s'animant et étant aspirée dans le "trou", remontant vers le haut étroit jusqu'au bas. sur la surface, gagnant en taille et en complexité à travers les couches de dom, puis remontant à travers le trou noir jusqu'à la conscience supérieure (:root).

Il est principalement cyclique verticalement (plut?t que principalement horizontalement ou statiquement cyclique)

Exfiltrer les 512 bits avec CSS

Les notes que nous avons légèrement modifiées et rendues plus claires?:

Test 256 -> 512 finale

et j'ai ajouté un n?ud de présentation à l'intérieur, ce qui est génial car je peux également montrer les éléments internes pendant l'exécution de l'algorithme.

mais voici les notes finales sans tout le bruit d'implémentation et de présentation. Cela décrit exactement comment tout cela fonctionne.

Ce n'est peut-être pas une bonne chose pour un article d'avoir autant de détails intégrés en externe, mais je vais décomposer chaque morceau pour montrer comment il est mis en ?uvre.

Contr?leur principal

En haut de cette structure se trouvent 4 valeurs de timeline et leurs animations. Alors mettons-les dedans.

L'élément clé du flux de données que cela permet est que cela nous donne la possibilité de remonter les données imbriquées profondément dans le DOM vers un h?te (portée de la chronologie). Ce n'est pas efficace, nous voulons donc limiter la fréquence à laquelle nous le faisons. Chaque propriété enregistrée et son animation peuvent héberger verticalement une seule donnée. La valeur des données est déterminée par la position en ligne ou en bloc d'un élément quelque part au plus profond de la structure - nous y reviendrons plus tard.

(voir l'exemple de boucle précédemment intégré ci-dessus pour une image plus claire du flux de données)

Les quatre éléments de données que nous récupérons ici sont?:

--xfl-cpu-phase - il s'agit d'une valeur numérique de 0 à 4 qui signale quelle phase du CPU Hack est actuellement en cours d'exécution. (une seule ? image ? du CPU Hack correspond à 4 à 5 images de rendu CSS, une boucle des phases ? coche ? le CPU Hack) Je le démontrerai plus spécifiquement plus tard dans cet article.

--xfl-raw-data - ceci héberge la hauteur du SVG partout où se trouve le SVG dans son cycle d'animation. Nos données brutes. Comme dit précédemment, si cette valeur est inférieure à 35, cette étape discrète de l'animation SVG est une valeur sentinelle. S'il est supérieur à 34, ce pas discret de l'animation SVG est notre valeur 16 bits 35, ce qui correspond à ce qu'indiquait la sentinelle précédente.

--xfl-data-type - il s'agit de la valeur sentinelle la plus récente. Cette valeur ne change pas jusqu'à ce que la prochaine sentinelle soit rencontrée. Il y a un délai d'une image CSS entre la définition de --xfl-raw-data et la définition de cette valeur.

--xfl-data-value - c'est la valeur actuelle des données après que 35 ait été soustraite de la valeur brute, ou 0 si nous n'avons pas encore atteint cette étape de la séquence. Il y a un délai d'une image CSS entre la définition de --xfl-data-type et la définition de cette valeur.

J'ai également enveloppé de manière préventive svg-animation-current-state-reporter dans une condition qui n'a que des fonctionnalités et ne charge que le SVG animé lorsque le processus est incomplet. (donc tous les éléments internes sont supprimés de la mémoire et le lourd svg animé est supprimé du rendu lorsque nous avons terminé)

Les valeurs des images clés vont d'une valeur maximale pour cette donnée à 0. J'expliquerai plus tard pourquoi elles sont à l'envers - recherchez l'image des cartes Uno Reverse.

Exfiltrateur de processeur

Ensuite, nous mettons en place le passe-partout de base pour un CPU Hack

Le modèle CPU Hack suit simplement un modèle de nom de variable pour configurer les animations de capture et de levage.

Si nous avons 1 entier --xfl\1 que nous voulons faire défiler horizontalement (dans le temps), nous l'enregistrons et nous mettons en place des animations de capture et de levage comme ceci?:

<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return $viewBoxXYWidth . ((string) ($val));
  }, $data, range(1, $datalen));

  $dur = $datalen * 0.33; // total seconds

  $keytimeStep = 1 / ($datalen); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $datalen - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>

Terminez ensuite l'affectation cyclique sur l'élément .cpu-exfiltrator où sont hébergées les deux animations CPU. Je vais le faire pour une seule des valeurs pour l'instant?:

<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  // add 35 to all the values so we can use 0 to 34 for sentinels. 0 = CSS-side sentinel, 1-32 = data frames, 33 = length, 34 = checksum
  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return ($viewBoxXYWidth . ((string) $index) . '; ' . $viewBoxXYWidth . ((string) ($val + 35)));
  }, $data, range(1, $datalen)); // 1 up to 32 = indicator that next frame is the value(+35) for that index(1-based)

  // no matter how many are in the array, '33' indicates the next frame is data length, which is used in the checksum too
  array_unshift($frames, $viewBoxXYWidth . '33; ' . $viewBoxXYWidth . ((string) ($datalen + 35))); // + 35 b/c data
  // unshift so the length is (hopefully) the first value read and a sense of progress can be reported

  $fullsum = 0;

  for ($x = 0; $x <= ($datalen - 1); $x++) {
    // double the odd ones so there's some semblance of order accounted for
    // the odd ones with 0 based index is the even ones on the CSS side
    $fullsum += ($data[$x] + (($x & 1) * $data[$x]));
  }

  $checksum = floor($fullsum / 2048) + ($fullsum % 2048) + $datalen + 35; // + 35 because it's data

  // no matter how many are in the array, '34' indicates the next frame is checksum
  array_push($frames, $viewBoxXYWidth . '34; ' . $viewBoxXYWidth . $checksum);

  $actualNumItems = count($frames) * 2;

  $dur = $actualNumItems * 0.33; // total seconds

  $keytimeStep = 1 / ($actualNumItems); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $actualNumItems - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>

Dans Chrome, ils ne feront pas de cycle statique (deviendront la valeur initiale) à moins que les deux animations ne s'exécutent en même temps. Ce qui est un effet secondaire FANTASTIQUE de ce qui est probablement une optimisation des animations en pause définissant des propriétés numériques.

Enfin, puisque nous utilisons une nouvelle version automatique du CPU Hack (vous n'avez pas besoin de :survoler pour cycler les phases comme dans le hack original), nous cablé dans la var --xfl-cpu-phase du précédent (hébergé sur l'élément parent ici, afin que nous puissions utiliser des requêtes de style pour y répondre) et contr?ler l'état de lecture de nos animations.

Nous produisons également --cpu-next-phase qui sera ensuite remonté vers le haut et définirons la valeur suivante pour --xfl-cpu-phase en utilisant sa position d'affichage et sa portée de chronologie.

J'ai ajouté une phase supplémentaire pour maintenir le CPU Hack en pause jusqu'à ce que la mesure de l'animation SVG soit verrouillée avec succès dans le prochain --xfl-data-type

<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return $viewBoxXYWidth . ((string) ($val));
  }, $data, range(1, $datalen));

  $dur = $datalen * 0.33; // total seconds

  $keytimeStep = 1 / ($datalen); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $datalen - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>

(comme c'est le cas maintenant, le type de données est toujours 0, donc une fois la phase suivante connectée, cela bouclera déjà le CPU Hack. Une fois que nous aurons une sentinelle de type de données, elle ne bouclera pas tant que nous n'aurons pas l'a effacé délibérément avec la sentinelle 0)

Plus tard, nous ajouterons également la condition notée pour empêcher le démarrage de la phase 1 du processeur jusqu'à ce que toutes les données soient en place. Cela garantira qu'entre le type de données (sentinelle) verrouillé et la valeur des données (brutes - 35) verrouillée, nous voulons laisser le CPU Hack dans sa phase de capture. C'est donc "prêt à être prêt" comme pourrait le dire Abraham Hicks.

Je vais continuer et enregistrer les 32 valeurs plus la somme de contr?le et la longueur que nous attendons de l'animation SVG.

étant donné que l'enregistrement de --xfl\1 à --xfl\32 est un gros bloc et que les animations du processeur ne sont également que des passe-partout, je vais déplacer toutes celles-ci au bas de la configuration du hack pour qu'elles soient ignorées à l'avenir.

Piratage automatique du processeur

Cela cable la phase suivante du processeur jusqu'à la valeur --xfl-cpu-phase

<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  // add 35 to all the values so we can use 0 to 34 for sentinels. 0 = CSS-side sentinel, 1-32 = data frames, 33 = length, 34 = checksum
  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return ($viewBoxXYWidth . ((string) $index) . '; ' . $viewBoxXYWidth . ((string) ($val + 35)));
  }, $data, range(1, $datalen)); // 1 up to 32 = indicator that next frame is the value(+35) for that index(1-based)

  // no matter how many are in the array, '33' indicates the next frame is data length, which is used in the checksum too
  array_unshift($frames, $viewBoxXYWidth . '33; ' . $viewBoxXYWidth . ((string) ($datalen + 35))); // + 35 b/c data
  // unshift so the length is (hopefully) the first value read and a sense of progress can be reported

  $fullsum = 0;

  for ($x = 0; $x <= ($datalen - 1); $x++) {
    // double the odd ones so there's some semblance of order accounted for
    // the odd ones with 0 based index is the even ones on the CSS side
    $fullsum += ($data[$x] + (($x & 1) * $data[$x]));
  }

  $checksum = floor($fullsum / 2048) + ($fullsum % 2048) + $datalen + 35; // + 35 because it's data

  // no matter how many are in the array, '34' indicates the next frame is checksum
  array_push($frames, $viewBoxXYWidth . '34; ' . $viewBoxXYWidth . $checksum);

  $actualNumItems = count($frames) * 2;

  $dur = $actualNumItems * 0.33; // total seconds

  $keytimeStep = 1 / ($actualNumItems); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $actualNumItems - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>

Il y a ici un passe-partout CSS pour faire de l'élément un conteneur de défilement et le mettre hors écran. La partie importante est?:

view-timeline?: --xfl-cpu-phase inline?;

qui indique où se situe le bord droit de ce pseudo-élément dans son parent de 100 px de large, connectez-le comme un "progrès" de la gauche à notre animation qui passe de 0 à 4... Donc 25 px est terminé à 25 %, qui correspond à 1 lorsque 25?% est compris entre 0 et 4.

picture of two 'reverse' cards from Uno image provenant d'une recherche Google menant à Twitter

TECHNIQUEMENT, l'animation est de 4 à 0 et TECHNIQUEMENT, elle mesure à partir du bord droit du pseudo au fur et à mesure que la vue progresse vers la droite. Ainsi, le pseudo de 25?px de large est à 75?% de la droite de son parent de défilement de 100?px de large et correspond à une valeur de 1 lorsque 75?% est compris entre 4 et 0.

Il est plus facile de comprendre si vous ne traitez pas cognitivement les mathématiques inverses et acceptez simplement que le résultat final est une simple progression de 0 à 4 car la valeur maximale dans l'animation est de 4 (en ignorant encore une fois que l'animation démarre à 4).

écrivons également l'état prêt qui maintient le CPU en phase 0 jusqu'à ce que les données soient prêtes. La note est à la ligne 64 de nos démos?:

Données prêtes = type de données > 0 && données de trame brutes - 35 === valeur de données

<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return $viewBoxXYWidth . ((string) ($val));
  }, $data, range(1, $datalen));

  $dur = $datalen * 0.33; // total seconds

  $keytimeStep = 1 / ($datalen); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $datalen - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>

Attendez, === en CSS ?

Ceux-ci sont assez obsolètes maintenant et je les ferais différemment aujourd'hui, écrits avant que clamp() ne soit la référence, mais j'ouvre toujours ce vieux codepen pour copier sans réfléchir des comparateurs numériques lorsque j'en ai besoin. Ce serait un bon article pour les mettre à jour et les expliquer mais voilà en attendant : https://codepen.io/propjockey/pen/YzZMNaz

Lecture de l'animation SVG

C'est initialement TRèS similaire à la section CPU Exfiltrator car c'est la même technique, mesurant et dépla?ant les données d'ici vers le haut du DOM jusqu'à l'endroit où elles sont hébergées (portée).

Nous mesurerons et rapporterons les 3 dernières valeurs de l'élément de base que nous avons configuré initialement.

Le ::avant, nous rendrons le SVG et définirons --xfl-raw-data en utilisant la position de vue en bloc qui est la mesure de la hauteur du SVG animé. (rappelez-vous, nous épinglerons la largeur à 10px)

Sur ::after, nous définirons --xfl-data-type en ligne (valeurs sentinelles 0 à 34) et --xfl-data-value block (valeurs 16 bits).

Le parent devra être suffisamment large pour restituer le SVG (au moins 10 px) et fournir avec précision des mesures pour les valeurs sentinelles (0 à 34).

Le parent devra également être suffisamment grand pour mesurer des valeurs de 16 bits (35). Puisque nous avons défini une valeur maximale dans la première étape de 100 000, nous l'utiliserons simplement même si elle est environ 30?% plus grande que ce dont nous avons besoin.

Et déplacez-le hors de l'écran vers le haut et la gauche pour ne pas provoquer de barres de défilement.

Par conséquent,

.svg-animation-current-state-reporter

obtient

<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  // add 35 to all the values so we can use 0 to 34 for sentinels. 0 = CSS-side sentinel, 1-32 = data frames, 33 = length, 34 = checksum
  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return ($viewBoxXYWidth . ((string) $index) . '; ' . $viewBoxXYWidth . ((string) ($val + 35)));
  }, $data, range(1, $datalen)); // 1 up to 32 = indicator that next frame is the value(+35) for that index(1-based)

  // no matter how many are in the array, '33' indicates the next frame is data length, which is used in the checksum too
  array_unshift($frames, $viewBoxXYWidth . '33; ' . $viewBoxXYWidth . ((string) ($datalen + 35))); // + 35 b/c data
  // unshift so the length is (hopefully) the first value read and a sense of progress can be reported

  $fullsum = 0;

  for ($x = 0; $x <= ($datalen - 1); $x++) {
    // double the odd ones so there's some semblance of order accounted for
    // the odd ones with 0 based index is the even ones on the CSS side
    $fullsum += ($data[$x] + (($x & 1) * $data[$x]));
  }

  $checksum = floor($fullsum / 2048) + ($fullsum % 2048) + $datalen + 35; // + 35 because it's data

  // no matter how many are in the array, '34' indicates the next frame is checksum
  array_push($frames, $viewBoxXYWidth . '34; ' . $viewBoxXYWidth . $checksum);

  $actualNumItems = count($frames) * 2;

  $dur = $actualNumItems * 0.33; // total seconds

  $keytimeStep = 1 / ($actualNumItems); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $actualNumItems - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>

et avant devient

@keyframes capture {
  0%, 100% {
    --xfl\1-captured: var(--xfl\1);
  }
}

@keyframes hoist {
  0%, 100% {
    --xfl\1-hoist: var(--xfl\1-captured, 0);
  }
}

et ::after obtient

  --xfl\1: calc(
    var(--xfl\1-hoist, 0) + 1
  );

Essentiellement, le support de stockage ici pour ces valeurs après est la position d'affichage d'un pseudo carré de 1 px par rapport à son conteneur de défilement parent. Nous soustrayons 1px dans les calculs de gauche et du haut car le pseudo lui-même est 1x1 et nous voulons qu'il rapporte 0 lorsque la valeur correspondante est 0.

Tout cela est très similaire à ce qui a été fait précédemment.

La fa?on dont nous calculons ces valeurs présente plusieurs complexités, comme l'indique la note?:

  @container style(--xfl-cpu-phase: 4) {
    animation-play-state: paused, paused;
    --cpu-next-phase: calc(
      min(1, var(--xfl-data-type)) * 4
    );
  }

La clé pour comprendre comment résoudre ce problème est que toute valeur de comparateur est définie sur 0 ou 1. 1 si c'est vrai, 0 si c'est faux. Ensuite, multipliez-le par une valeur. Si c'est faux, le résultat reste 0, sinon il devient quelle que soit la valeur.

Ana Tudor explique en profondeur comment cette idée fonctionne ici

Ensuite, si nous faisons cette comparaison deux fois, avec une comparaison différente ou opposée pour la deuxième valeur, et que nous les additionnons (en nous assurant qu'au plus un des comparateurs est 1), alors l'ajout de deux d'entre eux revient simplement à dire "sinon si".

si ce n'est pas prêt * utilisez l'ancienne valeur sinon
si est prêt * utilisez cette nouvelle valeur

C'est ainsi que nous conservons la valeur sentinelle pendant toute la durée de l'étape discrète de l'animation SVG pour la valeur une fois que le type a déjà été signalé.

Le code CSS l'implémentant commence ici à la ligne 191, juste au-dessus du gros bloc de --xfl\... les enregistrements de propriété que nous mettons vers le bas
@property --xfl\1 { syntaxe?: ""; valeur initiale?: 0?; hérite de?: vrai?; >
...
et il contient des notes supplémentaires?:

Définition de valeurs CSS --var spécifiques (affectations adressées)

La logique que nous venons d'aborder est exactement le même concept que nous utilisons pour toutes les valeurs --xfl\1, 2, 32.

<?php header('Content-type: image/svg+xml');

  $data = array(
    400,
    450,
    150,
    20,
    175
  );

  $datalen = count($data);

  $viewBoxXYWidth = '0 0 10 ';

  $frames = array_map(function ($val, $index) use ($viewBoxXYWidth) {
      return $viewBoxXYWidth . ((string) ($val));
  }, $data, range(1, $datalen));

  $dur = $datalen * 0.33; // total seconds

  $keytimeStep = 1 / ($datalen); // uniform portion per frame

  $keytimes = implode("; ", array_map(function ($index) use ($keytimeStep) {
      return ($index * $keytimeStep);
  }, range(0, $datalen - 1)));

  $values = implode("; ", $frames); 

  echo '<svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
    <animate attributename="viewBox" dur="' . $dur . 's" fill="freeze" begin="0.1s;" values="' . $values . '" keytimes="' . $keytimes . '" repeatcount="indefinite" calcmode="discrete"></animate>
  ';
?>

Vous lisez --xfl-set\1 comme si --xfl-data-type était égal à 1, utilisez --xfl-data-is-ready avec un implicite else 0

--xfl-data-is-ready a été établi plus t?t comme un drapeau nous maintenant dans la phase 0 jusqu'à ce qu'il soit temps de passer à la phase 1.

Cela signifie que notre condition est && logique. Les deux drapeaux doivent être à 1 pour passer.

Ensuite, vous continuez à lire --xfl\1 comme si --xfl-set\1 utilisait --xfl-data-value (la valeur actuelle de l'animation SVG), sinon si NON --xfl-set\1 utilisait -- xfl\1-hoist (la valeur précédente que le hack CPU détenait pour --xfl1)

Ceci est très répétitif, et décrit la quasi-intégralité du reste de cette exfiltration.

Les dernières étapes consistent à exécuter les mathématiques de base calc() et mod() pour construire la somme de contr?le comme décrit précédemment, puis à ajouter si la somme de contr?le calculée === la somme de contr?le intégrée dans l'animation SVG au CPU Hack afin que nous sachions quand c'est complet. C'est toujours la même chose.

Alors maintenant, il est temps. :)

Présentation?: Le hack d'exfiltration SVG animé CSS

Parce que je voulais montrer à chaque élément de ce hack une valeur par élément, la présentation est odieusement lourde. Plus de 2000 lignes de HTML et plus de 400 lignes de CSS. De plus, j'utilise css-bin-bits pour convertir chaque registre en binaire, etc.

(Cliquez sur Réexécuter en bas à droite du cadre du codepen pour voir cela se produire en temps réel !)

Pas de JavaScript?!


Ouvrir contact ?

N'hésitez pas à nous contacter si vous pensez que c'est intéressant et que vous souhaitez en savoir plus?! Toujours heureux de répondre aux questions.

% CSS?: récupérer et exfiltrer des bits de données générées par le serveur intégrées dans un SVG animé % CSS?: récupérer et exfiltrer des bits de données générées par le serveur intégrées dans un SVG animé DEV Blog % CSS?: récupérer et exfiltrer des bits de données générées par le serveur intégrées dans un SVG animé % CSS?: récupérer et exfiltrer des bits de données générées par le serveur intégrées dans un SVG animé
% CSS?: récupérer et exfiltrer des bits de données générées par le serveur intégrées dans un SVG animé % CSS?: récupérer et exfiltrer des bits de données générées par le serveur intégrées dans un SVG animé DEV Blog % CSS?: récupérer et exfiltrer des bits de données générées par le serveur intégrées dans un SVG animé % CSS?: récupérer et exfiltrer des bits de données générées par le serveur intégrées dans un SVG animé

?@JaneOri.% CSS?: récupérer et exfiltrer des bits de données générées par le serveur intégrées dans un SVG animé

?@Jane0ri

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefa?on, veuillez contacter admin@php.cn

Outils d'IA chauds

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

échangez les visages dans n'importe quelle vidéo sans effort grace à notre outil d'échange de visage AI entièrement gratuit?!

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Tutoriel PHP
1502
276
Tutoriel CSS pour créer des filateurs et des animations de chargement Tutoriel CSS pour créer des filateurs et des animations de chargement Jul 07, 2025 am 12:07 AM

Il existe trois fa?ons de créer un rotateur de chargement CSS: 1. Utilisez le rotateur de base des frontières pour obtenir une animation simple via HTML et CSS; 2. Utilisez un rotateur personnalisé de plusieurs points pour atteindre l'effet de saut à travers différents temps de retard; 3. Ajoutez un rotateur dans le bouton et basculez les classes via JavaScript pour afficher l'état de chargement. Chaque approche souligne l'importance des détails de conception tels que la couleur, la taille, l'accessibilité et l'optimisation des performances pour améliorer l'expérience utilisateur.

ATTENTION DES PROBLèMES ET PRéFIXES DE COMPATIBILITé DE BROWSER CSS ATTENTION DES PROBLèMES ET PRéFIXES DE COMPATIBILITé DE BROWSER CSS Jul 07, 2025 am 01:44 AM

Pour faire face à la compatibilité du navigateur CSS et aux problèmes de préfixe, vous devez comprendre les différences de prise en charge du navigateur et utiliser raisonnablement les préfixes des fournisseurs. 1. Comprendre les problèmes communs tels que Flexbox et le support de la grille, Position: Sticky Invalid et les performances d'animation sont différentes; 2. Vérifier l'état du support de la fonction de confirmation de Caniuse; 3. Utilisez correctement -webkit-, -moz-, -ms-, -o- et autres préfixes du fabricant; 4. Il est recommandé d'utiliser AutopRefixer pour ajouter automatiquement les préfixes; 5. Installez PostCSS et configurez le navigateur pour spécifier le navigateur cible; 6. Gérer automatiquement la compatibilité pendant la construction; 7. Les fonctionnalités de détection modernizr peuvent être utilisées pour les anciens projets; 8. Pas besoin de poursuivre la cohérence de tous les navigateurs,

Quelle est la différence entre l'affichage: en ligne, affichage: bloc et affichage: bloc en ligne? Quelle est la différence entre l'affichage: en ligne, affichage: bloc et affichage: bloc en ligne? Jul 11, 2025 am 03:25 AM

HEMAINDIFFERENCESBetweendisplay: Inline, Block, Andinline-BlockInhtml / CSSareLayoutBehavior, SpaceUsage et StylingControl.1.InlineElementsflowWithText, Don'tStartNewLines, Ignorewidth / Height, AndonlyApplyhorizontalPadding / Marges - IdealForninetLetetStyLinSing

Styling visité les liens différemment avec CSS Styling visité les liens différemment avec CSS Jul 11, 2025 am 03:26 AM

La définition du style de liens que vous avez visité peut améliorer l'expérience utilisateur, en particulier dans les sites Web à forte intensité de contenu pour aider les utilisateurs à mieux naviguer. 1. Utilisez CSS: Pseudo-classe visité pour définir le style du lien visité, tels que les changements de couleur; 2. Notez que le navigateur permet uniquement la modification de certains attributs en raison des restrictions de confidentialité; 3. La sélection des couleurs doit être coordonnée avec le style global pour éviter la brutalité; 4. Le terminal mobile peut ne pas afficher cet effet et il est recommandé de le combiner avec d'autres invites visuelles telles que les logos auxiliaires ic?nes.

Création de formes personnalisées avec CSS Clip Path Création de formes personnalisées avec CSS Clip Path Jul 09, 2025 am 01:29 AM

Utilisez l'attribut Clip-Path de CSS pour recadrer des éléments en formes personnalisées, telles que les triangles, les encoches circulaires, les polygones, etc., sans compter sur des images ou des SVG. Ses avantages incluent: 1. Prend en charge une variété de formes de base telles que le cercle, l'ellipse, le polygone, etc.; 2. Ajustement réactif et adaptable aux terminaux mobiles; 3. Facile à l'animation, et peut être combiné avec le survol ou le javascript pour obtenir des effets dynamiques; 4. Il n'affecte pas le flux de disposition et ne culte que la zone d'affichage. Les usages communs sont tels que le chemin de clip circulaire: cercle (50pxatcenter) et trame de clip Triangle: polygone (50% 0%, 100 0%, 0 0%). Avis

Comment créer des images réactives à l'aide de CSS? Comment créer des images réactives à l'aide de CSS? Jul 15, 2025 am 01:10 AM

Pour créer des images réactives à l'aide de CSS, elle peut être principalement réalisée grace aux méthodes suivantes: 1. Utilisez la largeur maximale: 100% et hauteur: Auto pour permettre à l'image de s'adapter à la largeur du conteneur tout en maintenant la proportion; 2. Utilisez les attributs SRCSET et tailles de HTML pour charger intelligemment les sources d'image adaptées à différents écrans; 3. Utilisez l'objet-ajustement et la position d'objet pour contr?ler le recadrage d'images et l'affichage de la mise au point. Ensemble, ces méthodes garantissent que les images sont présentées clairement et magnifiquement sur différents appareils.

Démystifier les unités CSS: PX, EM, REM, VW, VH Comparaisons Démystifier les unités CSS: PX, EM, REM, VW, VH Comparaisons Jul 08, 2025 am 02:16 AM

Le choix des unités CSS dépend des exigences de conception et des exigences réactives. 1.PX est utilisé pour la taille fixe, adaptée à un contr?le précis mais au manque d'élasticité; 2.EM est une unité relative, qui est facilement causée par l'influence de l'élément parent, tandis que REM est plus stable en fonction de l'élément racine et convient à la mise à l'échelle globale; 3.VW / VH est basé sur la taille de la fenêtre, adaptée à la conception réactive, mais l'attention doit être accordée aux performances sous des écrans extrêmes; 4. Lors du choix, il doit être déterminé en fonction de la question de savoir si les ajustements réactifs, les relations de hiérarchie d'éléments et la dépendance de la fenêtre. Une utilisation raisonnable peut améliorer la flexibilité et la maintenance de la disposition.

Quelles sont les incohérences courantes du navigateur CSS? Quelles sont les incohérences courantes du navigateur CSS? Jul 26, 2025 am 07:04 AM

Différents navigateurs ont des différences dans l'analyse CSS, ce qui entra?ne des effets d'affichage incohérents, y compris principalement la différence de style par défaut, la méthode de calcul du modèle de bo?te, le niveau de support Flexbox et la disposition de la grille et le comportement incohérent de certains attributs CSS. 1. Le traitement de style par défaut est incohérent. La solution consiste à utiliser cssreset ou normaliser.css pour unifier le style initial; 2. La méthode de calcul du modèle de bo?te de l'ancienne version de IE est différente. Il est recommandé d'utiliser la taille d'une bo?te: Border-Box de manière unifiée; 3. Flexbox et Grid fonctionnent différemment dans les cas de bord ou dans les anciennes versions. Plus de tests et utilisent Autoprefixer; 4. Certains comportements d'attribut CSS sont incohérents. Caniuse doit être consulté et rétrogradé.

See all articles