Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

658
Vistas
¿Por qué la aplicación de un filtro CSS en el padre rompe el posicionamiento del niño?

Así que tengo esta "animación" de pantalla de título que tiene el título centrado en una página de pantalla completa y cuando se desplaza hacia abajo se vuelve más pequeño y permanece en la parte superior de la página. Aquí hay un ejemplo de trabajo con el comportamiento esperado, del cual eliminé todo el código innecesario para hacerlo mínimo:

 $(window).scroll( () => { "use strict"; let windowH = $(window).height(); let windowS = $(window).scrollTop(); let header = $("#header").height(); if (windowS < windowH-header) { $("#title").css("transform", "scale("+(2-(windowS/($(document).outerHeight()-windowH))*2.7)+")"); $("#header").css("transform", "translateY(0)"); $("#inside, #content").css({ "position": "static", "margin-top": 0 }); } else { $("#inside").css({ "position": "fixed", "margin-top": -windowH+header }); $("#content").css("margin-top", windowH); } $("#header").css("position", windowS > (windowH-header)/2 ? "fixed" :"static"); });
 .fixed { position: fixed!important; } .wrapper { width: 100%; text-align: center; } .wrapper:before { display: table; content: " "; } .wrapper:after { clear: both; } #inside { width: 100%; height: 100vh; background-color: lightcoral; display: flex; align-items: center; justify-content: center; } #header { height: 90px; top: 0; position: sticky; display: flex; align-items: center; justify-content: center; transition: all 0.5s; } #title { width: 100%; color: #fff; transform: scale(2); } #content { height: 1000px; background-color: lightblue; }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body> <div class="wrapper"> <div id="inside"> <div id="header"> <h1 id="title">Title</h1> </div> </div> <div id="content"></div> </body>

El siguiente es exactamente el mismo fragmento pero con una adición: apliqué un filtro, que es, en lo que a mí respecta, puramente cosmético: filter: brightness(1.3); .

Como puede ver a continuación, cuando se desplaza a la mitad de la "animación", el título simplemente desaparece. Cuando inspeccionas el elemento, todavía tiene todas sus propiedades, pero de alguna manera se ha ido. Esto es lo mismo en Firefox y Chrome y no tengo idea de por qué. Apreciaría mucho si alguien pudiera publicar un fragmento que funcione con el filtro aplicado y explicar por qué no funcionó antes.

 $(window).scroll( () => { "use strict"; let windowH = $(window).height(); let windowS = $(window).scrollTop(); let header = $("#header").height(); if (windowS < windowH-header) { $("#title").css("transform", "scale("+(2-(windowS/($(document).outerHeight()-windowH))*2.7)+")"); $("#header").css("transform", "translateY(0)"); $("#inside, #content").css({ "position": "static", "margin-top": 0 }); } else { $("#inside").css({ "position": "fixed", "margin-top": -windowH+header }); $("#content").css("margin-top", windowH); } $("#header").css("position", windowS > (windowH-header)/2 ? "fixed" :"static"); });
 .fixed { position: fixed!important; } .wrapper { width: 100%; text-align: center; } .wrapper:before { display: table; content: " "; } .wrapper:after { clear: both; } #inside { width: 100%; height: 100vh; background-color: lightcoral; filter: brightness(1.3); /*<<<<<<<<<<<<<<<<*/ display: flex; align-items: center; justify-content: center; } #header { height: 90px; top: 0; position: sticky; display: flex; align-items: center; justify-content: center; transition: all 0.5s; } #title { width: 100%; color: #fff; transform: scale(2); } #content { height: 1000px; background-color: lightblue; }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body> <div class="wrapper"> <div id="inside"> <div id="header"> <h1 id="title">Title</h1> </div> </div> <div id="content"></div> </body>

over 4 years ago · Santiago Trujillo
4 Respuestas
Responde la pregunta

0

Si nos remitimos a la especificación podemos leer:

Un valor distinto de ninguno para la propiedad de filtro da como resultado la creación de un bloque contenedor para descendientes absolutos y de posición fija, a menos que el elemento al que se aplica sea un elemento raíz del documento en el contexto de exploración actual. La lista de funciones se aplica en el orden indicado.

