Tag Archives: CSS3

Sequential Letter Animations using CSS3 & jQuery

I think that my recent exploration of individual letter hover effects was always going to lead me down this path. Once I wrote the JS for sequentially applying a class to individual letters in a string with a flexible timer structure, the ideas just kept coming. It all starts with this:

See the Pen Sequential Letter Animation Starter Pen by Braad Martin (@BraadMartin) on CodePen.0

With that JS, designing the effect is as simple as setting this line of CSS:

.container span.active {
  /* Do something crazy */
}

Then you can change the timing of the effect simply by changing the variables in the JS:

duration = 400; // Set duration of the effect here
speed = 100; // Set animation speed through the letters here
infiniteLoop = false // Set whether animation should keep on triggering

There is a lot of potential here. I'm only starting to scratch the surface:

Example 1 - Rotating Letters

See the Pen Sequential Letter Animations - Rotating Letters by Braad Martin (@BraadMartin) on CodePen.0

Example 2 - Leaning Letters

See the Pen Sequential Letter Animations - Leaning Letters by Braad Martin (@BraadMartin) on CodePen.0

Example 3 - 3D Letters

See the Pen Sequential Letter Animations - 3D Letters by Braad Martin (@BraadMartin) on CodePen.0

Example 4 - Inset Letters

See the Pen Sequential Letter Animations - Inset Letters by Braad Martin (@BraadMartin) on CodePen.0

Too much fun!

-Braad

Individual Letter Hover Effects using CSS3 & jQuery

I've been playing around with the idea of applying CSS3 transforms and other effects to individual letters in a string, and I wanted a flexible way to do this that didn't involve any special markup from the content author.

After testing some ideas I settled on writing a small jQuery plugin to handle the task of wrapping each letter of a string in its own span. I call the plugin Span Letters, and it looks like this:

( function( $ ) {

    // Example usage: jQuery( '.selector' ).spanLetters();

    $.fn.spanLetters = function() {

        // Loop through each element on which this function has been called
        this.each( function() {   
          
            // Make an array with each letter of the string as a value
            var words = $( this ).text().split( '' );

            // Loop through the letters and wrap each one in a span
            for ( i = 0; i in words; i++ ) {
                words[i] = '<span class="sl' + (i + 1) + ' span-letter">' + words[i] + '</span>'
            };

            // Join our array of span-wrapped letters back into a string
            var text = words.join( '' );

            // Replace the original string with the new string
            $( this ).html( text );
        })
    }
}( jQuery ));

This will wrap each letter in a span and give the span a unique sequential class that we can use to apply our individual letter styling. Of course we can also use something like span:nth-child() instead of using the sequential classes. We can bring this to life with some CSS like this:

.container {
  font-family: verdana;
  font-weight: bold;
  text-shadow: -1px 0 0px #FFADDA, 0 1px 0px #F99ACD, -2px 1px 0px #FFADDA, -1px 2px 0px #F99ACD, -3px 2px 0px #FFADDA, -2px 3px 0px #F99ACD, -4px 3px 0px #FFADDA, -3px 4px 0px #F99ACD, -5px 4px 0px #FFADDA, -4px 5px 0px #F99ACD, -6px 5px 0px #FFADDA, -5px 6px 15px #000000;
  text-transform: uppercase;
}

.container span {
  display: inline-block;
  transition: 0.8s;
}

.container .sl1 {
  color: red;
  transform: rotateX( 20deg ) rotateY( -20deg ) rotateZ( 10deg );
}

.container .sl2 {
  color: orange;
  transform: rotateX( 0deg ) rotateY( 0deg ) rotateZ( -15deg );
}

.container .sl3 {
  color: yellow;
  transform: rotateX( 0deg ) rotateY( 30deg ) rotateZ( 25deg );
}

.container .sl4 {
  color: green;
  transform: rotateX( 0deg ) rotateY( 5deg ) rotateZ( -5deg );
}

.container .sl5 {
  color: blue;
  transform: rotateX( 20deg ) rotateY( 0deg ) rotateZ( -35deg );
}

.container .sl6 {
  color: indigo;
  transform: rotateX( 10deg ) rotateY( 0deg ) rotateZ( 5deg );
}

.container .sl7 {
  color: violet;
  transform: rotateX( 0deg ) rotateY( 30deg ) rotateZ( 35deg );
}

.container .sl8 {
  color: white;
  transform: rotateX( -10deg ) rotateY( 0deg ) rotateZ( -15deg );
}

