{"id":83165,"date":"2022-07-25T16:53:42","date_gmt":"2022-07-25T14:53:42","guid":{"rendered":"https:\/\/rmarketingdigital.com\/dev\/representacion-perfecta-de-pixeles-con-devicepixelcontentbox\/"},"modified":"2020-09-16T19:12:02","modified_gmt":"2020-09-16T22:12:02","slug":"representacion-perfecta-de-pixeles-con-devicepixelcontentbox","status":"publish","type":"post","link":"https:\/\/rmarketingdigital.com\/de\/dev\/representacion-perfecta-de-pixeles-con-devicepixelcontentbox\/","title":{"rendered":"Pixel perfektes Rendern mit devicePixelContentBox"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_86 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Contenidos<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/rmarketingdigital.com\/de\/dev\/representacion-perfecta-de-pixeles-con-devicepixelcontentbox\/#Fondo-pixeles-CSS-pixeles-de-lienzo-y-pixeles-fisicos\" >Fondo: p\u00edxeles CSS, p\u00edxeles de lienzo y p\u00edxeles f\u00edsicos<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/rmarketingdigital.com\/de\/dev\/representacion-perfecta-de-pixeles-con-devicepixelcontentbox\/#Perfeccion-de-pixeles\" >Perfecci\u00f3n de p\u00edxeles<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/rmarketingdigital.com\/de\/dev\/representacion-perfecta-de-pixeles-con-devicepixelcontentbox\/#Ajuste-de-pixeles\" >Ajuste de p\u00edxeles<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/rmarketingdigital.com\/de\/dev\/representacion-perfecta-de-pixeles-con-devicepixelcontentbox\/#devicePixelContentBox\" >devicePixelContentBox<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/rmarketingdigital.com\/de\/dev\/representacion-perfecta-de-pixeles-con-devicepixelcontentbox\/#Deteccion-de-caracteristicas\" >Detecci\u00f3n de caracter\u00edsticas<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/rmarketingdigital.com\/de\/dev\/representacion-perfecta-de-pixeles-con-devicepixelcontentbox\/#Conclusion\" >Conclusi\u00f3n<\/a><\/li><\/ul><\/nav><\/div>\n<p><\/p>\n<div>\n<header class=\"w-article-header\">\n<p class=\"w-article-header__subhead w-mb--non\">\n<p>          Cuantos pixeles hay <em>De Verdad<\/em> en un lienzo?\n        <\/p>\n<p>\n          <time>7 de julio de 2020<\/time><\/p>\n<\/header>\n<p>Desde Chrome 84, ResizeObserver admite una nueva medida de caja llamada <code>device-pixel-content-box<\/code>, que mide la dimensi\u00f3n del elemento en <em>f\u00edsico<\/em> p\u00edxeles.  Esto permite renderizar gr\u00e1ficos con p\u00edxeles perfectos, especialmente en el contexto de pantallas de alta densidad.<\/p>\n<h2 id=\"background:-css-pixels-canvas-pixels-and-physical-pixels\"><span class=\"ez-toc-section\" id=\"Fondo-pixeles-CSS-pixeles-de-lienzo-y-pixeles-fisicos\"><\/span>Fondo: p\u00edxeles CSS, p\u00edxeles de lienzo y p\u00edxeles f\u00edsicos <span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Si bien a menudo trabajamos con unidades abstractas de longitud como <code>em<\/code>, <code>%<\/code> o <code>vh<\/code>, todo se reduce a p\u00edxeles.  Siempre que especifiquemos el tama\u00f1o o la posici\u00f3n de un elemento en CSS, el motor de dise\u00f1o del navegador eventualmente convertir\u00e1 ese valor en p\u00edxeles (<code>px<\/code>).  Estos son \u00abP\u00edxeles CSS\u00bb, que tienen mucho historial y solo tienen una relaci\u00f3n poco precisa con los p\u00edxeles que tienes en tu pantalla.<\/p>\n<p>Durante mucho tiempo, fue bastante razonable estimar la densidad de p\u00edxeles de la pantalla de cualquier persona con 96 ppp (\u00abpuntos por pulgada\u00bb), lo que significa que cualquier monitor tendr\u00eda aproximadamente 38 p\u00edxeles por cm.  Con el tiempo, los monitores crecieron y \/ o encogieron o empezaron a tener m\u00e1s p\u00edxeles en la misma superficie.  Combine eso con el hecho de que una gran cantidad de contenido en la web define sus dimensiones, incluidos los tama\u00f1os de fuente, en <code>px<\/code>, y terminamos con texto ilegible en estas pantallas de alta densidad (\u00abHiDPI\u00bb).  Como contramedida, los navegadores ocultan la densidad de p\u00edxeles real del monitor y, en su lugar, fingen que el usuario tiene una pantalla de 96 DPI.  los <code>px<\/code> unidad en CSS representa el tama\u00f1o de un p\u00edxel en este <em>virtual<\/em> Pantalla de 96 DPI, de ah\u00ed el nombre \u00abCSS Pixel\u00bb.  Esta unidad solo se utiliza para medici\u00f3n y posicionamiento.  Antes de que ocurra cualquier renderizado real, ocurre una conversi\u00f3n a p\u00edxeles f\u00edsicos.<\/p>\n<p>\u00bfC\u00f3mo pasamos de esta pantalla virtual a la pantalla real del usuario?  Entrar <code>devicePixelRatio<\/code>.  Este valor global le dice cu\u00e1ntos <em>f\u00edsico<\/em> p\u00edxeles que necesita para formar un solo p\u00edxel CSS.  Si <code>devicePixelRatio<\/code> (dPR) es <code>1<\/code>, est\u00e1 trabajando en un monitor con aproximadamente 96 ppp.  Si tiene una pantalla de retina, probablemente su dPR sea <code>2<\/code>.  En los tel\u00e9fonos, no es raro encontrar valores dPR m\u00e1s altos (y m\u00e1s extra\u00f1os) como <code>2<\/code>, <code>3<\/code> o incluso <code>2.65<\/code>.  Es fundamental tener en cuenta que este valor es <em>exacto<\/em>, pero no le permite derivar el monitor <em>real<\/em> Valor de DPI.  Un dPR de <code>2<\/code> significa que 1 p\u00edxel CSS se asignar\u00e1 a <em>exactamente<\/em> 2 p\u00edxeles f\u00edsicos.<\/p>\n<details class=\"w-details\">\n<summary class=\"w-details__summary\">\n<p class=\"w-details__preview\">  Mi monitor tiene un dPR de <code>1<\/code> seg\u00fan Chrome &#8230;<\/p>\n<\/summary>\n<p>  Tiene 3440 p\u00edxeles de ancho y el \u00e1rea de visualizaci\u00f3n es de 79 cm de ancho.  Eso conduce a una resoluci\u00f3n de 110 DPI.  Cerca de 96, pero no del todo.  \u00c9sa es tambi\u00e9n la raz\u00f3n por la que <code>&lt;div style=\"width: 1cm; height: 1cm\"&gt;<\/code><br \/>\n  no medir\u00e1 exactamente 1 cm de tama\u00f1o en la mayor\u00eda de las pantallas.<br \/>\n<\/details>\n<p>Finalmente, dPR tambi\u00e9n puede verse afectado por la funci\u00f3n de zoom de su navegador.  Si hace zoom, el navegador aumenta el dPR informado, lo que hace que todo se vea m\u00e1s grande.  Si miras <code>devicePixelRatio<\/code> en una Consola de DevTools mientras hace zoom, puede ver que aparecen valores fraccionarios.<\/p>\n<figure class=\"w-figure\">\n  <img alt='dprs-1305951' src='https:\/\/rmarketingdigital.com\/wp-content\/uploads\/2020\/09\/dprs-1305951.png' alt=\"\" class=\"w-screenshot\" width=\"600\"><figcaption class=\"w-figcaption\">DevTools que muestra una variedad de <code>devicePixelRatio<\/code> debido al zoom.<\/figcaption><\/figure>\n<p>Agreguemos el <code>&lt;canvas&gt;<\/code> elemento a la mezcla.  Puede especificar cu\u00e1ntos p\u00edxeles desea que tenga el lienzo utilizando el <code>width<\/code> y <code>height<\/code> atributos.  Entonces <code>&lt;canvas width=40 height=30&gt;<\/code> ser\u00eda un lienzo de 40 por 30 p\u00edxeles.  Sin embargo, esto no significa que ser\u00e1 <em>desplegado<\/em> a 40 por 30 p\u00edxeles.  De forma predeterminada, el lienzo utilizar\u00e1 el <code>width<\/code> y <code>height<\/code> atributo para definir su tama\u00f1o intr\u00ednseco, pero puede cambiar el tama\u00f1o del lienzo arbitrariamente utilizando todas las propiedades CSS que conoce y ama.  Con todo lo que hemos aprendido hasta ahora, se le puede ocurrir que esto no ser\u00e1 ideal en todos los escenarios.  Un p\u00edxel en el lienzo puede terminar cubriendo varios p\u00edxeles f\u00edsicos o solo una fracci\u00f3n de un p\u00edxel f\u00edsico.  Esto puede generar artefactos visuales desagradables.<\/p>\n<p>Para resumir: Los elementos del lienzo tienen un tama\u00f1o determinado para definir el \u00e1rea en la que puede dibujar.  El n\u00famero de p\u00edxeles del lienzo es completamente independiente del tama\u00f1o de visualizaci\u00f3n del lienzo, especificado en p\u00edxeles CSS.  El n\u00famero de p\u00edxeles CSS no es el mismo que el n\u00famero de p\u00edxeles f\u00edsicos.<\/p>\n<h3 id=\"pixel-perfection\"><span class=\"ez-toc-section\" id=\"Perfeccion-de-pixeles\"><\/span>Perfecci\u00f3n de p\u00edxeles <span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>En algunos escenarios, es deseable tener un mapeo exacto de los p\u00edxeles del lienzo a los p\u00edxeles f\u00edsicos.  Si se logra este mapeo, se llama \u00abp\u00edxel perfecto\u00bb.  La representaci\u00f3n perfecta de p\u00edxeles es crucial para la representaci\u00f3n legible de texto, especialmente cuando se usa <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/en.wikipedia.org\/wiki\/Subpixel_rendering\">representaci\u00f3n de subp\u00edxeles<\/a> o al mostrar gr\u00e1ficos con l\u00edneas muy alineadas de brillo alterno.<\/p>\n<p>Para lograr algo lo m\u00e1s cercano posible a un lienzo de p\u00edxeles perfectos en la web, este ha sido m\u00e1s o menos el enfoque a seguir:<\/p>\n<p><web-copy-code><\/p>\n<pre class=\"language-html\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>style<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token style\"><span class=\"token language-css\"><br><\/span><\/span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>style<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>canvas<\/span> <span class=\"token attr-name\">id<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=<\/span><span class=\"token punctuation\">\"<\/span>myCanvas<span class=\"token punctuation\">\"<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>canvas<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><br><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>script<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><span class=\"token script\"><span class=\"token language-javascript\"><br><span class=\"token keyword\">const<\/span> cvs <span class=\"token operator\">=<\/span> document<span class=\"token punctuation\">.<\/span><span class=\"token function\">querySelector<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'#myCanvas'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br><span class=\"token keyword\">const<\/span> rectangle <span class=\"token operator\">=<\/span> cvs<span class=\"token punctuation\">.<\/span><span class=\"token function\">getBoundingClientRect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br>cvs<span class=\"token punctuation\">.<\/span>width <span class=\"token operator\">=<\/span> rectangle<span class=\"token punctuation\">.<\/span>width <span class=\"token operator\">*<\/span> devicePixelRatio<span class=\"token punctuation\">;<\/span><br>cvs<span class=\"token punctuation\">.<\/span>height <span class=\"token operator\">=<\/span> rectangle<span class=\"token punctuation\">.<\/span>height <span class=\"token operator\">*<\/span> devicePixelRatio<span class=\"token punctuation\">;<\/span><br><\/span><\/span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>script<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/code><\/pre>\n<p><\/web-copy-code><\/p>\n<p>El lector astuto podr\u00eda preguntarse qu\u00e9 sucede cuando dPR no es un valor entero.  Esa es una buena pregunta y exactamente d\u00f3nde radica el meollo de todo este problema.  Adem\u00e1s, si especifica la posici\u00f3n o el tama\u00f1o de un elemento mediante porcentajes, <code>vh<\/code>u otros valores indirectos, es posible que se resuelvan en valores de p\u00edxeles de CSS fraccionarios.  Un elemento con <code>margin-left: 33%<\/code> puede terminar con un rect\u00e1ngulo como este:<\/p>\n<figure class=\"w-figure\">\n  <img alt='fractional-pixels-9178262' src='https:\/\/rmarketingdigital.com\/wp-content\/uploads\/2020\/09\/fractional-pixels-9178262.png' alt=\"\" class=\"w-screenshot\" width=\"600\"><figcaption class=\"w-figcaption\">DevTools que muestra valores de p\u00edxeles fraccionarios como resultado de una <code>getBoundingClientRect()<\/code> llamada.<\/figcaption><\/figure>\n<p>Los p\u00edxeles CSS son puramente virtuales, por lo que tener fracciones de un p\u00edxel est\u00e1 bien en teor\u00eda, pero \u00bfc\u00f3mo calcula el navegador la asignaci\u00f3n a los p\u00edxeles f\u00edsicos?  Porque fraccional <em>f\u00edsico<\/em> los p\u00edxeles no son una cosa.<\/p>\n<h2 id=\"pixel-snapping\"><span class=\"ez-toc-section\" id=\"Ajuste-de-pixeles\"><\/span>Ajuste de p\u00edxeles <span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>La parte del proceso de conversi\u00f3n de unidades que se encarga de alinear elementos con p\u00edxeles f\u00edsicos se denomina \u00abajuste de p\u00edxeles\u00bb, y hace lo que dice en la lata: ajusta valores de p\u00edxeles fraccionarios a valores de p\u00edxeles f\u00edsicos enteros.  La forma en que esto sucede exactamente es diferente de un navegador a otro.  Si tenemos un elemento con un ancho de <code>791.984px<\/code> en una pantalla donde dPR es 1, un navegador puede representar el elemento en <code>792px<\/code> p\u00edxeles f\u00edsicos, mientras que otro navegador puede representarlo en <code>791px<\/code>.  Eso es solo un p\u00edxel menos, pero un solo p\u00edxel puede ser perjudicial para las representaciones que deben ser perfectas en p\u00edxeles.  Esto puede provocar borrosidad o incluso artefactos m\u00e1s visibles como el <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/en.wikipedia.org\/wiki\/Moir%C3%A9_pattern\">Efecto moir\u00e9<\/a>.<\/p>\n<figure class=\"w-figure\">\n  <img alt='side-by-side-5944113' src='https:\/\/rmarketingdigital.com\/wp-content\/uploads\/2020\/09\/side-by-side-5944113.png' alt=\"\" class=\"w-screenshot\" width=\"600\"><figcaption class=\"w-figcaption\">La imagen superior es una trama de p\u00edxeles de diferentes colores.  La imagen inferior es la misma que la anterior, pero el ancho y la altura se han reducido en un p\u00edxel mediante la escala bilineal.  El patr\u00f3n emergente se llama efecto Moir\u00e9.<br \/>(Puede que tenga que abrir esta imagen en una nueva pesta\u00f1a para verla sin aplicarle ninguna escala).<\/figcaption><\/figure>\n<h2 id=\"devicepixelcontentbox\"><span class=\"ez-toc-section\" id=\"devicePixelContentBox\"><\/span><code>devicePixelContentBox<\/code> <span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><code>devicePixelContentBox<\/code>  le ofrece el cuadro de contenido de un elemento en unidades de p\u00edxeles del dispositivo (es decir, p\u00edxeles f\u00edsicos).  Es parte de <code>ResizeObserver<\/code>.  Mientras <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/caniuse.com\/#feat=resizeobserver\">ResizeObserver ahora es compatible con todos los navegadores principales<\/a> desde Safari 13.1, el <code>devicePixelContentBox<\/code> La propiedad solo est\u00e1 en Chrome 84+ por ahora.<\/p>\n<p>Como se menciona en <code>ResizeObserver<\/code>: es como <code>document.onresize<\/code> para elementos, la funci\u00f3n de devoluci\u00f3n de llamada de un <code>ResizeObserver<\/code> se llamar\u00e1 antes de pintar y despu\u00e9s del dise\u00f1o.  Eso significa que el <code>entries<\/code> El par\u00e1metro de la devoluci\u00f3n de llamada contendr\u00e1 los tama\u00f1os de todos los elementos observados justo antes de que se pinten.  En el contexto de nuestro problema de lienzo descrito anteriormente, podemos aprovechar esta oportunidad para ajustar la cantidad de p\u00edxeles en nuestro lienzo, asegur\u00e1ndonos de que terminemos con un mapeo exacto uno a uno entre los p\u00edxeles del lienzo y los p\u00edxeles f\u00edsicos.<\/p>\n<p><web-copy-code><\/p>\n<pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const<\/span> observer <span class=\"token operator\">=<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">ResizeObserver<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">entries<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span><br><span class=\"token keyword\">const<\/span> entry <span class=\"token operator\">=<\/span> entries<span class=\"token punctuation\">.<\/span><span class=\"token function\">find<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">entry<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> entry<span class=\"token punctuation\">.<\/span>target <span class=\"token operator\">===<\/span> canvas<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br>canvas<span class=\"token punctuation\">.<\/span>width <span class=\"token operator\">=<\/span> entry<span class=\"token punctuation\">.<\/span>devicePixelContentBoxSize<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>inlineSize<span class=\"token punctuation\">;<\/span><br>canvas<span class=\"token punctuation\">.<\/span>height <span class=\"token operator\">=<\/span> entry<span class=\"token punctuation\">.<\/span>devicePixelContentBoxSize<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>blockSize<span class=\"token punctuation\">;<\/span><p><br><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br>observer<span class=\"token punctuation\">.<\/span><span class=\"token function\">observe<\/span><span class=\"token punctuation\">(<\/span>canvas<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span>box<span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">'device-pixel-content-box'<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p><\/code><\/pre>\n<p><\/web-copy-code><\/p>\n<p>los <code>box<\/code> propiedad en el objeto de opciones para <code>observer.observe()<\/code> le permite definir qu\u00e9 tama\u00f1os desea <em>observar<\/em>.  As\u00ed que mientras cada <code>ResizeObserverEntry<\/code> siempre proporcionar\u00e1 <code>borderBoxSize<\/code>, <code>contentBoxSize<\/code> y <code>devicePixelContentBoxSize<\/code> (siempre que el navegador lo admita), la devoluci\u00f3n de llamada solo se invocar\u00e1 si alguno de los <em>observado<\/em> las m\u00e9tricas de caja cambian.<\/p>\n<div class=\"w-aside w-aside--note\">\n<p>Todas las m\u00e9tricas de caja son matrices para permitir <code>ResizeObserver<\/code> para manejar la fragmentaci\u00f3n en el futuro.  En el momento de escribir este art\u00edculo, la matriz siempre tiene una longitud de 1.<\/p>\n<\/div>\n<p>Con esta nueva propiedad, incluso podemos animar el tama\u00f1o y la posici\u00f3n de nuestro lienzo (garantizando efectivamente valores de p\u00edxeles fraccionarios) y no ver ning\u00fan efecto Moir\u00e9 en el renderizado.  Si desea ver el efecto Moir\u00e9 en el enfoque utilizando <code>getBoundingClientRect()<\/code>y como el nuevo <code>ResizeObserver<\/code> propiedad le permite evitarlo, eche un vistazo a la <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/device-pixel-content-box.glitch.me\/\">manifestaci\u00f3n<\/a> en Chrome 84 o posterior.<\/p>\n<h3 id=\"feature-detection\"><span class=\"ez-toc-section\" id=\"Deteccion-de-caracteristicas\"><\/span>Detecci\u00f3n de caracter\u00edsticas <span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Para comprobar si el navegador de un usuario es compatible con <code>devicePixelContentBox<\/code>, podemos observar cualquier elemento y comprobar si la propiedad est\u00e1 presente en el <code>ResizeObserverEntry<\/code>:<\/p>\n<p><web-copy-code><\/p>\n<pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">function<\/span> <span class=\"token function\">hasDevicePixelContentBox<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br><span class=\"token keyword\">return<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">Promise<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">resolve<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span><br><span class=\"token keyword\">const<\/span> ro <span class=\"token operator\">=<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">ResizeObserver<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">entries<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span><br><span class=\"token function\">resolve<\/span><span class=\"token punctuation\">(<\/span>entries<span class=\"token punctuation\">.<\/span><span class=\"token function\">every<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">entry<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token string\">'devicePixelContentBoxSize'<\/span> <span class=\"token keyword\">in<\/span> entry<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br>ro<span class=\"token punctuation\">.<\/span><span class=\"token function\">disconnect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br>ro<span class=\"token punctuation\">.<\/span><span class=\"token function\">observe<\/span><span class=\"token punctuation\">(<\/span>document<span class=\"token punctuation\">.<\/span>body<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span>box<span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">'device-pixel-content-box'<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">catch<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br><span class=\"token punctuation\">}<\/span><p><span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">await<\/span> <span class=\"token function\">hasDevicePixelContentBox<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br><span class=\"token punctuation\">}<\/span><\/p><\/code><\/pre>\n<p><\/web-copy-code><\/p>\n<h2 id=\"conclusion\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusi\u00f3n <span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Los p\u00edxeles son un tema sorprendentemente complejo en la web y hasta ahora no hab\u00eda forma de saber el n\u00famero exacto de p\u00edxeles f\u00edsicos que ocupa un elemento en la pantalla del usuario.  El nuevo <code>devicePixelContentBox<\/code> propiedad en una <code>ResizeObserverEntry<\/code> le brinda esa informaci\u00f3n y le permite hacer representaciones perfectas en p\u00edxeles con <code>&lt;canvas&gt;<\/code>. <code>devicePixelContentBox<\/code> es compatible con Chrome 84+.<\/p>\n<p>    <web-feedback additional-questions=\"api\"><\/web-feedback>\n  <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Cuantos pixeles hay De Verdad en un lienzo? 7 de julio de 2020 Desde Chrome 84, ResizeObserver admite una nueva medida de caja llamada device-pixel-content-box, que mide la dimensi\u00f3n del&#8230;<\/p>","protected":false},"author":1,"featured_media":83166,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1356],"tags":[],"class_list":["post-83165","post","type-post","status-publish","format-standard","has-post-thumbnail","category-dev"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.0 (Yoast SEO v28.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Representaci\u00f3n perfecta de p\u00edxeles con devicePixelContentBox - R Marketing Digital<\/title>\n<meta name=\"description\" content=\"Cuantos pixeles hay De Verdad en un lienzo? 7 de julio de 2020 Desde Chrome 84, ResizeObserver admite una nueva medida de caja llamada\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/rmarketingdigital.com\/de\/dev\/pixel-perfect-rendering-with-devicepixelcontentbox\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Representaci\u00f3n perfecta de p\u00edxeles con devicePixelContentBox\" \/>\n<meta property=\"og:description\" content=\"Cuantos pixeles hay De Verdad en un lienzo? 7 de julio de 2020 Desde Chrome 84, ResizeObserver admite una nueva medida de caja llamada\" \/>\n<meta property=\"og:url\" content=\"https:\/\/rmarketingdigital.com\/de\/dev\/pixel-perfect-rendering-with-devicepixelcontentbox\/\" \/>\n<meta property=\"og:site_name\" content=\"R Marketing Digital\" \/>\n<meta property=\"article:published_time\" content=\"2022-07-25T14:53:42+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/rmarketingdigital.com\/wp-content\/uploads\/2020\/09\/pixels-3418453.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"360\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"R Marketing Digital\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/en\\\/dev\\\/pixel-perfect-rendering-with-devicepixelcontentbox\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/en\\\/dev\\\/pixel-perfect-rendering-with-devicepixelcontentbox\\\/\"},\"author\":{\"name\":\"R Marketing Digital\",\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/#\\\/schema\\\/person\\\/7c0d9782b2977b840b3740f00c69a73e\"},\"headline\":\"Representaci\u00f3n perfecta de p\u00edxeles con devicePixelContentBox\",\"datePublished\":\"2022-07-25T14:53:42+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/en\\\/dev\\\/pixel-perfect-rendering-with-devicepixelcontentbox\\\/\"},\"wordCount\":1570,\"image\":{\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/en\\\/dev\\\/pixel-perfect-rendering-with-devicepixelcontentbox\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/rmarketingdigital.com\\\/wp-content\\\/uploads\\\/2020\\\/09\\\/pixels-3418453.jpg\",\"articleSection\":[\"Dev\"],\"inLanguage\":\"de\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/en\\\/dev\\\/pixel-perfect-rendering-with-devicepixelcontentbox\\\/\",\"url\":\"https:\\\/\\\/rmarketingdigital.com\\\/en\\\/dev\\\/pixel-perfect-rendering-with-devicepixelcontentbox\\\/\",\"name\":\"Representaci\u00f3n perfecta de p\u00edxeles con devicePixelContentBox - R Marketing Digital\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/en\\\/dev\\\/pixel-perfect-rendering-with-devicepixelcontentbox\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/en\\\/dev\\\/pixel-perfect-rendering-with-devicepixelcontentbox\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/rmarketingdigital.com\\\/wp-content\\\/uploads\\\/2020\\\/09\\\/pixels-3418453.jpg\",\"datePublished\":\"2022-07-25T14:53:42+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/#\\\/schema\\\/person\\\/7c0d9782b2977b840b3740f00c69a73e\"},\"description\":\"Cuantos pixeles hay De Verdad en un lienzo? 7 de julio de 2020 Desde Chrome 84, ResizeObserver admite una nueva medida de caja llamada\",\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/rmarketingdigital.com\\\/en\\\/dev\\\/pixel-perfect-rendering-with-devicepixelcontentbox\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/en\\\/dev\\\/pixel-perfect-rendering-with-devicepixelcontentbox\\\/#primaryimage\",\"url\":\"https:\\\/\\\/rmarketingdigital.com\\\/wp-content\\\/uploads\\\/2020\\\/09\\\/pixels-3418453.jpg\",\"contentUrl\":\"https:\\\/\\\/rmarketingdigital.com\\\/wp-content\\\/uploads\\\/2020\\\/09\\\/pixels-3418453.jpg\",\"width\":1200,\"height\":360,\"caption\":\"pixels-3418453-1385843-jpg\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/#website\",\"url\":\"https:\\\/\\\/rmarketingdigital.com\\\/\",\"name\":\"R Marketing Digital\",\"description\":\"Agencia SEO | Publicidad redes sociales | Community Management\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/rmarketingdigital.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/rmarketingdigital.com\\\/#\\\/schema\\\/person\\\/7c0d9782b2977b840b3740f00c69a73e\",\"name\":\"R Marketing Digital\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c5599c203e0120b8ccbff4666af86f35f9b3dcad468a8bc6295313a3964a80be?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c5599c203e0120b8ccbff4666af86f35f9b3dcad468a8bc6295313a3964a80be?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c5599c203e0120b8ccbff4666af86f35f9b3dcad468a8bc6295313a3964a80be?s=96&d=mm&r=g\",\"caption\":\"R Marketing Digital\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Representaci\u00f3n perfecta de p\u00edxeles con devicePixelContentBox - R Marketing Digital","description":"Wie viele Pixel gibt es wirklich auf einer Leinwand? 7. Juli 2020 Seit Chrome 84 unterst\u00fctzt ResizeObserver eine neue Kassiererma\u00dfnahme namens","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/rmarketingdigital.com\/de\/dev\/pixel-perfect-rendering-with-devicepixelcontentbox\/","og_locale":"de_DE","og_type":"article","og_title":"Representaci\u00f3n perfecta de p\u00edxeles con devicePixelContentBox","og_description":"Cuantos pixeles hay De Verdad en un lienzo? 7 de julio de 2020 Desde Chrome 84, ResizeObserver admite una nueva medida de caja llamada","og_url":"https:\/\/rmarketingdigital.com\/de\/dev\/pixel-perfect-rendering-with-devicepixelcontentbox\/","og_site_name":"R Marketing Digital","article_published_time":"2022-07-25T14:53:42+00:00","og_image":[{"width":1200,"height":360,"url":"https:\/\/rmarketingdigital.com\/wp-content\/uploads\/2020\/09\/pixels-3418453.jpg","type":"image\/jpeg"}],"author":"R Marketing Digital","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/rmarketingdigital.com\/en\/dev\/pixel-perfect-rendering-with-devicepixelcontentbox\/#article","isPartOf":{"@id":"https:\/\/rmarketingdigital.com\/en\/dev\/pixel-perfect-rendering-with-devicepixelcontentbox\/"},"author":{"name":"R Marketing Digital","@id":"https:\/\/rmarketingdigital.com\/#\/schema\/person\/7c0d9782b2977b840b3740f00c69a73e"},"headline":"Representaci\u00f3n perfecta de p\u00edxeles con devicePixelContentBox","datePublished":"2022-07-25T14:53:42+00:00","mainEntityOfPage":{"@id":"https:\/\/rmarketingdigital.com\/en\/dev\/pixel-perfect-rendering-with-devicepixelcontentbox\/"},"wordCount":1570,"image":{"@id":"https:\/\/rmarketingdigital.com\/en\/dev\/pixel-perfect-rendering-with-devicepixelcontentbox\/#primaryimage"},"thumbnailUrl":"https:\/\/rmarketingdigital.com\/wp-content\/uploads\/2020\/09\/pixels-3418453.jpg","articleSection":["Dev"],"inLanguage":"de"},{"@type":"WebPage","@id":"https:\/\/rmarketingdigital.com\/en\/dev\/pixel-perfect-rendering-with-devicepixelcontentbox\/","url":"https:\/\/rmarketingdigital.com\/en\/dev\/pixel-perfect-rendering-with-devicepixelcontentbox\/","name":"Representaci\u00f3n perfecta de p\u00edxeles con devicePixelContentBox - R Marketing Digital","isPartOf":{"@id":"https:\/\/rmarketingdigital.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/rmarketingdigital.com\/en\/dev\/pixel-perfect-rendering-with-devicepixelcontentbox\/#primaryimage"},"image":{"@id":"https:\/\/rmarketingdigital.com\/en\/dev\/pixel-perfect-rendering-with-devicepixelcontentbox\/#primaryimage"},"thumbnailUrl":"https:\/\/rmarketingdigital.com\/wp-content\/uploads\/2020\/09\/pixels-3418453.jpg","datePublished":"2022-07-25T14:53:42+00:00","author":{"@id":"https:\/\/rmarketingdigital.com\/#\/schema\/person\/7c0d9782b2977b840b3740f00c69a73e"},"description":"Wie viele Pixel gibt es wirklich auf einer Leinwand? 7. Juli 2020 Seit Chrome 84 unterst\u00fctzt ResizeObserver eine neue Kassiererma\u00dfnahme namens","inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/rmarketingdigital.com\/en\/dev\/pixel-perfect-rendering-with-devicepixelcontentbox\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/rmarketingdigital.com\/en\/dev\/pixel-perfect-rendering-with-devicepixelcontentbox\/#primaryimage","url":"https:\/\/rmarketingdigital.com\/wp-content\/uploads\/2020\/09\/pixels-3418453.jpg","contentUrl":"https:\/\/rmarketingdigital.com\/wp-content\/uploads\/2020\/09\/pixels-3418453.jpg","width":1200,"height":360,"caption":"pixels-3418453-1385843-jpg"},{"@type":"WebSite","@id":"https:\/\/rmarketingdigital.com\/#website","url":"https:\/\/rmarketingdigital.com\/","name":"R Digitales Marketing","description":"SEO Agentur | Werbung f\u00fcr soziale Netzwerke | Community Management","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/rmarketingdigital.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Person","@id":"https:\/\/rmarketingdigital.com\/#\/schema\/person\/7c0d9782b2977b840b3740f00c69a73e","name":"R Digitales Marketing","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/c5599c203e0120b8ccbff4666af86f35f9b3dcad468a8bc6295313a3964a80be?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/c5599c203e0120b8ccbff4666af86f35f9b3dcad468a8bc6295313a3964a80be?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c5599c203e0120b8ccbff4666af86f35f9b3dcad468a8bc6295313a3964a80be?s=96&d=mm&r=g","caption":"R Marketing Digital"}}]}},"_links":{"self":[{"href":"https:\/\/rmarketingdigital.com\/de\/wp-json\/wp\/v2\/posts\/83165","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rmarketingdigital.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rmarketingdigital.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rmarketingdigital.com\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rmarketingdigital.com\/de\/wp-json\/wp\/v2\/comments?post=83165"}],"version-history":[{"count":0,"href":"https:\/\/rmarketingdigital.com\/de\/wp-json\/wp\/v2\/posts\/83165\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rmarketingdigital.com\/de\/wp-json\/wp\/v2\/media\/83166"}],"wp:attachment":[{"href":"https:\/\/rmarketingdigital.com\/de\/wp-json\/wp\/v2\/media?parent=83165"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rmarketingdigital.com\/de\/wp-json\/wp\/v2\/categories?post=83165"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rmarketingdigital.com\/de\/wp-json\/wp\/v2\/tags?post=83165"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}