28172 sujets

CSS et mise en forme, CSS3

Pages :
Bon, je viens pour un problème récurent que je n'ai jamais réussi à solutionner proprement.
Il s'agit lors d'un centrage d'un div container par la valeur auto des propriétés margin-right et margin-left du dernier pixel qui reste lorsque la résolution de la fenêtre est un nombre impaire.

Par exemple un container de 960px, sur une largeur de fenêtre de navigateur de 1200px, nous avons deux marges de 120px. C'est parfait.
Mais si la taille de la fenêtre est de 1201px, le navigateur non seulement fera une marge de 121px et une autre de 120px... Ce qui n'est pas très grave en soi.
Mais plus gênant la position de tous les élément à l'intérieur du div container seront calculé au plus proche et non par rapport au point d'origine du container...

Je sais pas si je suis très claire...

Enfin, au final, il y a des décalage de 1px qui apparaisse très nettement , surtout si on veux faire des filets verticaux en utilisant les propriétés border dans un système de grille.

Il me semble avoir vu une fois que l'on pouvait forcé les navigateurs à ne pas faire de calcul au plus proche... C'est peut être une solution, mais je ne retrouve plus la référence.

Merci de votre aide.
le plus simple serait de te servir d'un conteneur principal et que tout le monde s'aligne dedans.
Si tu as des elements positionné en absolu, il te faut mettre ce conteneur en position : relative ; pour qu'il soit l point de référence.

Sans plus de code, ce ne sont que de faciles suppositions Smiley smile
++
En fait je me suis trompé.

Le problème ne vient pas du margin auto du conteneur, mais de la largeur en pourcentage des éléments.

Ainsi j'ai un conteneur de 960 px avec 12 colonnes de 8.3333333% de large.
Le problème vient des approximations de pixel pour positionner le border.

Une petite image c'est plus simple :
upload/46424-mod.png

Donc on voit que dans la première rangée de 12 éléments, chaque élément à une largeur de
16 padding + 46.964 + 16 padding + 1 border dans un espace réservé de 80 px.
Il manque un petit quelque chose pour faire un compte rond... Et donc le border (qui est sur le coté droit sauf pour le dernier élément) n'arrive pas à bien se placer.

Sur les autres rangées, on obtiens des chiffres ronds donc le border-right s’aligne bien.

Donc du coup ma question :
comment faire lorsqu'on a des valeur exprimer en %, pour obtenir une valeur avec un nombre entier ?

Je pense que ca doit être possible en gérant une propriété du navigateur ?
Modifié par Heillige Leben (06 Oct 2013 - 10:38)
A noter tout de même que le problème ne survient que lorsque la taille de la fenêtre est impaire.

NB... Comment fait on pour changer le titre d'un post... Merci
Modifié par Heillige Leben (06 Oct 2013 - 11:10)
Administrateur
Heillige Leben a écrit :
NB... Comment fait on pour changer le titre d'un post... Merci

Bonjour,

Le bouton "Aide" n'apparaît pas dans le menu du forum chez toi ? Smiley murf

Si non, es-tu connecté ? Acceptes-tu les cookies ?
Merci pour cette idée.
Mais ça génére exactement le même problème visiblement.
Si je modifilie la taille de la fenêtre du lien que tu m'as envoyé.
J'ai pareil... Smiley decu

upload/46424-mod2.png

Je suis sur la dernière version de chrome.
Je sais qu'il y a un moyen de voir les propriétés natives des navigateurs...
Tu sais, le truc qu'il ne faut jamais toucher...
Ca doit aussi exister sur FireFox..

Il me semble qu'il doit y avoir une propriété du genre...
-webkit-calcul-approximation

On doit pouvoir la modifiée dans le css.
Le but étant d'arrondir à l'entier supérieur.

En tout cas merci de ton aide.
ah dommage pour chrome , pour firefox , je n'ai aucun decallage sur mes 2 ecrans (1920 et 1024)
de mon coté chrome est provisoirement désinstallé pour cause de freeze de PC , bug récurrent et connu sous Win depuis plusieurs mois.
En passant sur une autre machine sous xp, en incluant une decimale sur le width , chrome et FF semble s'accorder sur le calcul d'arrondi.
http://codepen.io/gcyrillus/pen/vrjbu

