Thursday, January 19, 2012

CSS: Elastic Videos

View Demo Elastic Videos



Elastic HTML5 Videos (demo)

With HTML5 video element, you can easily make it elastic by using the max-width:100% trick (see elastic HTML5 video demo). As mentioned in the introduction, this trick doesn't work if the embed code uses iframe or object tag which is commonly used by most video sharing sites such as YouTube and Vimeo.

video {
 max-width: 100%;
 height: auto;
}

Elastic Object & Iframe Embedded Videos (demo)

The trick is very simple. You need to wrap the embed code with a <div> container and specify 50% to 60% padding bottom. Then specify the child elements (iframe, object embed) 100% width, 100% height, with absolute position. This will force the embed elements to expand fullwidth automatically.

CSS


.video-container {
 position: relative;
 padding-bottom: 56.25%;
 padding-top: 30px;
 height: 0;
 overflow: hidden;
}

.video-container iframe,  
.video-container object,  
.video-container embed {
 position: absolute;
 top: 0;
 left: 0;
 width: 100%;
 height: 100%;
}

HTML


<div class="video-container">
 <iframe src="http://player.vimeo.com/video/6284199?title=0&byline=0&portrait=0" width="800" height="450" frameborder="0"></iframe>
</div>

How to Create Fixed Width & Elastic

To restrict the width of the video, an additional <div> wrapper is required. Wrap the video with another <div> tag and specify a fixed width value with max-width:100%.

CSS


.video-wrapper {
 width: 600px;
 max-width: 100%;
}

HTML


<div class="video-wrapper">
 <div class="video-container">
  <iframe src="http://player.vimeo.com/video/6284199?title=0&byline=0&portrait=0" width="800" height="450" frameborder="0"></iframe>
 </div>
 <!-- /video -->
</div>
<!-- /video-wrapper --> 

Compatibility

This trick works on all browsers (tested on Chrome, Safari, Firefox, Internet Explorer, Opera, iPhone and iPad).

Cross-Browser HTML5 Placeholder Text



Old School Javascript Way

Before we had the placeholder attribute, we relied on Javascript to fake the placeholder text. Below is an example. The text is inserted in the value attribute. On focus, it checks if the value is "search" and returns empty to clear the field. If the value is empty, it returns "search." As you can see, this way is not an efficient way because each field has to be checked.
<input type="text" value="Search" onfocus="if (this.value == 'Search') {this.value = '';}" onblur="if (this.value == '') {this.value = 'Search';}">

jQuery Placeholder Text (Demo)

Now with HTML5 placeholder, it is more semantic to use placeholder than value attribute. However, placeholder text is not supported by all browsers. To make it cross-browser, Modernizr and jQuery come in handy here.
Modernizr is used here to check if placeholder is supported. If placeholder is not supported, the jQuery code will run. It finds all elements with placeholder attribute and stores in a variable. It then compares the input value with the placeholder attribute. If the input value is empty, it will display the placeholder text and add a "placeholder" class to the input field. View Demo.
To use this on your site, download a copy of Modernizr and jQuery and paste the following code any where in your html page (be sure the jquery.js and modernizr.js file is in correct path).
<script src="jquery.js"></script>
<script src="modernizr.js"></script>

