¿Cómo detengo el destello de contenido sin estilo (FOUC) en una página web?
¿Cómo detengo el destello de contenido sin estilo (FOUC) en una página web?
Respuestas:
Lo que he hecho para evitar FOUC es:
Establezca la sección del cuerpo como: <body style="visibility: hidden;" onload="js_Load()">
Escribe una js_Load()
función de JavaScript:document.body.style.visibility='visible';
Con este enfoque, el cuerpo de mi página web se mantiene oculto hasta que se cargan la página completa y los archivos CSS. Una vez que todo está cargado, el evento onload hace que el cuerpo sea visible. Por lo tanto, el navegador web permanece vacío hasta el momento en que todo aparece en la pantalla.
Es una solución simple pero hasta ahora está funcionando.
<noscript><style>body { visibility: visible; }</style></noscript>
al final para que el sitio funcione con JS deshabilitado también.
El problema de usar un estilo CSS para ocultar inicialmente algunos elementos de la página, y luego usar javascript para cambiar el estilo de nuevo a visible después de cargar la página, es que las personas que no tienen Javascript habilitado nunca podrán ver esos elementos. Entonces es una solución que no se degrada con gracia.
Por lo tanto, una mejor manera es usar javascript tanto para ocultar inicialmente como para volver a mostrar esos elementos después de cargar la página. Usando jQuery, podríamos tener la tentación de hacer algo como esto:
$(document).ready(function() {
$('body').hide();
$(window).on('load', function() {
$('body').show();
});
});
Sin embargo, si su página es muy grande con muchos elementos, entonces este código no se aplicará lo suficientemente pronto (el cuerpo del documento no estará listo lo suficientemente pronto) y es posible que todavía vea un FOUC. Sin embargo, hay un elemento que PODEMOS ocultar tan pronto como se encuentre el script en el encabezado, incluso antes de que el documento esté listo: la etiqueta HTML. Entonces podríamos hacer algo como esto:
<html>
<head>
<!-- Other stuff like title and meta tags go here -->
<style type="text/css">
.hidden {display:none;}
</style>
<script type="text/javascript" src="/scripts/jquery.js"></script>
<script type="text/javascript">
$('html').addClass('hidden');
$(document).ready(function() { // EDIT: From Adam Zerner's comment below: Rather use load: $(window).on('load', function () {...});
$('html').show(); // EDIT: Can also use $('html').removeClass('hidden');
});
</script>
</head>
<body>
<!-- Body Content -->
</body>
</html>
Tenga en cuenta que el método jQuery addClass () se llama * fuera * del método .ready () (o mejor, .on ('load')).
$('html').show()'
con $('html').removeClass('hidden');
. Esto deja más claro que la función listo deshace el archivo addClass
.
removeClass
(como sugiero) en lugar de show
(como en la respuesta original); de lo contrario, el html NUNCA se mostrará. Creo que show () de jQuery ahora busca y restaura explícitamente cualquier estado de visualización del estilo css, para evitar interferir con el estilo. Por lo tanto, es necesario eliminar la clase 'oculta'.
<style>html { display: none; }</style>
en el <head>
y luego sus estilos reales justo antes </body>
?
Una solución solo de CSS:
<html>
<head>
<style>
html {
display: none;
}
</style>
...
</head>
<body>
...
<link rel="stylesheet" href="app.css"> <!-- should set html { display: block; } -->
</body>
</html>
A medida que el navegador analiza el archivo HTML:
<html>
.La ventaja de esto sobre una solución que usa JavaScript es que funcionará para los usuarios incluso si tienen JavaScript desactivado.
Nota: se le permite poner <link>
dentro de <body>
. Sin embargo, lo veo como una desventaja, porque viola la práctica común. Sería bueno si hubiera un defer
atributo para <link>
como hay para <script>
, porque eso nos permitiría ponerlo en el <head>
y aún así lograr nuestro objetivo.
display: none
también ocultará la imagen de fondo o el color. Dado que mi sitio web tiene un tema oscuro, parpadeará en blanco. Usar visibility: hidden
fue mejor para mi caso.
<head>
lugar de <body>
. (Aunque supongo que si tuviera una página muy larga, el navegador podría comenzar a mostrar la página antes de que se haya cargado el final de la página. Sin embargo, ese es mi comportamiento preferido ya que mi sitio carga tablas grandes desde una base de datos). ¡Aprobado por una solución simple que no requiere JavaScript!
Este es el que me ha funcionado y no requiere javascript y funciona muy bien para páginas con muchos elementos y mucho css:
Primero, agregue una <STYLE>
configuración dedicada para la <HTML>
etiqueta con visibilidad 'oculta' y opacidad como '0' en la parte superior de su HTML, por ejemplo, al principio del <HEAD>
elemento, por ejemplo, en la parte superior de su HTML agregar :
<!doctype html>
<html>
<head>
<style>html{visibility: hidden;opacity:0;}</style>
Luego, al final de su último archivo de hoja de estilo .css , configure los estilos de visibilidad y opacidad en 'visible' y '1', respectivamente:
html {
visibility: visible;
opacity: 1;
}
Si ya tiene un bloque de estilo existente para la etiqueta 'html', mueva todo el estilo 'html' al final del último archivo .css y agregue las etiquetas 'visibilidad' y 'opacidad' como se describe arriba.
https://gist.github.com/electrotype/7960ddcc44bc4aea07a35603d1c41cb0
html{display:none;}
en head
y html{display:block;}
en la hoja de estilo para conquistar completamente FOUC con navegadores basados en Chromium. (No he tenido problemas con un fondo oscuro en el body
.)
Una solución que no depende de jQuery, que funcionará en todos los navegadores actuales y no hará nada en los navegadores antiguos, incluye lo siguiente en su etiqueta principal:
<head>
...
<style type="text/css">
.fouc-fix { display:none; }
</style>
<script type="text/javascript">
try {
var elm=document.getElementsByTagName("html")[0];
var old=elm.class || "";
elm.class=old+" fouc-fix";
document.addEventListener("DOMContentLoaded",function(event) {
elm.class=old;
});
}
catch(thr) {
}
</script>
</head>
Gracias a @justastudent, intenté configurarlo elm.style.display="none";
y parece funcionar como se desea, al menos en el Firefox Quantum actual. Así que aquí hay una solución más compacta, siendo, hasta ahora, la cosa más simple que he encontrado que funciona.
<script type="text/javascript">
var elm=document.getElementsByTagName("html")[0];
elm.style.display="none";
document.addEventListener("DOMContentLoaded",function(event) { elm.style.display="block"; });
</script>
classList
API.
elm.style.display = 'none';
y luego deshacer eso elm.style.removeProperty('display');
?
Otra solución rápida que también funciona en Firefox Quantum es una <script>
etiqueta vacía en <head>
. Sin embargo, esto penaliza sus conocimientos sobre la velocidad de la página y el tiempo de carga general.
Tuve un 100% de éxito con él. Creo que también es la razón principal por la que las soluciones anteriores con otros JS están en proceso.
<script type="text/javascript">
</script>
Nadie ha hablado de CSS @import
Ese fue el problema para mí, estaba cargando dos hojas de estilo adicionales directamente en mi archivo css con @import
Solución simple: reemplace todos los @import
enlaces con<link />
@import
sea sincrónico.
Se me ocurrió una forma que no requiere ningún cambio de código real, ¡woohoo! Mi problema estaba relacionado con la importación de varios archivos css DESPUÉS de algunos archivos javascript.
Para resolver el problema, simplemente moví mis enlaces CSS para que estuvieran por encima de mis importaciones de JavaScript. Esto permitió que todo mi CSS se importara y estuviera listo para funcionar lo antes posible, de modo que cuando el HTML aparezca en la pantalla, incluso si el JS no está listo, la página tendrá el formato adecuado.
Aquí está mi código .. espero que resuelva su problema
set <body style="opacity:0;">
<script>
$(document).ready(function() {
$("body").css('opacity', 1);
});
</script>
<body style="opacity:0;">
La mejor solución que encontré hasta ahora es así:
Agregue todos los estilos de su encabezado a un <style/>
etiqueta en<head/>
en la parte superior de la etiqueta de estilo agregar .not-visible-first{visibility: hidden}
+ otro estilo de encabezado
Agregue css a través de JS al final del cuerpo
document.getElementsByTagName("head")[0].insertAdjacentHTML("beforeend","<link rel=\"stylesheet\" href=\"/css/main.min.css?v=1.2.4338\" />");
Y recuerda agregar .not-visible-first{visibility: visible}
al final demain.min.css
Esta opción creará una mejor experiencia de usuario
Podrías probar esto con vainilla
function js_method(){
//todos
var elementDiv = document.getElementById("main");
elementDiv.style.display ="block";
}
<body onload="js_method()" id="main" style="display:none">
//todos
<h2>Hello</h2>
</body>
La forma más sencilla que conozco es ocultar la etiqueta html y luego, en la parte inferior de su archivo javascript, desvanecer la etiqueta html.
HTML
<html style="display:none;">
...
</html>
Javascript
/*
* FOUC Fix - Flash of Unstyled Content
* By default, the <html> tag is hidden to prevent the flash of unstyled content.
* This simple fadeIn() function will allow the page to gracefully fade in once
* all assets are loaded. This line of code must remain at the bottom of the js
* assets.
*/
$( 'html' ).fadeIn();
Fuente: https://gist.github.com/marchershey/139db0e8fd6f03a83578698409d333ce
fadeIn()
es un método jQuery, no JavaScript nativo.