<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Website Tailor &#187; CSS</title>
	<atom:link href="http://www.thewebsitetailor.com/tag/css/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.thewebsitetailor.com</link>
	<description>Perry Trinier</description>
	<lastBuildDate>Wed, 02 Nov 2011 02:35:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Compare before and after photos using CSS Clip and jQuery</title>
		<link>http://www.thewebsitetailor.com/2009/11/compare-before-and-after-photos-using-css-clip-and-jquery/</link>
		<comments>http://www.thewebsitetailor.com/2009/11/compare-before-and-after-photos-using-css-clip-and-jquery/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 04:25:56 +0000</pubDate>
		<dc:creator>Perry</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.thewebsitetailor.com/?p=46</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>
<p><strong>UPDATE:</strong> <a href="http://www.catchmyfame.com/2009/06/25/jquery-beforeafter-plugin/">Turns out this has already been done!</a> Oh well, I still had fun with it.</a></p>
<p>Last night I followed a link from Reddit to <a href="http://www.nytimes.com/interactive/2009/11/09/world/europe/20091109-berlinwallthennow.html">The Berlin Wall: 20 Years Later</a> on the New York Times site. It was an interesting feature, but I thought that the use of Flash to display the before and after photos was a little bit gratuitous, especially considering that they could make the content accessible to a wider range of user agents (mobile browsers and Google image search come to mind) by using CSS and Javascript.</p>
<span id="more-46"></span>
<p>Here's a demo I put together:</p>
<style type="text/css"> 
    div.imagecompare { width:500px; height:640px; position:relative; }
    div.imagecompare img.after { 
        clip: rect(0px 500px 640px 250px); 
    }
    div.imagecompare .resizer {
       display:none;
       height:640px;
       width:2px;
       position:absolute;
       top:0;
       left: 250px; 
       cursor:col-resize;
       background:#888;
       text-indent:-999em;
    }
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
<script type="text/javascript">
    jQuery(document).ready( function ()
    {
        jQuery('.resizer').draggable({ 
            axis: 'x',
            containment:'parent',
            drag: function(event,ui) 
            {
                jQuery(this).prev('img.after').css('clip','rect(0px 500px 640px '+ui.position.left+'px)');
            }
        }).css('display','block');
        jQuery('.imagecompare img').click(function (event) 
        {
            var imgcompare_offset = jQuery(this).parent().offset();
            var pos = event.pageX - imgcompare_offset.left;
            jQuery(this).parent().find('.resizer').css('left',pos+'px');
            jQuery(this).parent().find('img.after').css('clip','rect(0px 500px 640px '+pos+'px)');
        });
       jQuery('.imagecompare img').css({
            position: 'absolute',
            top: 0,
            left: 0 
        });

        jQuery('.imagecompare img:last').addClass('after');
        
    });
</script> 
<div class="imagecompare"> 
        <img src="/wp-content/uploads/clip_img_1.jpg" alt="Before photo shows model with frizzy hair" /> 
        <img src="/wp-content/uploads/clip_img_2.jpg" alt="After photo shows manageable (but greasy-looking) hair" /> 
        <a class="resizer">If your browser supports it, drag the handle in the middle to compare the two photos</a>
</div>

<h3>If you'd like to experiment with this yourself, here's how:</h3>

<ol>
<li>Include jQuery and jQuery UI. I like to use the <a href="http://code.google.com/apis/ajaxlibs/documentation/#jquery">libraries hosted by Google</a>.</li>
<li>Here is the markup - beats the hell out of Flash embed code!
<pre><code class="html">
&lt;div class=&quot;imagecompare&quot;&gt;
    &lt;img src=&quot;clip_img_1.jpg&quot; alt=&quot;Before photo shows model with frizzy hair&quot; /&gt;
    &lt;img src=&quot;clip_img_2.jpg&quot; alt=&quot;After photo shows manageable (but greasy-looking) hair&quot; /&gt;
    &lt;a class=&quot;resizer&quot;&gt;If your browser supports it, drag the handle in the middle to compare the two photos&lt;/a&gt;
&lt;/div&gt;
</code></pre>
</li>
<li>Here is the CSS. In a nutshell, we position the images on top of one another and then set the <a href="http://www.ibloomstudios.com/articles/misunderstood_css_clip/" title="This is the best article I found re: CSS clip">CSS clip property</a> of the 'after' image. However, we apply most of the styles by adding classes using jQuery, so that if javascript is disabled the images can be seen in all their unclipped, static-positioned glory. Some CSS is also applied to the <code>a.resizer</code> to position it in the middle of our container, set the cursor style and set an extreme negative text-indent to hide the content of the link.
<pre><code class="css">
div.imagecompare { width:500px; height:640px; position:relative; }
div.imagecompare img.after { 
   clip: rect(0px 500px 640px 250px); /* use spaces instead of commas so it works in IE */
}
div.imagecompare .resizer {
   display:none; /* our JS will set this to block */
   height:100%;
   width:2px;
   position:absolute;
   top:0;
   left: 250px;
   cursor:col-resize;
   background:#888;
   text-indent:-999em;
}
</code></pre>
</li>
<li>The jQuery is pretty straightforward, because <a href="http://docs.jquery.com/UI/API/1.7.2/Draggable">Draggable</a> does most of the work. We set a callback on the 'drag' event, to adjust the clip of the after image when the resizer is dragged. There is also a function that sets the clip and repositions the resizer on click. Finally, we set some styles which are being set by JS because they shouldn't be present if JS is disabled.
<pre><code class="javascript">
jQuery(document).ready( function ()
 {
     /* Init jQuery UI Draggable on the resizer element - see http://docs.jquery.com/UI/API/1.7.2/Draggable */
     jQuery('.resizer').draggable({ 
         axis: 'x',
         containment:'parent',
         drag: function(event,ui) 
         {
             // Set the clip property of the after image on drag
             jQuery(this).prev('img.after').css('clip','rect(0px 500px 640px '+ui.position.left+'px)');
         }
     }).css('display','block');
     jQuery('.imagecompare img').click(function (event) 
     {
         // Get offset of imgcompare div
         var imgcompare_offset = jQuery(this).parent().offset();
         // The position/clip-left value we should use is the X coordinate of the click, minus the offset of the imgcompare container.
         var pos = event.pageX - imgcompare_offset.left;
         // Set the resizer position
         jQuery(this).parent().find('.resizer').css('left',pos+'px');
         // Set the clip
         jQuery(this).parent().find('img.after').css('clip','rect(0px 500px 640px '+pos+'px)');
     });

    /* Set the position of the img elements inside .imgcompare so they will overlap */
    jQuery('.imagecompare img').css({
         position: 'absolute',
         top: 0,
         left: 0 
    });
    
    jQuery('.imagecompare img:last').addClass('after'); // Add after class to the 'after' image
});
</code></pre>
</li>
</ol>

<p>This was my first time working with the CSS clip property. While I was pleasantly surprised that it works in IE6+ and all modern browsers, I was disappointed to learn that it's impossible to set the top, right, bottom and left clip values separately as you can for margin and padding. Instead, you have to reset the whole statement including all four values.</p>

<p>Be sure to leave a comment if you find a use for this code!</p>
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thewebsitetailor.com/2009/11/compare-before-and-after-photos-using-css-clip-and-jquery/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