<script>
$(document).ready(function(){

if(!Modernizr.input.placeholder){

 $('[placeholder]').focus(function() {
   var input = $(this);
   if (input.val() == input.attr('placeholder')) {
  input.val('');
  input.removeClass('placeholder');
   }
 }).blur(function() {
   var input = $(this);
   if (input.val() == '' || input.val() == input.attr('placeholder')) {
  input.addClass('placeholder');
  input.val(input.attr('placeholder'));
   }
 }).blur();
 $('[placeholder]').parents('form').submit(function() {
   $(this).find('[placeholder]').each(function() {
  var input = $(this);
  if (input.val() == input.attr('placeholder')) {
    input.val('');
  }
   })
 });

}

</script>

Remove Webkit Search Input Styles

Webkit browsers add extra styling to the search input field. To remove them, add the following CSS code:
input[type=search] {
 -webkit-appearance: none;
}

input[type="search"]::-webkit-search-decoration, 
input[type="search"]::-webkit-search-cancel-button {
 display: none;
}
webkit search input


HTML5 Grayscale Image Hover

View Demo HTML5 Grayscale


The Purpose

This demo is intented to show you how to make a grayscale/color image hover effect with HTML5 and jQuery. To achieve this effect before HTML5, two images are required: a color and a grayscale version. Now HTML 5 made it easier and faster because the grayscale image is generated from the original source. I hope you will find this script useful in your design such as portfolio showcase, photo gallery, etc.
demo screenshot

jQuery Code

The jQuery code below will look for the target images and generate a grayscale version. When hovering the image, it will fade the grayscale image into color.

<script src="jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
 
 // On window load. This waits until images have loaded which is essential
 $(window).load(function(){
  
  // Fade in images so there isn't a color "pop" document load and then on window load
  $(".item img").fadeIn(500);
  
  // clone image
  $('.item img').each(function(){
   var el = $(this);
   el.css({"position":"absolute"}).wrap("<div class='img_wrapper' style='display: inline-block'>").clone().addClass('img_grayscale').css({"position":"absolute","z-index":"998","opacity":"0"}).insertBefore(el).queue(function(){
    var el = $(this);
    el.parent().css({"width":this.width,"height":this.height});
    el.dequeue();
   });
   this.src = grayscale(this.src);
  });
  
  // Fade image 
  $('.item img').mouseover(function(){
   $(this).parent().find('img:first').stop().animate({opacity:1}, 1000);
  })
  $('.img_grayscale').mouseout(function(){
   $(this).stop().animate({opacity:0}, 1000);
  });  
 });
 
 // Grayscale w canvas method
 function grayscale(src){
  var canvas = document.createElement('canvas');
  var ctx = canvas.getContext('2d');
  var imgObj = new Image();
  imgObj.src = src;
  canvas.width = imgObj.width;
  canvas.height = imgObj.height; 
  ctx.drawImage(imgObj, 0, 0); 
  var imgPixels = ctx.getImageData(0, 0, canvas.width, canvas.height);
  for(var y = 0; y < imgPixels.height; y++){
   for(var x = 0; x < imgPixels.width; x++){
    var i = (y * 4) * imgPixels.width + x * 4;
    var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
    imgPixels.data[i] = avg; 
    imgPixels.data[i + 1] = avg; 
    imgPixels.data[i + 2] = avg;
   }
  }
  ctx.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
  return canvas.toDataURL();
    }
     
</script>

How to use it

To apply this to your site:
  • include a copy of jquery.js
  • paste the code as shown above
  • set the target image (eg: .post-img, img, .gallery img, etc.)
  • you may change the animation speed (ie. 1000 = 1 second)
code screenshot

Compatibility

It works with any browser that support HTML5 and Javascript such as Chrome, Safari, and Firefox. If HTML5 is not supported, it will fallback to original color image. Note: if it doesn't work with Firefox and Chrome locally. You need to put the HTML file on a web server.


CSS3 Image Styles

View Demo Image Styles


Problem (see demo)

Take a look at the demo and note that there is border-radius and inset box-shadow applied in the first row of images. Firefox does render border-radius on image element, but doesn't render the inset box-shadow. Chrome or Safari doesn't render the border-radius and inset box-shadow at all.
border-radius problem

Workaround

To get the border-radius and inset box-shadow working, the workaround is to apply the actual image as background-image.
code

Dynamic Way

To make it dynamic, you can use to jQuery to wrap the background image dynamically for every image element. The jQuery code below will wrap all images with a span tag and apply the image source as the background image (jQuery code by Darcy Clarke).

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){

  $("img").load(function() {
    $(this).wrap(function(){
      return '<span class="image-wrap ' + $(this).attr('class') + '" style="position:relative; display:inline-block; background:url(' + $(this).attr('src') + ') no-repeat center center; width: ' + $(this).width() + 'px; height: ' + $(this).height() + 'px;" />';
    });
    $(this).css("opacity","0");
  });

});
</script>

Output

The above code will output the following HTML code:

<span class="image-wrap " style="position:relative; display:inline-block; background:url(image.jpg) no-repeat center center; width: 150px; height: 150px;">
 <img src="image.jpg" style="opacity: 0;">
</span>

Circle Image (see demo)

Now that the image is applied as a background image, you can pretty much add any style to it. Below is a simple circle image created with border-radius. If you are not familiar with CSS3, read my tutorial on the Basics of CSS3.
circle image

