Durant l'intégration de ce site CV/Blog, je voulais que mes blocs restent alignés Pixel Perfect avec mon quadrillage de fond.
Essayez donc de redimensionner cette page, la taille du container va toujours suivre son quadrillage derrière. Ce qui fait que le rendu n'est pas symétrique... Maintenant que vous le savez, ça risque de vous énerver :).
Ma première intuition était d'utiliser les grilles CSS. Pour moi, il
suffisait de fractionner ma zone en n colonnes et avoir un gap de 39px entre chacune. Le problème est que : ma zone de contenu n'a pas de taille
fixe, le navigateur dicte sa largeur, j'applique juste un padding
fixe à droite et à gauche de ma page, je ne limite pas la largeur. Ce qui
rend ma zone pas forcément découpable en carré de 40px.
Pour la page d'accueil, rien de plus simple. C'est moi qui décide de la
taille de mes cartes, il me suffit de multiplier par 40 le nombre de
colonnes ou de ligne que je souhaite et d'y rajouter 1px pour la bordure.
Je laisse le flex-wrap
s'occuper du ... wrap s'il n'y a pas la
place, et utiliser le gap
qui permet de m'assurer que chaque fenêtre
soit bien à 39px l'une de l'autre.
---
interface Props {
title: string;
row: number;
col: number;
}
const { title, col, row } = Astro.props;
const width = `${40 * col + 1}px`;
const height = `${40 * row + 1}px`;
---
<div class="window">
<h1>
<slot name="icon" />{title}
</h1>
<div class="body"><slot /></div>
</div>
<style define:vars={{ width, height }}>
.window {
width: var(--width);
min-width: var(--width);
max-width: var(--width);
height: var(--height);
min-height: var(--height);
max-height: var(--height);
}
</style>
Effectivement rien de bien compliqué ici...
Sur mes pages de Blog, je souhaite que mon container prenne le maximum
de place tout en restant un multiple de 40. Je pourrais utiliser du JavaScript en écoutant l'événement resize
, venir calculer la bonne
largeur de mon container et l'appliquer.
Mais nous on veut une solution sans Javascript. calc
permet de
rendre une valeur dynamique en CSS. On peut donc effectuer des opérations tel
qu'une soustraction à une valeur en px
ou vw
.
Mais comment récupérer le nombre de pixel en trop ? L'opérateur %
nous serait bien utile pour soustraire le reste, mais il n'est pas disponible
dans la fonction calc
.
Fort heureusement pour nous, la fonction round
nous permet de
pallier ce soucis. Il nous suffit de diviser la taille de notre container par
40, et d'arrondir à l'entier inférieur. Cela nous permet d'avoir la taille
maximum de notre container en multipliant par 40.
---
import { Image } from "astro:assets";
import profilePng from "../../public/me.png";
interface Props {
title: string;
}
const { title } = Astro.props;
---
<div class="window">
<h1>
<a href="javascript:history.back()"><slot name="icon" /></a>{title}
</h1>
<div class="window-body">
<Image class="float" src={profilePng} alt="My profile picture" />
<slot />
</div>
</div>
<style>
.window {
--x: calc(100% / 40);
--y: calc(100% / 40);
--round-x: round(down, var(--x), 1px);
--round-y: round(down, var(--y), 1px);
width: calc(var(--round-x) * 40);
height: calc(var(--round-y) * 40);
}
</style>
Plus simple de lire le code, non ? La problématique n'est pas vraiment commune, et j'aurais très certainement fini par utiliser du JavaScript pour ça. Mais il est toujours bon si possible de se baser sur une version uniquement CSS.