¿Es posible calcular el ancho de la ventana gráfica (vw) sin barra de desplazamiento?

82

Como se menciona en el título, ¿es posible calcular el vwsin las barras de desplazamiento solo en CSS?

Por ejemplo, mi pantalla tiene un ancho de 1920px. vwdevuelve 1920px, genial. Pero el ancho de mi cuerpo real es solo algo así como 1903px.

¿Hay alguna forma de recuperar el 1903pxvalor solo con css (no solo para los hijos directos de body), o necesito absolutamente JavaScript para esto?

Marten Zander
fuente
2
pero ... ¿¡la barra de desplazamiento no está incluida en el ancho de la ventana gráfica !?
Danield
@Danield lo siento, actualicé mi pregunta
Marten Zander
Si estamos hablando de una barra de desplazamiento artificial que colocó allí, entonces tal vez esté buscando algo como esto: width: calc(100vw - scrollbarWidth)donde 'scrollbarWidth' es un valor fijo como 15px
Danield
@Danield De hecho, necesito una solución de navegador cruzado donde tenga el ancho variable de cada desplazamiento del navegador nativo
Marten Zander
2
Actualmente estoy trabajando en una página que usa bootstrap 4 en Chrome v64 y% es el ancho interno (sin incluir la barra de desplazamiento) y vw es el ancho externo (el ancho incluye la barra de desplazamiento); por lo tanto, no puedo usar vw y, como el OP, no No entiendo por qué está pasando.
Eric_B

Respuestas:

112

Una forma de hacerlo es con calc. Hasta donde yo sé, el 100% es el ancho, incluidas las barras de desplazamiento. Entonces, si lo hace:

body {
  width: calc(100vw - (100vw - 100%));
}

Obtienes los 100vw menos el ancho de la barra de desplazamiento.

También puede hacer esto con la altura, si desea un cuadrado que sea el 50% de la ventana gráfica, por ejemplo (menos el 50% del ancho de la barra de desplazamiento)