CSS


.circle .image-wrap {
 -webkit-border-radius: 50em;
 -moz-border-radius: 50em;
 border-radius: 50em;
}

Card Style (see demo)

Below is a card-like image style created with multiple inset box-shadow values.
card style

CSS


.card .image-wrap {
 -webkit-box-shadow: inset 0 0 1px rgba(0,0,0,.8), inset 0 2px 0 rgba(255,255,255,.5), inset 0 -1px 0 rgba(0,0,0,.4);
 -moz-box-shadow: inset 0 0 1px rgba(0,0,0,.8), inset 0 2px 0 rgba(255,255,255,.5), inset 0 -1px 0 rgba(0,0,0,.4);
 box-shadow: inset 0 0 1px rgba(0,0,0,.8), inset 0 2px 0 rgba(255,255,255,.5), inset 0 -1px 0 rgba(0,0,0,.4);

 -webkit-border-radius: 20px;
 -moz-border-radius: 20px;
 border-radius: 20px;
}

Embossed Style (see demo)

With some alterations, I can turn the card style into embossed style.
embossed image

CSS


.embossed .image-wrap {
 -webkit-box-shadow: inset 0 0 2px rgba(0,0,0,.8), inset 0 2px 0 rgba(255,255,255,.5), inset 0 -7px 0 rgba(0,0,0,.6), inset 0 -9px 0 rgba(255,255,255,.3);
 -moz-box-shadow: inset 0 0 2px rgba(0,0,0,.8), inset 0 2px 0 rgba(255,255,255,.5), inset 0 -7px 0 rgba(0,0,0,.6), inset 0 -9px 0 rgba(255,255,255,.3);
 box-shadow: inset 0 0 2px rgba(0,0,0,.8), inset 0 2px 0 rgba(255,255,255,.5), inset 0 -7px 0 rgba(0,0,0,.6), inset 0 -9px 0 rgba(255,255,255,.3);

 -webkit-border-radius: 20px;
 -moz-border-radius: 20px;
 border-radius: 20px;
}

Soft Embossed Style (see demo)

This is pretty much the same as the embossed style, but I just applied 1px blur to it.
soft embossed

CSS


.soft-embossed .image-wrap {
 -webkit-box-shadow: inset 0 0 4px rgba(0,0,0,1), inset 0 2px 1px rgba(255,255,255,.5), inset 0 -9px 2px rgba(0,0,0,.6), inset 0 -12px 2px rgba(255,255,255,.3);
 -moz-box-shadow: inset 0 0 4px rgba(0,0,0,1), inset 0 2px 1px rgba(255,255,255,.5), inset 0 -9px 2px rgba(0,0,0,.6), inset 0 -12px 2px rgba(255,255,255,.3);
 box-shadow: inset 0 0 4px rgba(0,0,0,1), inset 0 2px 1px rgba(255,255,255,.5), inset 0 -9px 2px rgba(0,0,0,.6), inset 0 -12px 2px rgba(255,255,255,.3);

 -webkit-border-radius: 20px;
 -moz-border-radius: 20px;
 border-radius: 20px;
}

Cutout Style (see demo)

Again with just inset box-shadow, I can make it to look like a cutout effect.
cutout effect

CSS


.cut-out .image-wrap {
 -webkit-box-shadow: 0 1px 0 rgba(255,255,255,.2), inset 0 4px 5px rgba(0,0,0,.6), inset 0 1px 0 rgba(0,0,0,.6);
 -moz-box-shadow: 0 1px 0 rgba(255,255,255,.2), inset 0 4px 5px rgba(0,0,0,.6), inset 0 1px 0 rgba(0,0,0,.6);
 box-shadow: 0 1px 0 rgba(255,255,255,.2), inset 0 4px 5px rgba(0,0,0,.6), inset 0 1px 0 rgba(0,0,0,.6);

 -webkit-border-radius: 20px;
 -moz-border-radius: 20px;
 border-radius: 20px;
}

Morphing & Glowing (see demo)

In this example, I added transition to the image wrap element. On mouse over, it will morph from rounded corners to circle and add a glowing effect. The glowing effect is done with multiple box-shadow values.
morphing glowing

CSS


.morphing-glowing .image-wrap {
 -webkit-transition: 1s;
 -moz-transition: 1s;
 transition: 1s;

 -webkit-border-radius: 20px;
 -moz-border-radius: 20px;
 border-radius: 20px;
}

