style color change html css dom

html - color - Entendiendo offsetWidth, clientWidth, scrollWidth y-He, respectivamente



style javascript (4)

Creé una versión más completa y más limpia que algunas personas podrían 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 las 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 padre posicionado más cercano (un elemento cuya propiedad de position se establece en un valor diferente al static o initial ). 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 elemento html o body como referencia

Espero que alguien lo encuentre útil, solo mis 2 centavos;)

Hay varias preguntas en StackOverflow con respecto a offsetWidth / clientWidth / scrollWidth (y -Height, respectivamente), pero ninguna da una explicación completa de cuáles son esos valores.

Además, hay varias fuentes en la web que proporcionan información confusa o incorrecta.

¿Puedes dar una explicación completa incluyendo algunos consejos visuales? Además, ¿cómo pueden usarse esos valores para calcular los anchos de las barras de desplazamiento?


El modelo de caja CSS es bastante complicado, particularmente cuando se trata de desplazar contenido. Si bien el navegador usa los valores de su CSS para dibujar cuadros, determinar todas las dimensiones utilizando 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 (por lo tanto, posiblemente sujetos a errores de redondeo).

Vamos a verlos 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 tiene una display: block
  • clientWidth , clientHeight : la parte visual del contenido de la caja, 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.

Pruébalo:

Como 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, podemos obtener errores de redondeo, ya que offsetWidth y clientWidth son siempre enteros, mientras que los tamaños reales pueden ser fraccionarios con niveles de zoom diferentes a 1.

Tenga en cuenta que este

scrollbarWidth = getComputedStyle().width + getComputedStyle().paddingLeft + getComputedStyle().paddingRight - clientWidth

no funciona de manera confiable en Chrome, ya que Chrome devuelve el width con la barra de desplazamiento ya restada. (Además, Chrome muestra paddingBottom en la parte inferior del contenido de desplazamiento, mientras que otros navegadores no)


Hay un buen artículo en 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 de boundingClientRect vs offsetWidth / offsetHeight.

Entonces, para probar que la teoría es correcta o incorrecta, necesitas algunas pruebas. Eso es lo que hice aquí: https://github.com/lingtalfi/dimensions-cheatsheet

Está probando para chrome53, ff49, safari9, edge13 y ie11.

Los resultados de las pruebas demuestran que la teoría es generalmente correcta. Para las pruebas, creé 3 divs que contenían 10 párrafos de ipsum de lorem cada uno. Se les aplicó algo de css:

.div1{ width: 500px; height: 300px; padding: 10px; border: 5px solid black; overflow: auto; } .div2{ width: 500px; height: 300px; padding: 10px; border: 5px solid black; box-sizing: border-box; overflow: auto; } .div3{ width: 500px; height: 300px; padding: 10px; border: 5px solid black; overflow: auto; transform: scale(0.5); }

Y aquí están los resultados:

  • div1

    • offsetWidth: 530 (chrome53, ff49, safari9, edge13, ie11)
    • offsetHeight: 330 (chrome53, ff49, safari9, edge13, ie11)
    • ancho de bcr: 530 (chrome53, ff49, safari9, edge13, ie11)
    • bcr.height: 330 (chrome53, ff49, safari9, edge13, ie11)

    • Ancho de cliente: 505 (chrome53, ff49, safari9)

    • Ancho de cliente: 508 (borde 13)
    • Ancho de cliente: 503 (ie11)
    • clientHeight: 320 (chrome53, ff49, safari9, edge13, ie11)

    • Ancho de desplazamiento: 505 (chrome53, safari9, ff49)

    • Ancho de desplazamiento: 508 (borde 13)
    • scrollWidth: 503 (ie11)
    • scrollHeight: 916 (chrome53, safari9)
    • scrollHeight: 954 (ff49)
    • scrollHeight: 922 (edge13, ie11)
  • div2

    • offsetWidth: 500 (chrome53, ff49, safari9, edge13, ie11)
    • offsetHeight: 300 (chrome53, ff49, safari9, edge13, ie11)
    • bcr.width: 500 (chrome53, ff49, safari9, edge13, ie11)
    • bcr.height: 300 (chrome53, ff49, safari9)
    • bcr.height: 299.9999694824219 (edge13, ie11)
    • Ancho de cliente: 475 (chrome53, ff49, safari9)
    • Ancho de cliente: 478 (borde 13)
    • Ancho de cliente: 473 (ie11)
    • clientHeight: 290 (chrome53, ff49, safari9, edge13, ie11)

    • Ancho de desplazamiento: 475 (chrome53, safari9, ff49)

    • Ancho de desplazamiento: 478 (borde 13)
    • ancho de desplazamiento: 473 (ie11)
    • scrollHeight: 916 (chrome53, safari9)
    • scrollHeight: 954 (ff49)
    • scrollHeight: 922 (edge13, ie11)
  • div3

    • offsetWidth: 530 (chrome53, ff49, safari9, edge13, ie11)
    • offsetHeight: 330 (chrome53, ff49, safari9, edge13, ie11)
    • bcr.width: 265 (chrome53, ff49, safari9, edge13, ie11)
    • bcr.height: 165 (chrome53, ff49, safari9, edge13, ie11)
    • Ancho de cliente: 505 (chrome53, ff49, safari9)
    • Ancho de cliente: 508 (borde 13)
    • Ancho de cliente: 503 (ie11)
    • clientHeight: 320 (chrome53, ff49, safari9, edge13, ie11)

    • Ancho de desplazamiento: 505 (chrome53, safari9, ff49)

    • Ancho de desplazamiento: 508 (borde 13)
    • scrollWidth: 503 (ie11)
    • scrollHeight: 916 (chrome53, safari9)
    • scrollHeight: 954 (ff49)
    • scrollHeight: 922 (edge13, ie11)

Entonces, aparte del valor de altura de boundingClientRect (299.9999694824219 en lugar de los 300 esperados) en edge13 y 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:

  • offsetWidth / offsetHeight: dimensiones del cuadro de borde de diseño
  • boundingClientRect: dimensiones del cuadro de borde de representación
  • clientWidth / clientHeight: dimensiones de la parte visible del cuadro de relleno de diseño (excluidas las barras de desplazamiento)
  • scrollWidth / scrollHeight: dimensiones del cuadro de relleno de diseño si no estuviera limitado por las barras de desplazamiento

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 se ha comprobado correctamente 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.

Por lo tanto, dadas las definiciones de esos conceptos, el ancho de la barra de desplazamiento vertical debe ser igual a (en pseudo có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 entiende 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 usted mismo), puede ver mi página de prueba aquí: http://codepen.io/lingtalfi/pen/BLdBdL


Si desea utilizar scrollWidth para obtener el ANCHO / ALTURA DE CONTENIDO "REAL" (ya que el contenido puede ser MÁS GRANDE que el cuadro de ancho / alto definido por css), el ancho de ancho / alto de scroll es muy INCREÍBLE ya que algunos navegadores parecen "MOVER" el relleno & paddingBOTTOM si el contenido es demasiado grande. Luego colocan los rellenos a la DERECHA / INFERIOR 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 aclaré un poco más en lo que respecta a los "rellenos movidos" y el "ancho de desplazamiento poco fiable". En el ÁREA AZUL, ¡encuentra mi solución sobre cómo obtener el ANCHO DE CONTENIDO "REAL"!

Espero que esto ayude a aclarar las cosas!