.container .sl9 {
  color: black;
  transform: rotateX( -10deg ) rotateY( 0deg ) rotateZ( 15deg );
}

.container:hover span {
  transform: rotateX( 0deg ) rotateY( 0deg ) rotateZ( 0deg );
  cursor: pointer;
}

To create this:

Transform

Hover/Tap to revert to normal

That's pretty neat, but how can we make this more functional? I like the idea of transitioning into or out of the effect when the user hovers over the text. Here are some examples:

Example 1 - 2D Spinning Letters

.container {
  font-family: verdana;
  font-weight: bold;
  text-shadow: -1px 0 0px #FFADDA, 0 1px 0px #F99ACD, -2px 1px 0px #FFADDA, -1px 2px 0px #F99ACD, -3px 2px 0px #FFADDA, -2px 3px 0px #F99ACD, -4px 3px 0px #FFADDA, -3px 4px 0px #F99ACD, -5px 4px 0px #FFADDA, -4px 5px 0px #F99ACD, -6px 5px 0px #FFADDA, -5px 6px 15px #000000;
  text-transform: uppercase;
  color: white;
}

.container span {
  display: inline-block;
  transition: 0.8s;
}

.container:hover span:nth-child(odd) {
  transform: rotateX( 0deg ) rotateY( 0deg ) rotateZ( 370deg );
  cursor: pointer;
}

.container:hover span:nth-child(even) {
  transform: rotateX( 0deg ) rotateY( 0deg ) rotateZ( -370deg );
  cursor: pointer;
}
Result:

Transform

Hover/Tap for effect

Example 2 - 3D Spinning Letters

.container {
  font-family: verdana;
  font-weight: bold;
  text-shadow: -1px 0 0px #FFADDA, 0 1px 0px #F99ACD, -2px 1px 0px #FFADDA, -1px 2px 0px #F99ACD, -3px 2px 0px #FFADDA, -2px 3px 0px #F99ACD, -4px 3px 0px #FFADDA, -3px 4px 0px #F99ACD, -5px 4px 0px #FFADDA, -4px 5px 0px #F99ACD, -6px 5px 0px #FFADDA, -5px 6px 15px #000000;
  text-transform: uppercase;
  color: white;
}

.container span {
  display: inline-block;
  transition: 1.5s;
}

.container:hover span:nth-child(odd) {
  transform: rotateX( 0deg ) rotateY( 370deg ) rotateZ( 370deg );
  cursor: pointer;
}

.container:hover span:nth-child(even) {
  transform: rotateX( -370deg ) rotateY( 0deg ) rotateZ( -370deg );
  cursor: pointer;
}
Result:

Transform

Hover/Tap for effect

Example 3 - The Gangster Lean

.container {
  font-family: verdana;
  font-weight: bold;
  text-transform: uppercase;
  color: #545454;
}

.container span {
  display: inline-block;
  transition: 1s;
}

.container:hover span {
  transform: skewX( -10deg ) translateX( 10px );
  cursor: pointer;
}
Result:

Transform

Hover/Tap for effect

Example 4 - Individual Letter Scaling

.container {
  font-family: verdana;
  font-weight: bold;
  text-shadow: -1px 0 0px #FFADDA, 0 1px 0px #F99ACD, -2px 1px 0px #FFADDA, -1px 2px 0px #F99ACD, -3px 2px 0px #FFADDA, -2px 3px 0px #F99ACD, -4px 3px 0px #FFADDA, -3px 4px 0px #F99ACD, -5px 4px 0px #FFADDA, -4px 5px 0px #F99ACD, -6px 5px 0px #FFADDA, -5px 6px 15px #000000;
  text-transform: uppercase;
  color: white;
}

.container span {
  display: inline-block;
  transition: 0.8s;
}

.container:hover span {
  cursor: pointer;
  position: relative;
}

.container:hover .sl1 {
  transform: scale(1.25);
  z-index: 4;
}

.container:hover .sl2 {
  transform: scale(1.15);
  z-index: 3;
}

.container:hover .sl3 {
  transform: scale(1.05);
  z-index: 2;
}

.container:hover .sl4 {
  transform: scale(0.95);
  z-index: 1;
}

.container:hover .sl5 {
  transform: scale(0.85);
  z-index: 0;
}

.container:hover .sl6 {
  transform: scale(0.95);
  z-index: 1;
}

.container:hover .sl7 {
  transform: scale(1.05);
  z-index: 2;
}