.morphing-glowing .image-wrap:hover {
 -webkit-box-shadow: 0 0 20px rgba(255,255,255,.6), inset 0 0 20px rgba(255,255,255,1);
 -moz-box-shadow: 0 0 20px rgba(255,255,255,.6), inset 0 0 20px rgba(255,255,255,1);
 box-shadow: 0 0 20px rgba(255,255,255,.6), inset 0 0 20px rgba(255,255,255,1);

 -webkit-border-radius: 60em;
 -moz-border-radius: 60em;
 border-radius: 60em;
}

Glossy Overlay (see demo)

The glossy gradient overlay is added with the :after pseudo element in the example below.
glossy overlay

CSS


.glossy .image-wrap {
 -webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,.5);
 -moz-box-shadow: inset 0 -1px 0 rgba(0,0,0,.5);
 box-shadow: inset 0 -1px 0 rgba(0,0,0,.5);

 -webkit-border-radius: 20px;
 -moz-border-radius: 20px;
 border-radius: 20px;
}

.glossy .image-wrap:after {
 position: absolute;
 content: ' ';
 width: 100%;
 height: 50%;
 top: 0;
 left: 0;

 -webkit-border-radius: 20px;
 -moz-border-radius: 20px;
 border-radius: 20px;

 background: -moz-linear-gradient(top, rgba(255,255,255,0.7) 0%, rgba(255,255,255,.1) 100%);
 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0.7)), color-stop(100%,rgba(255,255,255,.1)));
 background: linear-gradient(top, rgba(255,255,255,0.7) 0%,rgba(255,255,255,.1) 100%);
}

Reflection (see demo)

In this example, I shifted the overlay gradient to the bottom to create a reflection.
reflection

CSS


.reflection .image-wrap:after {
 position: absolute;
 content: ' ';
 width: 100%;
 height: 30px;
 bottom: -31px;
 left: 0;

 -webkit-border-top-left-radius: 20px;
 -webkit-border-top-right-radius: 20px;
 -moz-border-radius-topleft: 20px;
 -moz-border-radius-topright: 20px;
 border-top-left-radius: 20px;
 border-top-right-radius: 20px;

 background: -moz-linear-gradient(top, rgba(0,0,0,.3) 0%, rgba(255,255,255,0) 100%);
 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,0,0,.3)), color-stop(100%,rgba(255,255,255,0)));
 background: linear-gradient(top, rgba(0,0,0,.3) 0%,rgba(255,255,255,0) 100%);
}

.reflection .image-wrap:hover {
 position: relative;
 top: -8px;
}

Glossy & Reflection (see demo)

In this example, I combined the :before and :after element to create a glossy image style with reflection.
glossy + reflection

CSS


.glossy-reflection .image-wrap {
 -webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.6);
 -moz-box-shadow: inset 0 -1px 0 rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.6);
 box-shadow: inset 0 -1px 0 rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.6);

 -webkit-transition: 1s;
 -moz-transition: 1s;
 transition: 1s;

 -webkit-border-radius: 20px;
 -moz-border-radius: 20px;
 border-radius: 20px;
}

.glossy-reflection .image-wrap:before {
 position: absolute;
 content: ' ';
 width: 100%;
 height: 50%;
 top: 0;
 left: 0;

 -webkit-border-radius: 20px;
 -moz-border-radius: 20px;
 border-radius: 20px;

 background: -moz-linear-gradient(top, rgba(255,255,255,0.7) 0%, rgba(255,255,255,.1) 100%);
 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0.7)), color-stop(100%,rgba(255,255,255,.1)));
 background: linear-gradient(top, rgba(255,255,255,0.7) 0%,rgba(255,255,255,.1) 100%);
}

.glossy-reflection .image-wrap:after {
 position: absolute;
 content: ' ';
 width: 100%;
 height: 30px;
 bottom: -31px;
 left: 0;

 -webkit-border-top-left-radius: 20px;
 -webkit-border-top-right-radius: 20px;
 -moz-border-radius-topleft: 20px;
 -moz-border-radius-topright: 20px;
 border-top-left-radius: 20px;
 border-top-right-radius: 20px;

 background: -moz-linear-gradient(top, rgba(230,230,230,.3) 0%, rgba(230,230,230,0) 100%);
 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(230,230,230,.3)), color-stop(100%,rgba(230,230,230,0)));
 background: linear-gradient(top, rgba(230,230,230,.3) 0%,rgba(230,230,230,0) 100%);
}

Tape Style (see demo)

The :after is used here to create a tape like gradient on top of the image.
tape style

CSS


.tape .image-wrap {
 -webkit-box-shadow: inset 0 0 2px rgba(0,0,0,.7), inset 0 2px 0 rgba(255,255,255,.3), inset 0 -1px 0 rgba(0,0,0,.5), 0 1px 3px rgba(0,0,0,.4);
 -moz-box-shadow: inset 0 0 2px rgba(0,0,0,.7), inset 0 2px 0 rgba(255,255,255,.3), inset 0 -1px 0 rgba(0,0,0,.5), 0 1px 3px rgba(0,0,0,.4);
 box-shadow: inset 0 0 2px rgba(0,0,0,.7), inset 0 2px 0 rgba(255,255,255,.3), inset 0 -1px 0 rgba(0,0,0,.5), 0 1px 3px rgba(0,0,0,.4);
}

.tape .image-wrap:after {
 position: absolute;
 content: ' ';
 width: 60px;
 height: 25px;
 top: -10px;
 left: 50%;
 margin-left: -30px;
 border: solid 1px rgba(137,130,48,.2);

 background: -moz-linear-gradient(top, rgba(254,243,127,.6) 0%, rgba(240,224,54,.6) 100%);
 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(254,243,127,.6)), color-stop(100%,rgba(240,224,54,.6)));
 background: linear-gradient(top, rgba(254,243,127,.6) 0%,rgba(240,224,54,.6) 100%);
 -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 1px 0 rgba(0,0,0,.2);
}

Morphing & Tinting (see demo)

In the example below, I use the :after element to add a radial gradient on mouse over.
morphing + tinting

CSS


.morphing-tinting .image-wrap {
 position: relative;

 -webkit-transition: 1s;
 -moz-transition: 1s;
 transition: 1s;

 -webkit-border-radius: 20px;
 -moz-border-radius: 20px;
 border-radius: 20px;
}

.morphing-tinting .image-wrap:hover {
 -webkit-border-radius: 30em;
 -moz-border-radius: 30em;
 border-radius: 30em;
}

.morphing-tinting .image-wrap:after {
 position: absolute;
 content: ' ';
 width: 100%;
 height: 100%;
 top: 0;
 left: 0;

 -webkit-transition: 1s;
 -moz-transition: 1s;
 transition: 1s;

 -webkit-border-radius: 30em;
 -moz-border-radius: 30em;
 border-radius: 30em;
}
.morphing-tinting .image-wrap:hover:after  {
 background: -webkit-gradient(radial, 50% 50%, 40, 50% 50%, 80, from(rgba(0,0,0,0)), to(rgba(0,0,0,1)));
 background: -moz-radial-gradient(50% 50%, circle, rgba(0,0,0,0) 40px, rgba(0,0,0,1) 80px);
}

Feather Edge Circle (see demo)

The radial gradient can also be used as a mask to create a circle feather effect as seen in the example below.
feather circle

CSS


.feather .image-wrap {
 position: relative;

 -webkit-border-radius: 30em;
 -moz-border-radius: 30em;
 border-radius: 30em;
}

.feather .image-wrap:after  {
 position: absolute;
 content: ' ';
 width: 100%;
 height: 100%;
 top: 0;
 left: 0;

 background: -webkit-gradient(radial, 50% 50%, 50, 50% 50%, 70, from(rgba(255,255,255,0)), to(rgba(255,255,255,1)));
 background: -moz-radial-gradient(50% 50%, circle, rgba(255,255,255,0) 50px, rgba(255,255,255,1) 70px);
}

Browser Capability

This trick pretty much work on any browser (eg. Chrome, Firefox and Safari) that supports border-radius, box-shadow, :before and :after. The unsupported browsers will fall back to the image without any styles.

Word-Wrap: Force Text to Wrap


CSS: Word-Wrap Property (view demo)

You can specify either normal or break-word value with the word-wrap property. Normal means the text will extend the boundaries of the box. Break-word means the text will wrap to next line.
.break-word {
  word-wrap: break-word;
}
break word