Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

654
Views
¿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 answers
Answer question

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 Report

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!