.box {
  width: calc(50vw - ((100vw - 100%)/2))
  height: 0
  padding-bottom: calc(50vw - ((100vw - 100%)/2))
}  
Mattias Ottosson
fuente
40
Esto es asombroso, pero desafortunadamente solo funciona si el elemento que está dimensionando es hijo directo bodyo un elemento que tiene el mismo ancho que body(de lo contrario, 100%se referirá al ancho del elemento incorrecto). En cuyo caso, simplemente puede usar porcentajes. ¿A menos que me esté perdiendo algo?
Nateowami
7
No está bien para los casos en los que 100vw contabilizar la barra de desplazamiento es realmente un problema, es decir, cuando necesita colocar un bloque de 100vw en un contenedor con un ancho fijo.
ciertamente
52
Matemáticas: 100vw - (100vw - 100%) = 100vw - 100vw + 100% = 100% ¿me pierdo algo?
Kamil Kiełczewski
3
Desafortunadamente, esto no funcionaría para el elemento posicionado absoluto ya que el 100% no está disponible allí :(
Hrvoje Golcic
4
@TKoL En todos los casos en los que su solución realmente resolvería el problema, width: 50% funcionaría igual de bien. Kamil Kiełczewski tiene razón, esta solución es inútil.
Eliezer Berlin
14

Hago esto agregando una línea de javascript para definir una variable CSS una vez que el documento se ha cargado:

document.documentElement.style.setProperty('--scrollbar-width', (window.innerWidth - document.documentElement.clientWidth) + "px");

luego, en el CSS, puede usar var(--scrollbar-width)para realizar los ajustes que necesite para diferentes navegadores con / sin barras de desplazamiento de diferentes anchos. Puede hacer algo similar para la barra de desplazamiento horizontal, si es necesario, reemplazando innerWidthcon innerHeighty clientWidthcon clientHeight.

usuario11990065
fuente
Para mí, el tamaño que devuelve es el doble de lo necesario. ¿Alguna pista? Me da 16px pero 8px sería suficiente ...
Fabian Beyerlein
9

Según las especificaciones , las unidades de longitud relativa de la ventana gráfica no tienen en cuenta las barras de desplazamiento (y de hecho, asumen que no existen).

Entonces, sea cual sea su comportamiento previsto, no puede tener en cuenta las barras de desplazamiento al usar estas unidades.

Fantasma de Madara
fuente
Nuevamente, vwpor especificación, no están al tanto de la existencia de ninguna barra de desplazamiento. Entonces no puedes tenerlos en cuenta.
Madara's Ghost
1
De acuerdo con las especificaciones, vw elimina el ancho de la barra de desplazamiento A MENOS que el desbordamiento esté en automático, entonces funciona como "oculto" para el valor de vw. Entonces, si la página debe desbordarse, configúrela en "scroll". Con overflow-x & overflow-y, eliges qué barra de desplazamiento mostrar.
Kulvar
1
@Kulvar acaba de probarlo en Chrome, configurar el cuerpo en overflow-y: scrollvs overflow-y: autono parece cambiar el valor calculado para las unidades vw. Específicamente, tengo algo configurado en mi sitio en 3.82vw, y el ancho de mi computadora es 1920px. Con overflow auto, 3.82vw = 73.344px, y luego probé con overflow scroll que también emite 73.344px, sin cambios, cuando en realidad debería emitir 72.6946px si estaba en lo correcto
TKoL
El 100% tiene en cuenta las barras de desplazamiento, por lo que si su caso es 100vw, si puede, cámbielo a 100%
Jairo
3

Los navegadores Webkit excluyen las barras de desplazamiento, otros las incluyen en el ancho devuelto. Por supuesto, esto puede conducir a problemas: por ejemplo, si ha generado contenido dinámicamente con ajax que agrega altura dinámicamente, Safari puede cambiar de un diseño a otro durante la visualización de la página ... Ok, no sucede a menudo, pero es algo para tenga en cuenta. En dispositivos móviles, menos problemas, ya que las barras de desplazamiento generalmente no se muestran.

Dicho esto, si su problema es calcular exactamente el ancho de la ventana gráfica sin barras de desplazamiento en todos los navegadores, hasta donde yo sé, un buen método es este:

width = $('body').innerWidth();

habiendo establecido previamente:

body {
    margin:0;
}
holden
fuente
2

La vwunidad no tiene overflow-yen cuenta la barra de desplazamiento cuando overflow-yestá configurada en auto.

Cámbielo a overflow-y: scroll;y la vwunidad será la ventana gráfica sin la barra de desplazamiento.

Único inconveniente a tener en cuenta. Si el contenido cabe en la pantalla, la barra de desplazamiento se muestra de todos modos. La posible solución es cambiar de autoa scrollen javascript.

Ilario Engler
fuente
1
¿te refieres overflow-x?
Eliran Malka
Esto no es verdad. La unidad vw incluye barra de desplazamiento conoverflow-y: scroll;
NoSkill
0

La única forma en que encontré que funciona sin alterar su código con "calc" es hacer que el tamaño del elemento del contenedor sea 100vw; Añadiendo una envoltura alrededor del contenedor para overflow-x; Esto hará que el contenedor sea de ancho completo como si la barra de desplazamiento estuviera sobre el contenido.

<!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>

SequenceDigitale.com
fuente
0

Si el caso fuera algo similar a un control deslizante: como se publicó en muchas respuestas, el ancho 100% no tiene en cuenta la barra de desplazamiento, mientras que 100vw sí. En el caso de tener muchos elementos que necesitan tomar el ancho de la ventana y que están anidados dentro de un contenedor que ya tiene el 100% de ancho de ventana (o cuyo ancho de bloque natural sería tal), puedes usar:

  • Pantalla flexible para contenedor
  • Flex: 0 0100% para elementos secundarios
Facundo Videla Peña
fuente
-3

La forma más sencilla es configurar el html & body en 100vw:

html, body{ width:100vw; overflow-x: hidden; overflow-y: auto; margin: 0; }

El único problema es que el extremo derecho se cortará un poco si se muestra la barra de desplazamiento.

goingvis
fuente
-3

en mi caso, tengo que configurar un div 100wh - 230px y estaba enfrentando el mismo problema con ese ancho de desplazamiento adicional, lo que hice es:

width: calc(100vw - (100vw - 100%) - 230px);
Omar Errabaany
fuente
-4

No es mi solución, pero me ayuda a crear un menú desplegable de ancho completo con absoluto en elemento relativo en no completo con intervalo.

Deberíamos hacer scroll con css var en: root y luego usarlo.

:root{
 --scrollbar-width: calc(100vw - 100%);
}


div { margin-right: var(--scrollbar-width); }

https://codepen.io/superkoders/pen/NwWyee

Denis Savenko
fuente
2
Esto solo funciona porque el div está en la raíz. Si el div no está en la raíz, se rompe. Esto se debe a que calc se resuelve cuando se hace referencia a él, en relación con el selector en el que se hace referencia, no donde está definido. codepen.io/Pedr/pen/YorLPM
Destracción