.container:hover .sl8 {
  transform: scale(1.15);
  z-index: 3;
}

.container:hover .sl9 {
  transform: scale(1.25);
  z-index: 4;
}
Result:

Transform

Hover/Tap for effect

Example 5 - Text-Shadow Animations

.container {
  font-family: verdana;
  font-weight: bold;
  text-transform: uppercase;
  color: rgba(210, 210, 210, 0.6);
  text-shadow: 1px 2px 6px #FFFFFF, 0 0 0 #000000;
}

.container span {
  transition: 0.3s;
  display: inline-block;
}

.container:hover span {
  cursor: pointer;
  color: rgba(200, 200, 200, 0.6);
  text-shadow: 3px 6px 10px #FFFFFF, 0 0 0 #000000;
}
Result:

Transform

Hover/Tap for effect

With each letter wrapped in a span, the possibilities are endless.

-Braad

Hover zoom on image links using only CSS3 or only jQuery

I love CSS3. The new transforms are incredibly powerful, and I'm learning new things that I can do with them and the other new CSS3 features every day.

Here is a quick example of a CSS3 transform for image links that I've started using. The effect is a slow zoom on the image on hover. The markup requires a wrapper div and looks like this:

<div class="wrapper">
  <a href="#"><img src="someimage.jpg" alt="" /></a>
</div>

In our CSS we need to set a height or width on the wrapper div that is at least equal to the size of the image, along with overflow: hidden. Here we're using an image that is big, so it's safe to make it responsive by setting our wrapper width as a percentage and leaving height set to auto:

div.wrapper {
  overflow: hidden;
  width: 100%;
  height: auto;
}
a img {
  -webkit-transition: -webkit-transform 0.4s ease;
  -moz-transition: -moz-transform 0.4s ease;
  -o-transition: -o-transform 0.4s ease;
  transition: transform 0.4s ease;
}
a img:hover {
  -webkit-transform: scale(1.05);
  -moz-transform: scale(1.05);
  -ms-transform: scale(1.05);
  -o-transform: scale(1.05);
  transform: scale(1.05);
}

And the result:

kauai

This kind of effect is ideal when you've got big images that are fully rectangle or square shaped, which is why I love using it on photo galleries, portfolios, and big splash image backgrounds. It avoids re-sizing the element on the page but still adds that hint of interactivity that is key to making a website feel responsive to the user.

For added portability, you can use jQuery to apply the effect to all image links automatically. This can get tricky because the script needs to run after all images are loaded so that they have proper dimensions for it to measure to create the wrapper div, but it's a nice hack if the situation allows for it:

/* We are getting help here from desandro's imagesLoaded plugin, but this could be triggered differently to avoid this dependency */ 
$( document ).imagesLoaded( function() {

   // Select all images that are links
   var $imageLinks = $( 'a img' );
  
   // Loop through each image that is a link  
   $imageLinks.each( function(){

      // Store the current item
      var $this = $( this );

      // Wrap the image link in a div
      $this.parent( 'a' ).wrap( '<div class="img-link-wrapper" style="display: inline-block; text-align: center;"></div>' );

      // Setup initial css
      $this.css({ '-webkit-transition' : '0.4s ease',
                  '-moz-transition' : '0.4s ease',
                  '-o-transition' : '0.4s ease',
                  'transition' : '0.4s ease'
                });
     
      // Set the height of the wrapper div to the height of the image
      var imgHeight = $this.height();
      var imgWidth = $this.width();
      $this.parents( 'div.img-link-wrapper' )
           .css({ 'height' : imgHeight,
                  'width' : imgWidth,
                  'overflow' : 'hidden'
                });
   });

   // Set up a .hovered class
   $( 'body' ).append( '<style>.img-link-hovered {-webkit-transform: scale(1.05);-moz-transform: scale(1.05);-ms-transform: scale(1.05);-o-transform: scale(1.05);transform: scale(1.05);}</style>' );

   // add/remove the class on hover
   $( 'a img' ).hover(
      function() {
         $( this ).addClass( 'img-link-hovered' );
      }, function() {
         $( this ).removeClass( 'img-link-hovered' );
      }
   );
});

The result:

See the Pen Hover zoom on image links using only jQuery by Braad Martin (@BraadMartin) on CodePen.0

You might use a script like this to achieve the hover zoom effect in a situation where you're doing front-end work on top of some markup that you can't control. jQuery can be infinitely useful in these situations.

-Braad