El modelo de cuadro CSS es bastante complicado, especialmente cuando se trata de desplazar contenido. Si bien el navegador usa los valores de su CSS para dibujar cuadros, determinar todas las dimensiones usando JS no es sencillo si solo tiene el CSS.
Es por eso que cada elemento tiene seis propiedades DOM para su conveniencia: offsetWidth
, offsetHeight
, clientWidth
, clientHeight
, scrollWidth
y scrollHeight
. Estos son atributos de solo lectura que representan el diseño visual actual, y todos ellos son enteros (posiblemente sujetos a errores de redondeo).
Veamos en detalle:
offsetWidth
, offsetHeight
: El tamaño del cuadro visual que incluye todos los bordes. Se puede calcular agregando width
/ height
y rellenos y bordes, si el elemento tienedisplay: block
clientWidth
, clientHeight
: La porción visual del contenido del cuadro, sin incluir bordes ni barras de desplazamiento, pero incluye relleno. No se puede calcular directamente desde CSS, depende del tamaño de la barra de desplazamiento del sistema.
scrollWidth
, scrollHeight
: El tamaño de todo el contenido del cuadro, incluidas las partes que actualmente están ocultas fuera del área de desplazamiento. No se puede calcular directamente desde CSS, depende del contenido.
Dado que offsetWidth
tiene en cuenta el ancho de la barra de desplazamiento, podemos usarlo para calcular el ancho de la barra de desplazamiento mediante la fórmula
scrollbarWidth = offsetWidth - clientWidth - getComputedStyle().borderLeftWidth - getComputedStyle().borderRightWidth
Desafortunadamente, puede obtener errores de redondeo, puesto offsetWidth
y clientWidth
siempre son números enteros, mientras que los tamaños reales pueden ser fraccionada con niveles de zoom distintos a 1.
Tenga en cuenta que esto
scrollbarWidth = getComputedStyle().width + getComputedStyle().paddingLeft + getComputedStyle().paddingRight - clientWidth
no no funcionar de forma fiable en Chrome, ya que Chrome vuelve width
con barra de desplazamiento ya se restan. (Además, Chrome muestra el relleno de la parte inferior a la parte inferior del contenido de desplazamiento, mientras que otros navegadores no)
element.getBoundingClientRect()
(vea la nota en developer.mozilla.org/en-US/docs/Web/API/Element.clientWidth )naturalWidth
ynaturalHeight
scrollHeight
incluyepadding-bottom
peroscrollWidth
no incluyepadding-right
clientWidth
paradocument.documentElement.clientWidth
es diferente, ya que parece incluir elpadding
,borders
ymargin
Creé una versión más completa y limpia que algunas personas pueden encontrar útil para recordar qué nombre corresponde a qué valor. Utilicé el código de color de Chrome Dev Tool y las etiquetas están organizadas simétricamente para captar analogías más rápido:
Nota 1:
clientLeft
también incluye el ancho de la barra de desplazamiento vertical si la dirección del texto se establece de derecha a izquierda (ya que la barra se muestra a la izquierda en ese caso)Nota 2: la línea más externa representa el más cercano posicionado padre (un elemento cuya
position
propiedad está ajustado a un valor diferente destatic
oinitial
). Por lo tanto, si el contenedor directo no es un elemento posicionado , entonces la línea no representa el primer contenedor en la jerarquía sino otro elemento más alto en la jerarquía. Si no se encuentra ningún padre posicionado , el navegador tomará el elementohtml
obody
como referenciaEspero que alguien lo encuentre útil, solo mis 2 centavos;)
fuente
Si desea usar scrollWidth para obtener el ANCHO / ALTURA DE CONTENIDO "REAL" (ya que el contenido puede ser MÁS GRANDE que el ancho / alto-cuadro definido por css), el ancho / alto de desplazamiento es muy poco confiable ya que algunos navegadores parecen "MOVER" el relleno DERECHO & paddingBOTTOM si el contenido es demasiado grande. Luego colocan los rellenos a la DERECHA / ABAJO del "contenido demasiado amplio / alto" (vea la imagen a continuación).
==> Por lo tanto, para obtener el ANCHO DE CONTENIDO REAL en algunos navegadores, debe restar AMBOS rellenos del ancho de desplazamiento y en algunos navegadores solo debe restar el Relleno IZQUIERDO.
Encontré una solución para esto y quería agregar esto como un comentario, pero no estaba permitido. Así que tomé la foto y la hice un poco más clara con respecto a los "rellenos movidos" y el "ancho de desplazamiento poco confiable". ¡En el ÁREA AZUL encontrará mi solución sobre cómo obtener el ANCHO DE CONTENIDO "REAL"!
¡Espero que esto ayude a aclarar las cosas!
fuente
Hay un buen artículo sobre MDN que explica la teoría detrás de esos conceptos: https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements
También explica las importantes diferencias conceptuales entre el ancho / alto del límite de ClientRect frente a offsetWidth / offsetHeight.
Luego, para demostrar que la teoría es correcta o incorrecta, necesita algunas pruebas. Eso es lo que hice aquí: https://github.com/lingtalfi/dimensions-cheatsheet
Está probando chrome53, ff49, safari9, edge13 e ie11.
Los resultados de las pruebas demuestran que la teoría es generalmente correcta. Para las pruebas, creé 3 divs que contienen 10 párrafos lorem ipsum cada uno. Se les aplicó algo de CSS:
Y aquí están los resultados:
div1
bcr. altura: 330 (chrome53, ff49, safari9, edge13, ie11)
ancho del cliente: 505 (chrome53, ff49, safari9)
clientHeight: 320 (chrome53, ff49, safari9, edge13, ie11)
scrollWidth: 505 (chrome53, safari9, ff49)
div2
clientHeight: 290 (chrome53, ff49, safari9, edge13, ie11)
scrollWidth: 475 (chrome53, safari9, ff49)
div3
clientHeight: 320 (chrome53, ff49, safari9, edge13, ie11)
scrollWidth: 505 (chrome53, safari9, ff49)
Por lo tanto, aparte del valor de altura del límite de ClientRect (299.9999694824219 en lugar del esperado 300) en edge13 e ie11, los resultados confirman que la teoría detrás de esto funciona.
A partir de ahí, aquí está mi definición de esos conceptos:
Nota: el ancho predeterminado de la barra de desplazamiento vertical es 12px en edge13, 15px en chrome53, ff49 y safari9, y 17px en ie11 (hecho por mediciones en photoshop a partir de capturas de pantalla, y demostrado por los resultados de las pruebas).
Sin embargo, en algunos casos, tal vez su aplicación no esté utilizando el ancho predeterminado de la barra de desplazamiento vertical.
Entonces, dadas las definiciones de esos conceptos, el ancho de la barra de desplazamiento vertical debe ser igual a (en pseudocódigo):
dimensión de diseño: offsetWidth - clientWidth - (borderLeftWidth + borderRightWidth)
dimensión de representación: boundingClientRect.width - clientWidth - (borderLeftWidth + borderRightWidth)
Tenga en cuenta que si no comprende el diseño frente a la representación, lea el artículo de mdn.
Además, si tiene otro navegador (o si desea ver los resultados de las pruebas por sí mismo), puede ver mi página de prueba aquí: http://codepen.io/lingtalfi/pen/BLdBdL
fuente