largeurs brievement testées:
.grid {
  width:959.3px;
  margin:auto;
}
hr ~.grid {
  width:79.68%;
}

l'idée est de forcer d'entrée un calcul d'arrondi, 1 pixel est 1 pixel Smiley smile
Modifié par gc-nomade (06 Oct 2013 - 12:49)
J'ai testé sous firefox avec tes valeurs et si je redimensionne la fenêtre, j'ai encore ce bug.
C'est bizarre que tu ne le reproduises pas ?

Je voudrais bien lui dire que 1 pixel est un pixel.
ou plus exactement que 0.975 est 1 pixel.
Mais comment faire ?
Bon , en fait le plus imple est de s'affranchir de ces calcul d'arrondies et de revoir le redimensionnement sur une base de 12*XXpixel = width conteneur principal.

Pour cela , les mediaqueries peuvent t'aider je pense pour une largeur qui s'adapte en allant de en pas de 12.(voir point de rupture)

... 948 (12*79) - 960(12*80) - 972(12*81) ...
excepté via JavaScript, je ne vois aucun autre moyen de maitriser les largeurs au pixel.
++
En fait j'utilise le framework foundation sous compass (enfin, je teste...) .
Du coup, je ne veux pas tout toucher.

Cela dit j'ai trouvé la solution la plus vilaine qui soit.
En étudiant les valeurs sorties dans le navigateur, j'ai vu qu'il y avait un décalage d'un pixel entre les valeurs arrondies et celles qui tombaient justes.
Du coup, il suffit de fixer dans les variables une largeur de container qui ne donne jamais un chiffre rond lorsque je la divise par mon nombre de colonne.

Du coup j'ai choisi 961px, et là ça marche à merveille.
Par exemple
1024 ne marche pas, 1023 et 1022 non plus.
1021 et 1025 oui.

@ gc-nomade : J'aime bien ton truc en ligne pour tester du code
Modifié par Heillige Leben (06 Oct 2013 - 23:35)
Bonsoir à toutes et à tous.

Il y a deux choses que je ne comprends pas dans votre problème.
Excusez moi si je prends le sujet en cours de route mais j'aime comprendre !

1) vous parlez de pixels dont l'expression est avec une virgule, du genre : width:959.3px;
Mais je croyais que la plus petite entité sur un écran était le pixel et que l'on ne pouvait pas avoir plus petit.
Si tu exprimes 959.3, ton navigateur risque d'interpréter cela soit au plancher (959px) soit au plafond (960px).
Donc je ne comprends pas le fait de mettre un nombre à virgule dans cette propriété ?*

Le problème du pourcentage est exactement pareil car 33.33% sera interprété afin de correspondre à un résultat qui s'exprimera en pixel. D'où les problèmes d'arrondis.

Comme gc-nomage le dit, l'usage de calc() est peut être une solution.
prenons l'exemple de 1/3 et de 2/3.
--> calc(33.34%)
--> calc(66.66%).
Oui il faut que cela fasse 100%.
Ou alors, transcrire ainsi :
--> calc(33.33% + 1px)
--> calc (66.66%).

Comme nous n'avons pas l'usage de variables sous CSS, il est difficile d'avoir un résultat juste. En JavasSript, je récupérerais la largeur de la page, en pixel. Exemple : 1400px. Il ne faut pas que cela soit divisible par trois pour la démonstration.
Ensuite, si je désire prendre 33.33%. Comme je sais que c'est 1/3, je fais le calcul suivant :
--> 1400/3 = 466.66666px et on arrondis à 466px.
Et pour l'autre colonne au 2/3, je calcul tout simplement la différence, ce qui donne : 1400 - 466 = 934.
Si on calcul les 2/3, voici ce que cela donne : 1400 *2/3 = 933.33px ce qui donne, par l'arrondi, 933px. Soit une différence de 1px, d'où le problème du décalage.