Esto significa que su elemento position:fixed se colocará en relación con el contenedor filtrado y no más con la ventana gráfica. En otras palabras, todavía está arreglado pero dentro de su nuevo bloque contenedor (el contenedor filtrado)

Aquí hay una versión simplificada para ilustrar el problema:

 .container { display: inline-block; width: 200px; height: 200vh; border: 1px solid; } .container>div { position: fixed; width: 100px; height: 100px; background: red; color: #fff; }
 <div class="container"> <div>I am fixed on scroll</div> </div> <div class="container" style="filter:grayscale(1);"> <div>I move with the scroll</div> </div>

Para solucionar el problema, intente mover el filtro al elemento fijo en lugar de su contenedor:

 .container { display: inline-block; width: 200px; height: 200vh; border: 1px solid; } .container>div { position: fixed; width: 100px; height: 100px; background: red; color: #fff; filter: grayscale(1); }
 <div class="container"> <div>I am fixed on scroll</div> </div>


Aquí hay una lista no exhaustiva 1 de las propiedades que dan como resultado la creación de un bloque contenedor para descendientes absolutos y de posición fija

  • filter
  • transform referencia
  • referencia backdrop-filter
  • referencia de perspective
  • contain referencia
  • referencia transform-style
  • referencia content-visibility
  • will-change cuando se use con uno de los valores anteriores

Si cualquier valor no inicial de una propiedad hace que el elemento genere un bloque contenedor para elementos con posiciones absolutas, especificar esa propiedad en will-change debe hacer que el elemento genere un bloque contenedor para elementos con posiciones absolutas. árbitro


1 : Intentaré mantener esta lista actualizada.

over 4 years ago · Santiago Trujillo Denunciar

0

Para evitar un mantenimiento intensivo y una implementación diferente para cada navegador, puede utilizar una función de recorrido de árbol recursivo que marca los nodos de posición 'fijos' y luego aplica el filtro necesario correctamente sin destruir las posiciones.

Utilicé este código para aplicar la propiedad 'filter invert' globalmente, sin codificarlo en elementos principales específicos.

over 4 years ago · Santiago Trujillo Denunciar

0

Puedes hacer que suceda usando before . en lugar de asignar el filter: brightness(1.3); al elemento secundario directamente. asigne color y filtro al before de este elemento secundario. entonces tu código debería ser así:

 #inside:before{ filter: brightness(1.3); content: ""; background-color: lightcoral; top: 0; left: 0; width: 100%; height: 100%; position: absolute; }

Esto arreglará el problema.

También debe editar parte de su código para que esto funcione completamente:

 #inside{ position: relative; }

Haga que la posición principal sea relativa para asegurarse de que before se ajuste dentro de su principal.

Esta solución también funciona con otros filtros como backdrop-filter .

over 4 years ago · Santiago Trujillo Denunciar

0

Si desea desenfocar o escalar en gris toda la página, excepto un elemento, simplemente use backdrop-filter lugar del filter . Al momento de escribir, Firefox solo necesita enviarlo de manera predeterminada.

No funciona:

 <!DOCTYPE html><html><head> <style> .overlay { position:fixed; right:10%; top:10%; bottom:10%; left:10%; background-color:red; z-index:2; } .overlay ~ * { filter: grayscale(50%) blur(5px); } </style> </head> <body> <div class="overlay">I am not blurred</div> <!-- position test --> <div style="margin-top:100px;float:right;"> <div style="background-color:red;position:fixed;top:0;right:0;width:100px;height:100px;"></div> </div> </body> </html>

Trabajando:

 <!DOCTYPE html><html><head> <style> .overlay { position:fixed; right:10%; top:10%; bottom:10%; left:10%; background-color:red; z-index:2; } body:after { content:""; position:fixed; z-index: 1; top:0; left:0; width:100%; height:100%; backdrop-filter: grayscale(50%) blur(5px); } </style> </head> <body> <div class="overlay">I am not blurred</div> <!-- position test --> <div style="margin-top:100px;float:right;"> <div style="background-color:red;position:fixed;top:0;right:0;width:100px;height:100px;"></div> </div> </body> </html>

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda