css3 animación de transición en carga?

195

¿Es posible usar la animación de transición CSS3 en la carga de la página sin usar Javascript?

Esto es algo de lo que quiero, pero en la carga de la página:

http://rilwis.googlecode.com/svn/trunk/demo/image-slider.html

Lo que encontré hasta ahora

  • CSS3 transición-retraso , una forma de retrasar los efectos en los elementos. Solo funciona en vuelo estacionario.
  • CSS3 Keyframe , funciona con carga pero es extremadamente lento. No es útil por eso.
  • La transición CSS3 es lo suficientemente rápida pero no se anima en la carga de la página.
Jens Törnell
fuente
@blesh: casi cualquier cosa - vea, por ejemplo, mysociety.org/2011/08/11/mobile-operators-breaking-content y robertnyman.com/2006/04/25/…
NickFitz
2
Los fotogramas clave lograrán esto y proporcionarán el mejor respaldo cuando las animaciones CSS3 no sean compatibles. ¿Por qué crees que son demasiado lentos?
zachleat
¡Hola! ¡El enlace ahora está roto y no sé a dónde debía ir, así que alguien puede arreglarlo, por favor!
Linux4Life531

Respuestas:

459

Usted puede ejecutar un CSS animación al cargar la página sin usar ningún JavaScript; solo tienes que usar CSS3 Keyframes .

Veamos un ejemplo...

Aquí hay una demostración de un menú de navegación deslizándose en su lugar usando solo CSS3 :

@keyframes slideInFromLeft {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(0);
  }
}

header {  
  /* This section calls the slideInFromLeft animation we defined above */
  animation: 1s ease-out 0s 1 slideInFromLeft;
  
  background: #333;
  padding: 30px;
}

/* Added for aesthetics */ body {margin: 0;font-family: "Segoe UI", Arial, Helvetica, Sans Serif;} a {text-decoration: none; display: inline-block; margin-right: 10px; color:#fff;}
<header>
  <a href="#">Home</a>
  <a href="#">About</a>
  <a href="#">Products</a>
  <a href="#">Contact</a>
</header>

Descomponerlo...

Las partes importantes aquí son la animación de fotogramas clave que llamamos slideInFromLeft...

@keyframes slideInFromLeft {
    0% {
        transform: translateX(-100%);
    }
    100% {
        transform: translateX(0);
    }
}

... que básicamente dice "al principio, el encabezado estará fuera del borde izquierdo de la pantalla en todo su ancho y al final estará en su lugar".

La segunda parte es llamar a esa slideInFromLeftanimación:

animation: 1s ease-out 0s 1 slideInFromLeft;

Arriba está la versión abreviada, pero aquí está la versión detallada para mayor claridad:

animation-duration: 1s; /* the duration of the animation */
animation-timing-function: ease-out; /* how the animation will behave */
animation-delay: 0s; /* how long to delay the animation from starting */
animation-iteration-count: 1; /* how many times the animation will play */
animation-name: slideInFromLeft; /* the name of the animation we defined above */

Puede hacer todo tipo de cosas interesantes, como deslizar el contenido o llamar la atención sobre las áreas.

Esto es lo que tiene que decir el W3C.

Chris Spittles
fuente
20
¿Qué hace que esto se ejecute al cargar la página, y no antes?
Rolf
2
Solo para responder la pregunta anterior, parece que, por defecto, la animación comienza 0s después de que se aplica, sin demora. Hay una propiedad adicional, animación-retraso, que se puede configurar para controlar esto. Ver: w3.org/TR/css3-animations/#animation-delay-property
Michael Davis
2
Para garantizar que la animación comience después de que se cargue el documento, coloque el código de animación en una hoja de estilo debajo del elemento del cuerpo o la etiqueta de estilo en la parte inferior del elemento del cuerpo.
TaylorMac
@SuzanneEdelmanCreoconcept, que yo sepa, IE9 no admite la propiedad de transición. Sus opciones serían JS o degradación elegante.
Chris Spittles
1
Excelente respuesta, me ha ayudado en 2019!
Gosi
28

Se necesita muy poco Javascript:

window.onload = function() {
    document.body.className += " loaded";
}

Ahora el CSS:

.fadein {
    opacity: 0;
    -moz-transition: opacity 1.5s;
    -webkit-transition: opacity 1.5s;
    -o-transition: opacity 1.5s;
    transition: opacity 1.5s;
}

body.loaded .fadein {
    opacity: 1;
}

Sé que la pregunta decía "sin Javascript", pero creo que vale la pena señalar que hay una solución fácil que involucra una línea de Javascript.

Incluso podría ser Javascript en línea, algo así:

<body onload="document.body.className += ' loaded';" class="fadein">

Eso es todo el JavaScript que se necesita.

Rolf
fuente
2
Una pequeña solución: <body onload = "document.body.setAttribute ('class', 'loaded')">
Ivan
1
Si no necesita esperar el evento onLoad de la página, inserte este código antes de la etiqueta </body>: <script type = "text / javascript"> document.body.setAttribute ('class', 'loaded'); </script>
Ivan
77
Para evitar la anulación de las bodyclases existentes , utilice:document.body.classList.add('loaded)
Vyacheslav Cotruta
1
Descubrí document.body.className += " loaded";que es un poco menos detallado para agregar la loadedclase a las clases existentes.
Pim Schaaf
1
@PimSchaaf Gracias por su sugerencia, tiene mucho sentido. Lo editaré ahora. Hoy en día también puedes usar classList, que es un poco más elegante (pero menos compatible).
Rolf
20

Creo que he encontrado una especie de solución alternativa para la pregunta de OP: en lugar de una transición que comienza 'on.load' de la página, descubrí que el uso de una animación para una opacidad se desvaneció tuvo el mismo efecto (estaba buscando lo mismo que OP).

Entonces, quería que el texto del cuerpo se desvaneciera del blanco (igual que el fondo del sitio) al color del texto negro en la carga de la página, y solo he estado codificando desde el lunes, así que estaba buscando un código de estilo de 'carga', pero aún no conozco JS, así que aquí está mi código que funcionó bien para mí.

#main p {
  animation: fadein 2s;
}
@keyframes fadein {
  from { opacity: 0}
  to   { opacity: 1}
}

Y por alguna razón, esto no funciona .classsolo #idpara los (al menos no en los míos)

Espero que esto ayude, ya que sé que este sitio me ayuda mucho.

Lee John
fuente
6

Bueno, este es complicado.

La respuesta es "no realmente".

CSS no es una capa funcional. No tiene conciencia de lo que sucede o cuándo. Se usa simplemente para agregar una capa de presentación a diferentes "banderas" (clases, id, estados).

De manera predeterminada, CSS / DOM no proporciona ningún tipo de estado "en carga" para que CSS lo use. Si quisieras / pudieras usar JavaScript, asignarías una clase bodyo algo para activar CSS.

Dicho esto, puedes crear un truco para eso. Daré un ejemplo aquí, pero puede o no ser aplicable a su situación.

Estamos operando bajo el supuesto de que "cerrar" es "suficientemente bueno":

<html>
<head>
<!-- Reference your CSS here... -->
</head>
<body>
    <!-- A whole bunch of HTML here... -->
    <div class="onLoad">OMG, I've loaded !</div>
</body>
</html>

Aquí hay un extracto de nuestra hoja de estilo CSS:

.onLoad
{
    -webkit-animation:bounceIn 2s;
}

También asumimos que los navegadores modernos se procesan progresivamente, por lo que nuestro último elemento se procesará en último lugar y, por lo tanto, este CSS se activará en último lugar.

astuto
fuente
1

Similar a la solución de @ Rolf, pero omita la referencia a funciones externas o jugar con clase. Si la opacidad se mantendrá fija en 1 una vez cargada, simplemente use la secuencia de comandos en línea para cambiar directamente la opacidad a través del estilo. Por ejemplo

<body class="fadein" onload="this.style.opacity=1">

donde CSS sytle "fadein" se define por @ Rolf, definiendo la transición y configurando la opacidad al estado inicial (es decir, 0)

el único inconveniente es que esto no funciona con elementos SPAN o DIV, ya que no tienen un evento onload que funcione

usuario3907296
fuente
1

Comience con el desplazamiento del cuerpo de lo que comenzará cuando el mouse se mueva por primera vez en la pantalla, que es principalmente dentro de un segundo después de la llegada, el problema aquí es que se revertirá cuando esté fuera de la pantalla.

html:hover #animateelementid, body:hover #animateelementid {rotate ....}

eso es lo mejor que se me ocurre: http://jsfiddle.net/faVLX/

pantalla completa: http://jsfiddle.net/faVLX/embedded/result/

Editar vea los comentarios a continuación:
Esto no funcionará en ningún dispositivo con pantalla táctil porque no hay desplazamiento, por lo que el usuario no verá el contenido a menos que lo toque. - Rich Bradshaw

código de barba
fuente
Sí, lo descubrí yo mismo. Es una buena solución si nada más funciona. Un voto por eso.
Jens Törnell
13
Esta es una idea terrible: en cualquier dispositivo con pantalla táctil no hay desplazamiento, por lo que el usuario no verá el contenido a menos que lo toque.
Rich Bradshaw
1

CSS solo con un retraso de 3s

Algunos puntos para tomar aquí:

  • múltiples animaciones en una llamada
  • creamos una animación de espera que solo retrasa la real (la segunda en nuestro caso).

Código:

header {
    animation: 3s ease-out 0s 1 wait, 0.21s ease-out 3s 1 slideInFromBottom;
}

@keyframes wait {
    from { transform: translateY(20px); }
    to { transform: translateY(20px); }
}

@keyframes slideInFromBottom {
  from { transform: translateY(20px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}
Claudiu
fuente
0

Ok, he logrado lograr una animación cuando la página se carga usando solo transiciones CSS (¡más o menos!):

He creado 2 hojas de estilo CSS: la primera es cómo quiero que el html tenga un estilo antes de la animación ... y la segunda es cómo quiero que se vea la página después de que se haya llevado a cabo la animación.

No entiendo completamente cómo he logrado esto, pero solo funciona cuando los dos archivos css (ambos en el encabezado de mi documento) están separados por algún javascript de la siguiente manera.

He probado esto con Firefox, safari y opera. A veces la animación funciona, a veces salta directamente al segundo archivo CSS y a veces la página parece estar cargándose pero no se muestra nada (¿tal vez soy solo yo?)

<link media="screen,projection" type="text/css" href="first-css-file.css"  rel="stylesheet" />

<script language="javascript" type="text/javascript" src="../js/jQuery JavaScript Library v1.3.2.js"></script>

<script type='text/javascript'>
$(document).ready(function(){

// iOS Hover Event Class Fix
if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) ||
(navigator.userAgent.match(/iPad/i))) {
$(".container .menu-text").click(function(){  // Update class to point at the head of the list
});
}
});
</script>

<link media="screen,projection" type="text/css" href="second-css-file.css"  rel="stylesheet" />

Aquí hay un enlace a mi sitio web de trabajo en progreso: http://www.hankins-design.co.uk/beta2/test/index.html

Tal vez me equivoque, pero pensé que los navegadores que no admiten transiciones CSS no deberían tener ningún problema, ya que deberían saltar directamente al segundo archivo CSS sin demora ni duración.

Estoy interesado en conocer las opiniones sobre qué tan amigable es este método para los motores de búsqueda. Con mi sombrero negro puesto, supongo que podría llenar una página con palabras clave y aplicar un retraso de 9999 en su opacidad.

Me interesaría saber cómo manejan los motores de búsqueda el atributo de retraso de transición y si, utilizando el método anterior, incluso verían los enlaces y la información en la página.

Más importante aún, ¡me gustaría saber por qué esto no es consistente cada vez que se carga la página y cómo puedo rectificar esto!

Espero que esto pueda generar algunos puntos de vista y opiniones si nada más!

Michael Walkling
fuente
0

Si alguien más tuvo problemas para hacer dos transiciones a la vez, esto es lo que hice. Necesitaba que el texto viniera de arriba a abajo en la carga de la página.

HTML

<body class="existing-class-name" onload="document.body.classList.add('loaded')">

HTML

<div class="image-wrapper">
    <img src="db-image.jpg" alt="db-image-name">
    <span class="text-over-image">DB text</span>
</div>

CSS

.text-over-image {
    position: absolute;
    background-color: rgba(110, 186, 115, 0.8);
    color: #eee;
    left: 0;
    width: 100%;
    padding: 10px;
    opacity: 0;
    bottom: 100%;
    -webkit-transition: opacity 2s, bottom 2s;
    -moz-transition: opacity 2s, bottom 2s;
    -o-transition: opacity 2s, bottom 2s;
    transition: opacity 2s, bottom 2s;
}

body.loaded .text-over-image {
    bottom: 0;
    opacity: 1;
}

No sé por qué seguí tratando de usar 2 declaraciones de transición en 1 selector y (no realmente) pensando que usaría ambas.

s3c
fuente
0

Solución aún más simple (aún con [una línea en línea] javascript):

Use esto como la etiqueta del cuerpo: tenga en cuenta que body.o this.no funcionó para mí. Solo el largo; querySelectorpermitir el uso de classList.remove(Linux Chromium)

<body class="onload" onload="document.querySelector('body').classList.remove('onload')">

y agregue esta línea encima de sus otras reglas CSS.

body.onload *{ transform: none !important; }

Tenga en cuenta que esto puede aplicarse a la opacidad (como lo solicitó OP [otros pósters]) simplemente usando la opacidad como desencadenante de transición. (incluso podría funcionar en cualquier otra regla css de la misma manera y puede usar múltiples clases para un retraso explícito entre los disparos)

La lógica es la misma. No imponga ninguna transformación (con :none !importanttodos los elementos secundarios de body.onloady una vez que se cargue el documento, elimine la clase para activar todas las transiciones en todos los elementos como se especifica en su CSS.

PRIMERA RESPUESTA A CONTINUACIÓN (VER EDITAR ARRIBA PARA RESPUESTA MÁS CORTA)

Aquí hay una solución inversa:

  1. Realice su diseño html y configure el css de acuerdo con su resultado final (con toda la transformación que desee).
  2. Establezca la propiedad de transición a su gusto.
  3. agregue una clase (por ejemplo: waitload) a los elementos que desea transformar DESPUÉS de la carga. La palabra clave CSS ! Importante es la palabra clave aquí.
  4. Una vez que se carga el documento, use JS para eliminar la clase de los elementos para iniciar la transformación (y eliminar la transición: ninguna anulación).

Funciona con transición múltiple en múltiples elementos. No probé la compatibilidad entre navegadores.

#rotated{
    transform : rotate(90deg) /* any other transformation */;
    transition  3s;
}
#translated{
    transform : translate(90px) /* any other transformation */;
    transition  3s;
}
.waitload{
    transform: none !important;
}
<div id='rotated' class='waitload'>
    rotate after load