Si on fait le calcul avec 33.33%, voila ce que cela donne : 1400 * 33.33% = 466.62
Par comparaison, nous avons d'une part 466.666666 et d'autre part 466.62
Il y a bien un problème d'arrondi dans la façon de faire ce genre de calcul.

2) le problème que tu exposes, ne viendrait-il pas d'un mauvais usage de la mise en forme de ta page ?

Si tu as une boîte servant de conteneur ayant 2x de large et que tu redécoupes en deux cette largeur afin d'avoir x de large, je ne vois pas comment peut-on avoir un décalage, même si x est impair ???

Prenons l'exemple avec x=2p+1. Tout ce que tu risques d'avoir, c'est une boîte dont la largeur sera x=p et l'autre sera x=p+1. Le tout est d'avoir toujours la même chose, c'est-à-dire la première boîte à x=p et l'autre boîte à x=p+1 où vice-versa.

Peut-être qu'il faut coller ces boîtes dites flottantes par un 'float:left' et ainsi il n'y aura plus de jeu dans les résultats.

Enfin, je n'ai pas tout compris de ce qui a été exposé. Je peux très bien me tromper dans mon interprétation de ce que vous exposez.

@+
Modifié par tournikoti (06 Oct 2013 - 21:18)
Argh...
Je croyais que ça marchait, mais pas du tout...
Il y a toujours un décalage de 1px qui apparaît si on change manuellement la taille de la fenêtre.


Tournikoti, tout ce que tu dis est très juste, seul problème... ça ne marche pas dans les navigateurs...
En fait ce qui ne marche pas c'est l'alignement vertical des filets.
Reprend l'exemple de gc-nomade,

http://codepen.io/gcyrillus/pen/vrjbu

Lorsque tu as une largeur de grid de 959.3px, ça s'aligne, car il n'y a que des approximations.
Mais remplace cette valeur par 960px et que tu réduis manuellement la fenêtre,
tu verras qu'il y a un décalage dans les filets rouges sur la rangée ou il n'y a que 2 colonnes. Pourtant 960px et divisible par 12 et 960 et aussi divisible par 2. Mais comme dans la css, on a 8.33%, on obtient une approximation. Alors qu'avec 50% la longueur calculée est un entier.

Du coup ma conclusion est qu'il est impossible d'utiliser des valeurs de pourcentage pour calculer des largeurs de grille si on veut un alignement vertical consistant.
Modifié par Heillige Leben (06 Oct 2013 - 23:40)
Bonsoir à toutes et à tous.

En fait, ce ne sont que des problèmes d'arrondis ! Prenons un exemple avec deux largeurs qui sont 960px et 959.3px. Elles sont proches !

Pour 960px tout va bien puisqu'il est multiple de 2, 3, 4, 6 et 12. On divise notre largeur par les multiples.
Ce qui donne respectivement les valeurs suivantes : 480px, 320px, 240px, 160px et 80px.

Si nous prenons maintenant le pourcentage, cela donne : 50%, 33.3333%, 25%, 16.6666% et 8.3333%.
Nous faisons les calculs en conservant exactement la précision donnée.
Ce qui donne respectivement les valeurs suivantes : 480px, 319.99968px, 240px, 159.99936px et 79.99968px.

Pour 959.3px, il n'est multiple d'aucun nombre !
Refaisons les mêmes calculs sur les multiples de 2, 3, 4, 6 et 12.
Ce qui donne respectivement les valeurs suivantes : 479.65px, 319.766666px, 239.825px, 159.883333px et 79.941666px.

Si nous prenons maintenant le pourcentage, cela donne : 50%, 33.3333%, 25%, 16.6666% et 8.3333%.
Ce qui donne respectivement les valeurs suivantes : 479.65px, 319.7663469px, 239.825px, 159.8826938px et 79.9413469px.

