Comme mentionné dans le titre, est-il possible de calculer le vw
sans les barres de défilement dans CSS uniquement?
Par exemple, mon écran a une largeur de 1920px
. vw
retourne 1920px
, génial. Mais la largeur réelle de mon corps n’est que quelque chose comme 1903px
.
Est-il possible pour moi de récupérer le 1903px
valeur avec css seulement (pas seulement pour les enfants directs du body
), ou ai-je absolument besoin de JavaScript pour cela?
Une façon de faire est d'utiliser calc. Pour autant que je sache, 100% est la largeur, barres de défilement comprises. Donc si vous le faites:
body {
width: calc(100vw - (100vw - 100%));
}
Vous obtenez le 100vw moins la largeur de la barre de défilement.
Vous pouvez le faire aussi avec la hauteur, si vous voulez un carré qui représente 50% de la fenêtre d'affichage par exemple (moins 50% de la largeur de la barre de défilement).
.box {
width: calc(50vw - ((100vw - 100%)/2))
height: 0
padding-bottom: calc(50vw - ((100vw - 100%)/2))
}
Selon les spécifications, les unités de longueur relative de la fenêtre de visualisation ne tiennent pas compte des barres de défilement (et supposent en fait qu'elles ne n'existe pas).
Quel que soit votre comportement, vous ne pouvez pas prendre en compte les barres de défilement lorsque vous utilisez ces unités.
Les navigateurs Webkit excluent les barres de défilement, les autres les incluent dans la largeur renvoyée. Cela peut bien sûr poser problème: par exemple, si vous avez généré dynamiquement du contenu avec ajax ajoutant de la hauteur de manière dynamique, Safari peut passer d'une présentation à une autre lors de la visualisation de la page ... Bon, cela n'arrive pas souvent, mais être conscient de. Sur mobile, moins de problèmes, car les barres de défilement ne sont généralement pas affichés.
Cela dit, si votre problème est de calculer exactement la largeur de la fenêtre sans barres de défilement dans tout le navigateur, pour autant que je sache, une bonne méthode est la suivante:
width = $('body').innerWidth();
ayant préalablement défini:
body {
margin:0;
}
La seule façon dont je l'ai trouvé fonctionne sans déranger votre code avec "calc" est de rendre la taille de l'élément conteneur à 100vw; Ajout d'une enveloppe autour du conteneur pour overflow-x; Cela rendra le conteneur pleine largeur, comme si la barre de défilement était au-dessus du contenu.
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
html{ overflow-y: scroll; }
html, body{ padding:0; margin: 0;}
#wrapper{ overflow-x: hidden; }
.row{ width: 100vw; }
.row:after{ clear: both; content: ''; display: block; overflow: hidden; }
.row-left{ background: blue; float: left; height: 40vh; width: 50vw; }
.row-right{ background: red; float: right; height: 40vh; width: 50vw; }
</style>
</head>
<body>
<div id="wrapper">
<div class="row">
<div class="row-left"></div>
<div class="row-right"></div>
</div>
</div>
</body>
</html>
Je le fais en ajoutant une ligne de javascript pour définir une variable CSS une fois le document chargé:
document.documentElement.style.setProperty('--scrollbar-width', (window.innerWidth - document.documentElement.clientWidth) + "px");
ensuite, dans le CSS, vous pouvez utiliser var(--scrollbar-width)
pour effectuer les réglages nécessaires pour différents navigateurs avec/sans barres de défilement de largeurs différentes. Vous pouvez faire quelque chose de similaire pour la barre de défilement horizontale, si nécessaire, en remplaçant innerWidth
par innerHeight
et clientWidth
par clientHeight
.
Le moyen le plus simple est de régler le code HTML et le corps sur 100vw:
html, body{ width:100vw; overflow-x: hidden; overflow-y: auto; margin: 0; }
Le seul problème est que le plus à droite sera coupé un peu si la barre de défilement est affichée.
L'unité vw
ne prend pas le overflow-y
barre de défilement en compte lorsque overflow-y
est réglé sur auto
.
Changez-le en overflow-y: scroll;
et l’unité vw
sera la fenêtre d’affichage sans la barre de défilement.
Seul inconvénient à prendre en compte. Si le contenu s'adapte à l'écran, la barre de défilement est quand même affichée. La solution possible est de passer de auto
à scroll
en javascript.