</div>
<div id='translated' class='waitload'>
    trasnlate after load
</div>
<script type="text/javascript">
     // or body onload ?
    [...document.querySelectorAll('.waitload')]
        .map(e => e.classList.remove('waitload'));

</script>
Louis Loudog Trottier
fuente
-2

En realidad no, ya que el CSS se aplica lo antes posible, pero es posible que los elementos aún no se hayan dibujado. Podrías adivinar un retraso de 1 o 2 segundos, pero esto no se verá bien para la mayoría de las personas, dependiendo de la velocidad de su internet.

Además, si desea desvanecer algo, por ejemplo, requeriría CSS que oculta el contenido que se entregará. Si el usuario no tiene transiciones CSS3, nunca lo verán.

Recomiendo usar jQuery (para facilitar su uso + es posible que desee agregar animación para otros UA) y algunos JS como este:

$(document).ready(function() {
    $('#id_to_fade_in')
        .css({"opacity":0})   // Set to 0 as soon as possible – may result in flicker, but it's not hidden for users with no JS (Googlebot for instance!)
        .delay(200)           // Wait for a bit so the user notices it fade in
        .css({"opacity":1});  // Fade it back in. Swap css for animate in legacy browsers if required.
});

Junto con las transiciones agregadas en el CSS. Esto tiene la ventaja de permitir fácilmente el uso de animar en lugar del segundo CSS en navegadores heredados si es necesario.

Rich Bradshaw
fuente
17
¿Por qué se aceptó esta respuesta? Realmente no hace nada de lo que se hizo la pregunta. Simplemente (y muy rápidamente, a veces de manera imperceptible) inicia el elemento invisible, espera una pequeña fracción de segundo (200 ms) y luego lo vuelve a ver de forma instantánea. Eso no es un desvanecimiento, lo último que revisé.
VoidKing
Incluiría una transición CSS en el #id_to_fade in, aunque estoy de acuerdo, eso no está tan claro en la respuesta.
Rich Bradshaw el
como en, agregue otro .css ({transición: 'opacity 2s'}) a la llamada jQuery? O solo en tu css? Tengo la sensación de que voy a sentir que esta es una pregunta estúpida ...
VoidKing
3
Está bien, debería haber puesto una demostración realmente. En CSS, #id_to_fade_in { -webkit-transition:opacity 0.5s ease-in-out; }+ -o-, -moz-prefijos también.
Rich Bradshaw
2
Esta no debería ser la respuesta aceptada, el uso de fotogramas clave es el camino a seguir.
Eduardo Naveda