Tout dépend le genre d'arrondi que le navigateur produit ensuite.
On en recense trois :
--> arrondi au plancher. On conserve que la partie entière.
--> arrondi au plus près. On ajoute au résultat 0.5 et on prend la valeur entière.
--> arrondi au plafond. On ajoute au résultat 0.99 et on prend la valeur entière.
Pourquoi 0.99 ? Caron désire une précision sur deux chiffres.
Attention à ne pas prendre la partie entière et à ajouter +1 car si nous avons 12.00 on ne doit obtenir 13 mais bien 12.

Donc selon la précision que l'on donnera au pourcentage, nous aurons des résultats différents.
Reprenons l'exemple de la largeur 959.3px avec la précision de 1/3. Et à la fin nous donnerons l'arrondi au plus près.
--> 0.3 ==> 287.79 ==> 288px
--> 0.33 ==> 316.569 ==> 317px
--> 0.333 ==> 319.4469 ==> 319px
--> 0.3333 ==> 319.73469 ==> 320px

Et si on pratique aussi un arrondi sur le pourcentage.
--> 0.34 ==> 326.162 ==> 326px
--> 0.334 ==> 320.4062 ==> 320px
--> 0.3334 ==> 319.83062 ==> 320px

On constate que selon la précision et l'arrondi donné au pourcentage, on n'obtient pas toujours la même chose.
Il faut mieux alors privilégier une grande précision et un arrondi sur la dernière décimale du pourcentage comme je l'ai fait.

En jouant sur le redimensionnement de la page web, je n'ai pas vu de différence dans les alignements avec :
width : calc(25% / 3 - 1px);
ou bien avec :
width : calc(8.333334% - 1px);

qui exprime une largeur de 1/12 ième.
Le 1px que je retranche, c'est à cause de la bordure de 1px à droite afin de visualiser les alignements verticaux.
Il y a exactement, au même moment, le même décalage qui se fait.

En conclusion, je n'ai pas pu obtenir un alignement parfait en utilisant les pourcentages sur les multiples de 2, 3, 4, 6 et 8 à partir d'une largeur non divisible par ces multiples.
On peut utiliser les pourcentages à la conditions que ce sont des multiples. L'exemple de la division par 3 de la largeur 960px et qui donne 320px, fonctionne correctement.

@+

On peut utiliser les pourcentages à la conditions que ce sont des multiples. L'exemple de la division par 3 de la largeur 960px et qui donne 320px, fonctionne correctement.


Ben pas forcément.
Avec un conteneur de 960px, 2 colonnes (width:50%)
ne s’alignera pas avec 6 colonnes (width:16.666666666666666666666666666667%)
Pourtant pour les deux la division donne un entier (480px et 160px).
Ce n'est qu'un exemple. Je prends ces nombres de colonnes pour qu'on voit bien le décalage.
Modifié par Heillige Leben (07 Oct 2013 - 09:48)
Bonjour Heillige Leben.

J'ai pourtant fait le test et je me suis assuré que j'avais bien l'alignement à chaque fois et non des décalages ou si tu préfères des lignes brisées !

A titre indicatif, j'ai refait à ma façon l'exemple donné par cg-nomate, qui au passage je remercie d'avoir donné cet exemple ! Cela m'a permis de mieux comprendre la problématique soulevée.

<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<title>Alignement</title>

<style>
* {
		margin					: 0;
		border					: 0 none;
		padding					: 0;
		-webkit-box-sizing		: border-box;
		-moz-box-sizing			: border-box;
		box-sizing				: border-box;
}

.grid {
		background-color		: green;
		width					: 960px;
		margin					: 0 auto;
}

.grid6 {
		float					: left;
		background-color		: lightgrey;
		border-right			: 1px solid red;
		width					: 16.666667%;
		text-align				: center;
}

.grid3 {
		float					: left;
		background-color		: lightgrey;
		border-right			: 1px solid red;
		width					: 33.333334%;
		text-align				: center;
}

.grid2 {
		float					: left;
		background-color		: lightgrey;
		border-right			: 1px solid red;
		width					: 50%;
		text-align				: center;
}
</style>
</head>

<body>
	<div class="grid">
		<div class="grid6">6</div>
		<div class="grid6">6</div>
		<div class="grid6">6</div>
		<div class="grid6">6</div>
		<div class="grid6">6</div>
		<div class="grid6">6</div>
	</div>
	<div class="grid">
		<div class="grid3">3</div>
		<div class="grid3">3</div>
		<div class="grid3">3</div>
	</div>
	<div class="grid">
		<div class="grid2">2</div>
		<div class="grid2">2</div>
	</div>
</body>
</html>

Sur l'exemple donné par gc-nomade, je retrouve bien les lignes brisées !
Avec mon exemple, non. Ou alors, je n'ai pas les yeux en face des trous.
J'ai testé cela sur Mozilla Firefox version 24.0 ainsi que sur Google Chrome version 30.0.1599.69 m

Une chose qui m'arrive assez fréquemment, c'est que je comprends la question de travers.

@+
Salut tournikoti,

Merci, tu réponds parfaitement à mon problème.
Effectivement je me suis trompé, et ton exemple est parfaitement correct.

Du coup j'ai regardé la différence entre ton code et celui de gc-nomade.
Elle se fait au niveaux de précision, ainsi si je veux aligner avec une colonne d'une demi page

.grid2 { width : 50% }


un grid6 qui fait un sixiéme de page

.grid6 { width : 16.66% } // Un élément aura un px de moins

.grid6 { width : calc(100%/6 } // Pareil, un élément aura un px de moins

.grid6 { width :  16.67% } // Un élément aura un px de plus

.grid6 {width : 16.666667% } //Correct  



Conclusion les valeurs exprimées en pourcentage doivent se faire avec une précision supérieure à 2 chiffres après la virgule.

Du coup, sur le framework de "Foudation" pour Compass (l'origine de mon problème), les valeurs en pourcentage sont calculées.
Je me demande dans quelle mesure les calculs se font avec seulement 2 chiffres après la virgule (comme la fonction calc() ).
Du coup, ça ne serait pas très pertinent à utiliser.
Modifié par Heillige Leben (08 Oct 2013 - 09:02)
Intéressant, j'avais aussi tester en augmentant le nombre de chiffre après la virgule, cependant en incluant Opéra et IE, dans les test , je n’était pas plus convaincu.
Les résultats, comportement sur le test qui diffère d'un PC a l'autre (chez moi pas de décalage sur mon PC principal en screen 1024 ou 1920) et chez vous , décalage , continue a me laisser pensé que la division reste aléatoire pour des raisons autres ou en plus que le simple navigateur . Matériel , OS, et/ou plugins des navigateurs ?

Je continue donc a penser que
- la multiplication à partir d'entier évince les arrondis,
- que JavaScript pourrait aussi se charger de gérer ça avec la maitrise du calcul a partir de la plus petite largeur.
- et enfin, pas dit avant mais pas tapé ! , qu'un tableau et colspan s'affranchirait de se souci de lui même sans risquer de voir une ligne passer sur 2 ,si données 'tabulaire', pourquoi s'en passer Smiley cligne .

Bonne journée.

<edit> surement du a une petite fatigue , 1/3 serait plutôt proche de 33.333334 % Smiley cligne
Modifié par gc-nomade (08 Oct 2013 - 07:36)
Attention, le décalage apparaît lorsqu'on réduit manuellement la fenêtre sur des taille de fenêtre impaire.
Je pense que le contexte rentre en cause également.
A savoir les marges droite et gauche en auto.
Du coup sur les taille de fenêtre impaire, il y a un premier calcul d'interprétation par le navigateur.
Je pense donc que ce problème devrait apparaître quelque soit le système.

Sinon je suis tout à fait d'accord avec toi sur les 3 points soulevés.
La multiplication par un entier annule le problème. la division aussi d’ailleurs.
Tout calculer en em me semble alors le mieux. D'ailleurs cette option doit être couplé avec du javascript si on n'utilise pas un compilateur css.
Et pour les données tabulaires le tableau s'impose.

Ps : je corrige mes pseudos tiers...
Pages :