<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-4835543129581941165</atom:id><lastBuildDate>Sun, 29 Jan 2012 19:44:50 +0000</lastBuildDate><category>web application</category><category>flash</category><category>content sink</category><category>parsing errors</category><category>ecmascript</category><category>bug</category><category>css attribute selectors</category><category>modena</category><category>algorithms</category><category>RIA</category><category>wcag 2.0</category><category>cocoa</category><category>xampp</category><category>google sitemap</category><category>lightbox</category><category>classes</category><category>procedural programming</category><category>xpath</category><category>silvia dini</category><category>jaws</category><category>semantics</category><category>prototypes</category><category>xhtml</category><category>nodelist</category><category>c++</category><category>closures</category><category>fbml</category><category>opera</category><category>roberto ellero</category><category>jss</category><category>google apis</category><category>facebook</category><category>scripting</category><category>attack</category><category>daily life</category><category>jast</category><category>java</category><category>olpc</category><category>reset css</category><category>property</category><category>best practices</category><category>django</category><category>experiment</category><category>c</category><category>mvc</category><category>background images</category><category>browser statistics</category><category>css comments</category><category>richard stallman</category><category>interview</category><category>desktop</category><category>web fonts</category><category>object oriented</category><category>flickr</category><category>obtrusive</category><category>google prettify</category><category>design</category><category>specifications</category><category>simon daniels</category><category>json</category><category>compiler</category><category>svn</category><category>google</category><category>jsanim</category><category>radio buttons</category><category>css urls</category><category>W3C</category><category>search engine</category><category>application</category><category>eric seidel</category><category>site</category><category>lastModified</category><category>typography</category><category>text-indent</category><category>plugin</category><category>font sizer</category><category>overriding styles</category><category>id selectors</category><category>dxr</category><category>embed</category><category>web toolkit</category><category>social network</category><category>xlink</category><category>user experience</category><category>daniele florio</category><category>navigation</category><category>layout engine</category><category>extensions</category><category>matilde</category><category>screen readers</category><category>engine</category><category>xslt</category><category>scriptaculous</category><category>lynx</category><category>widgets</category><category>simplexml</category><category>private</category><category>properties</category><category>jquery</category><category>boris zbarsky</category><category>wikipedia</category><category>print</category><category>web typography</category><category>sabayon</category><category>sql</category><category>twitter</category><category>web forms</category><category>source code</category><category>standards</category><category>media queries</category><category>social media</category><category>acid test 3</category><category>includes</category><category>gmail</category><category>andy budd</category><category>mobile</category><category>clear</category><category>overuse</category><category>wai-aria</category><category>html5</category><category>web</category><category>firebug</category><category>tails</category><category>library</category><category>application/xhtml+xml</category><category>wordpress theme</category><category>web slices</category><category>applications</category><category>queries</category><category>standard</category><category>css</category><category>javascript engine</category><category>web 2.0</category><category>essentials</category><category>appunti sui css</category><category>file inputs</category><category>performance</category><category>v8</category><category>local hosts</category><category>dummy text</category><category>ims</category><category>christopher schmitt</category><category>safari</category><category>asp</category><category>xml</category><category>unobtrusive javascript</category><category>urls</category><category>mysql</category><category>google maps</category><category>inline styles</category><category>dom level 2</category><category>input background images</category><category>experiments</category><category>google adsense</category><category>web standards</category><category>cameron moll</category><category>automation server can't create object</category><category>POSIX</category><category>android</category><category>accessibility guidelines</category><category>domdocument</category><category>svg</category><category>david baron</category><category>o'reilly</category><category>simon collison</category><category>javascript effects</category><category>regular expressions</category><category>slide</category><category>syntax highlighter</category><category>zend</category><category>web accessibility</category><category>itunes</category><category>prototype</category><category>bugzilla</category><category>css anomalies</category><category>floats</category><category>selectors</category><category>design patterns</category><category>wireframe</category><category>javascript</category><category>documents</category><category>web development</category><category>gnu</category><category>youtube</category><category>var keyword</category><category>dave raggett</category><category>iwa</category><category>browsers</category><category>effects</category><category>get glue</category><category>yahoo user interface</category><category>developers</category><category>portfolio</category><category>css tables</category><category>analysis</category><category>amazon</category><category>browser</category><category>forms</category><category>windows</category><category>layouts</category><category>filling text</category><category>image element</category><category>css breadcrumbs</category><category>progressive enhancement</category><category>csv</category><category>textpattern</category><category>email validation</category><category>feed</category><category>tabs</category><category>sass</category><category>internet explorer</category><category>php</category><category>2010</category><category>lucene</category><category>oop</category><category>website</category><category>gecko</category><category>wamboo</category><category>jquery 1.4.2</category><category>eric meyer</category><category>free software</category><category>libxml</category><category>singleton pattern</category><category>tests</category><category>captcha</category><category>formatrssdate</category><category>blogger</category><category>type hinting</category><category>pseudo-elements</category><category>css tests</category><category>poetry</category><category>pattern</category><category>polyglot inc</category><category>namespace selectors</category><category>modular</category><category>keywords</category><category>images</category><category>dom navigation</category><category>icons</category><category>dtd</category><category>development</category><category>border-opacity</category><category>events</category><category>parsing</category><category>api</category><category>white-space</category><category>yql</category><category>tokenizer</category><category>chrome</category><category>inheritance</category><category>git</category><category>spam</category><category>rss</category><category>apps</category><category>code compressions</category><category>video</category><category>redirect</category><category>mashup</category><category>hcard</category><category>basics</category><category>directory listing</category><category>extending</category><category>stoyan stefanov</category><category>demos</category><category>sitepoint</category><category>mxr</category><category>301</category><category>faq</category><category>social icons</category><category>zend studio</category><category>themes</category><category>wordpress</category><category>pdf</category><category>rest</category><category>javascript libraries</category><category>form validation</category><category>smarty</category><category>optimization</category><category>rich internet applications</category><category>magento</category><category>framework</category><category>feedburner</category><category>yahoo query language</category><category>scott meyers</category><category>feeds</category><category>objects literals</category><category>nomenclature</category><category>information architecture</category><category>dom</category><category>page refresh</category><category>XMLHttpRequest</category><category>perl</category><category>github</category><category>accordion</category><category>css positioning</category><category>generated content</category><category>tech talks</category><category>steve souders</category><category>excel</category><category>prototyping</category><category>webkit</category><category>steve jobs</category><category>uml</category><category>prince</category><category>textarea</category><category>bleach</category><category>css parser</category><category>usability</category><category>dreamweaver</category><category>mark pilgrim</category><category>css generated content</category><category>table model</category><category>css classes</category><category>mac os x</category><category>interoperability</category><category>web services</category><category>aaron gustafson</category><category>anne van kesteren</category><category>publishing</category><category>haslayout</category><category>seo</category><category>default style sheet</category><category>douglas crockford</category><category>permanent links</category><category>squirrelfish extreme</category><category>reusable</category><category>css table values</category><category>web site</category><category>javascript animations</category><category>ie6fix</category><category>michele diodati</category><category>templates</category><category>css bugs</category><category>html forms</category><category>gwt</category><category>john resig</category><category>bug tracking</category><category>functions</category><category>syntax</category><category>date</category><category>validation</category><category>css 3 selectors</category><category>firefox</category><category>navigation menu</category><category>iphone</category><category>accessibility</category><category>css sprites</category><category>nicholas c. zakas</category><category>bjarne stroustrup</category><category>css 2.1</category><category>matt mullenweg</category><category>eclipse</category><category>supporting</category><category>user testing</category><category>cascade</category><category>css 3</category><category>lorem ipsum</category><category>page rank</category><category>security</category><category>semantic web</category><category>object</category><category>css3</category><category>form validator</category><category>aural css</category><category>rootkit</category><category>headings</category><category>minidom</category><category>theming</category><category>microformats</category><category>box model</category><category>gears</category><category>geolocation</category><category>tutorials</category><category>zend framework</category><category>html</category><category>hakon wium lie</category><category>testing</category><category>russ weakley</category><category>ide</category><category>web design</category><category>yui</category><category>javascript dates</category><category>image optimization</category><category>debugging</category><category>pcre</category><category>marco olivetti</category><category>validation icons</category><category>url rewriting</category><category>conference</category><category>overflow</category><category>validator</category><category>css absolute positioning</category><category>tables</category><category>compression</category><category>tim berners-lee</category><category>jquery plugin</category><category>namespaces</category><category>ibm</category><category>python</category><category>cms</category><category>internet</category><category>rounded corners</category><category>html 5</category><category>css floats</category><category>database</category><category>molly holzschlag</category><category>simon willison</category><category>apache</category><category>linux</category><category>fancybox</category><category>rendering</category><category>template blocks</category><category>calendars</category><category>ajax</category><category>programming</category><category>tutorial</category><category>objects</category><category>facebook api</category><category>ian hickson</category><category>jsp</category><category>blog</category><category>data urls</category><category>roberto scano</category><category>object oriented programming</category><category>form elements</category><category>drupal</category><category>jquery novice to ninja</category><category>microsoft</category><category>colors</category><category>legacy browsers</category><category>smau</category><category>visited links</category><category>mercurial</category><category>client-side code</category><category>high performance websites</category><title>onwebdev</title><description>Web development by Gabriele Romanato</description><link>http://onwebdev.blogspot.com/</link><managingEditor>noreply@blogger.com (Gabriele Romanato)</managingEditor><generator>Blogger</generator><openSearch:totalResults>1669</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/blogspot/onwebdev" /><feedburner:info uri="blogspot/onwebdev" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>blogspot/onwebdev</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/blogspot/onwebdev" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-7272202624652305148</guid><pubDate>Sun, 29 Jan 2012 19:44:00 +0000</pubDate><atom:updated>2012-01-29T11:44:50.235-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">wordpress</category><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: AJAX contact form for WordPress</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/08/wordpress_jquery.jpg" alt="" class="aligncenter spaced"/&gt;jQuery can actually interact very well with WordPress. A typical example of this is surely a contact form enhanced with AJAX. Let's see how things work from the client-side point of view.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;The first thing to bear in mind is that a WordPress contact page is self-processed, meaning that the value of the &lt;code&gt;action&lt;/code&gt; attribute corresponds to the current page.&lt;/p&gt;

&lt;p&gt;For that reason, we need to use this value as our target URL. Then we need to attach an extra POST variable to notify the server-side script (which also handles data validation) that our form has been submitted. We also need to attach another variable to make sure that the output of the server-side script will be displayed only when the form has been actually sent:&lt;/p&gt;

&lt;pre&gt;
(function($) {


 $(function() {
 
  var Contact = function() {
  
   var form = '#contact';
   
   
   
   
   this.process = function() {
   
   
   $(form).submit(function(event) {
   
    var $form = $(this);
    var url = $form.attr('action');
    var data = 'from=' + $('#from', $form).val() + '&amp;email=' + $('#email', $form).val() +
                '&amp;subject=' + $('#subject', $form).val() +
                '&amp;message=' + $('#message', $form).val() +
                '&amp;captcha=' + $('#captcha', $form).val() +
                '&amp;contact-submit=Send&amp;ajax=true';
    
    $.ajax({
     type: 'POST',
     dataType: 'text',
     url: url,
     data: data,
     success: function(txt) {
     
         $('div.success, div.error', $form).remove();
     
      $(txt).prependTo($('ul', $form));
      
      $('html, body').animate({
       scrollTop: $form.offset().top
      }, 500);
      
     
     
     }
     
    });
    
    
    event.preventDefault();
   
   
   });
   
   }
  
  
  };
  
  var contact = new Contact();
  
  if($('#contact').length) {
  
   contact.process();
   
  }
 
 
 });


})(jQuery);
&lt;/pre&gt;

&lt;p&gt;In the &lt;code&gt;success()&lt;/code&gt; callback method we remove any message generated by the server-side script before adding further messages. Then we use the &lt;code&gt;scrollTop&lt;/code&gt; property to make the entire page scroll up to the top of the form:&lt;/p&gt;

&lt;pre&gt;
$('div.success, div.error', $form).remove();
     
$(txt).prependTo($('ul', $form));
      
$('html, body').animate({
 scrollTop: $form.offset().top
}, 500);
&lt;/pre&gt;

&lt;p&gt;You can see the demo below.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="420" height="315" src="http://www.youtube.com/embed/PFvTvuJ4Lb8?rel=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-7272202624652305148?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/DudFuzoI6vY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/DudFuzoI6vY/jquery-ajax-contact-form-for-wordpress.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/PFvTvuJ4Lb8/default.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/jquery-ajax-contact-form-for-wordpress.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-7242249903320676094</guid><pubDate>Wed, 25 Jan 2012 18:16:00 +0000</pubDate><atom:updated>2012-01-25T10:16:08.858-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">css</category><title>CSS: create layouts with table values</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/images/css.png" alt="" class="alignright"/&gt;In this article I'll explain how to use the table values of the &lt;acronym title="Cascading Style Sheets"&gt;CSS&lt;/acronym&gt;
&lt;code&gt;display&lt;/code&gt; property to format certain sections of a simple three-columns layout.&lt;/p&gt; 

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;The final layout is shown in the
picture below.
&lt;/p&gt;

&lt;div class="picture"&gt;
&lt;a href="http://www.css-zibaldone.com/articles/table-values/examples/final/final.html"&gt;
&lt;img src="http://www.css-zibaldone.com/articles/table-values/img/final.png" alt="The final layout" /&gt;
&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;The relevant sections that will be formatted with such values are highlighted in the following picture.&lt;/p&gt;

&lt;div class="picture"&gt;
&lt;img src="http://www.css-zibaldone.com/articles/table-values/img/highlight.png" alt="Navigation, sub-header and post title" /&gt;
&lt;/div&gt;

&lt;h2 id="navigation-menu"&gt;The navigation menu&lt;/h2&gt;
&lt;p&gt;We start with the following markup:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;div id=&amp;quot;header&amp;quot;&amp;gt;
&amp;lt;h1&amp;gt;CSS Magazine&amp;lt;/h1&amp;gt;
&amp;lt;ul id=&amp;quot;nav&amp;quot;&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;Home&amp;lt;/strong&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Articles&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Tests&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Tutorials&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;As you can see, the navigation menu (&lt;code&gt;#nav&lt;/code&gt;) is contained in the &lt;code&gt;#header&lt;/code&gt;
section, where there is also the main title of the page (an &lt;code&gt;h1&lt;/code&gt; element. The styles could
be the following:&lt;/p&gt;

&lt;pre&gt;
#header {
height: 8em;
min-height: 80px;
border-bottom: 1px solid #333;
background: #fff url("img/banner.png") no-repeat 0 0;
position: relative;
}
#header h1 {
position: absolute;
top: -1000em;
}
#nav {
display: table;
position: absolute;
top: 0;
right: 0;
height: 100%;
border-left: 1px solid;
margin: 0;
padding: 0;
border-collapse: collapse;
width: 15%;
}
#nav li {
display: table-row;
}
#nav li a, #nav li strong {
display: table-cell;
border: 1px solid #000;
font-size: 120%;
width: 100%;
padding: 0 0.3em;
text-decoration: none;
}
#nav li a:hover {
background: #800;
color: #fff;
}
#nav li strong {
background: #800;
color: #fff;
}
&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://www.css-zibaldone.com/articles/table-values/examples/3/3.html"&gt;View the example&lt;/a&gt; -
&lt;a href="http://www.css-zibaldone.com/articles/table-values/img/3.png"&gt;View the screenshot&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;The first two rules give a basic formatting to our header. We've set a height in ems and a
minimum height in pixels. The latter equals the height of the background image that we'll use as
a banner. A minimum height gives a full visibility to our background image even when the user
decreases the base font size or when the specified font used on the page is not available. The last
declaration of the first rule creates a new context positioning through the value &lt;code&gt;relative&lt;/code&gt;
of the &lt;code&gt;position&lt;/code&gt; property. Thanks to this declaration, we can absolutely position our
navigation menu by taking the header section as a reference and not the whole viewport. Then we want
to get rid of the heading's text, since it must be replaced by the background image. We use absolute
positioning with an enormous negative value for the &lt;code&gt;top&lt;/code&gt; property. This value will
actually make the text disappear from the page.&lt;/p&gt;

&lt;p&gt;Then comes our navigation menu.
The first declaration of the third rule turns our unordered list into a table.
Since we're working now with tables, we should be sure that there will be no extra space
between the cells. For that reason, we use the &lt;code&gt;border-collapse&lt;/code&gt; property set to
&lt;code&gt;collapse&lt;/code&gt;. By doing so, the borders of the single cells will collapse to form an unique
border. Tables can be floated and absolutely positioned, since they're actually block-level elements or,
more precisely, elements that work in a block-level formatting context.
Our menu will be absolutely positioned on the right and with a left border. Its height will equal the
height of its container, while its width will be 15% of the container's width.&lt;/p&gt;

&lt;p&gt;Now we need table rows to host our cells. We turn the list items into table rows by declaring
&lt;code&gt;display: table-row&lt;/code&gt; on each &lt;code&gt;li&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;Finally, we create the table cells in the fifth rule by declaring
&lt;code&gt;display: table-cell&lt;/code&gt; on the &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;strong&lt;/code&gt; elements.
The border of these cells will collapse to form an unique border, as said above.
The width of the cells will be 100% of the total, plus a 0.3em of left and right padding.
In case you're wondering, the content of the cells will not overflow its container because of the
type of table layout set on our menu. Tables can have two types of layout, controlled by the
&lt;code&gt;table-layout&lt;/code&gt; property: &lt;code&gt;auto&lt;/code&gt; and &lt;code&gt;fixed&lt;/code&gt;. The first value
is used by default on all tables and it's used also on our menu. With this value, the global width
of the table will be determined by the width (and the content) of its single cells. In other words,
we have a fluid table that will expand automatically together with its cells.&lt;/p&gt;

&lt;h2 id="sub-header"&gt;The sub-header&lt;/h2&gt;

&lt;p&gt;The sub-header is marked up as follows:&lt;/p&gt;


&lt;pre&gt;
&amp;lt;div id=&amp;quot;subheader&amp;quot;&amp;gt;
&amp;lt;p id=&amp;quot;issue&amp;quot;&amp;gt;Issue 1, August 2008&amp;lt;/p&amp;gt;
&amp;lt;form id=&amp;quot;search&amp;quot; action=&amp;quot;#&amp;quot;&amp;gt;
&amp;lt;div&amp;gt;
&amp;lt;label for=&amp;quot;text&amp;quot;&amp;gt;Search:&amp;lt;/label&amp;gt;
&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; id=&amp;quot;text&amp;quot; /&amp;gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; id=&amp;quot;btn&amp;quot; name=&amp;quot;btn&amp;quot; value=&amp;quot;Go&amp;quot; /&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;We want to put the &lt;code&gt;#issue&lt;/code&gt; element on the left and the search form on the right.
The code could be the following:&lt;/p&gt;

&lt;pre&gt;
#subheader {
display: table;
width: 100%;
height: 1.4em;
border-bottom: 1px solid #000;
font-size: 120%;
}
#subheader #issue {
display: table-cell;
width: 30%;
vertical-align: middle;
font-weight: bold;
padding: 0 0.5em;
text-transform: uppercase;
}
#subheader form {
display: table-cell;
width: 68%;
text-align: right;
vertical-align: middle;
padding: 0.5em;
}
#subheader form label {
font-weight: bold;
}
#subheader form input {
font: 1em Verdana, sans-serif;
}
#subheader form input#text {
border: 1px solid #000;
background: #fff;
color: #333;
}
#subheader form input#btn {
background: #800;
color: #fff;
font-weight: bold;
border: 1px solid #800;
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/table-values/examples/4/4.html"&gt;View the example&lt;/a&gt; -
&lt;a href="http://www.css-zibaldone.com/articles/table-values/img/4.png"&gt;View the screenshot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first rule turns the sub-header section into a table, sets a global height and width
plus a bottom border. The second rule turns the &lt;code&gt;#issue&lt;/code&gt; element into a table cell, sets
a width on the element plus the vertical alignment of the text inside the cell (&lt;code&gt;middle&lt;/code&gt;).
The third rule turns the form into a table cell. As for the previous element, also in this case
the vertical margins of this element will be resetted, since table cells cannot have vertical margins.
The width of this element covers almost all the available space and this is actually our intended
purpose. In fact, with the declaration &lt;code&gt;text-align: right&lt;/code&gt; we push the form elements to
the right of the sub-header, as we do want. Also in this case the elements will be vertically
aligned, thanks to the declaration &lt;code&gt;vertical-align: middle&lt;/code&gt;.
The fifth rule deserves a further explanation: since the dimensions of form elements are determined
also by the type and size of the used font, a good way to get consistency across browsers is an explicit
declaration of font type/size on the elements we want to format (in this case, &lt;code&gt;input&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id="post-title"&gt;The post title&lt;/h2&gt;
&lt;p&gt;The markup for this section is really simple, as you can see below.&lt;/p&gt;

&lt;pre&gt;
&amp;lt;div class=&amp;quot;art-title&amp;quot;&amp;gt;
&amp;lt;h2&amp;gt;Lorem ipsum&amp;lt;/h2&amp;gt;
&amp;lt;p class=&amp;quot;date&amp;quot;&amp;gt;8/17/2008&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;The post title has been inserted through a &lt;code&gt;h2&lt;/code&gt; element and the date of the post is
marked up with a paragraph having &lt;code&gt;.date&lt;/code&gt; as its own class. The styles could be the
following:&lt;/p&gt;




&lt;pre&gt;
.art-title {
background: #800;
color: #fff;
display: table;
width: 100%;
margin-top: 1em;
padding: 0.3em 0;
}
.art-title h2 {
font-size: 1.4em;
display: table-cell;
width: 40%;
vertical-align: middle;
color: #fff;
padding-left: 3px;
}
.art-title .date {
display: table-cell;
width: 60%;
vertical-align: middle;
text-align: right;
padding-right: 3px;
font-style: italic;
font-weight: bold;
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/table-values/examples/6/6.html"&gt;View the example&lt;/a&gt; -
&lt;a href="http://www.css-zibaldone.com/articles/table-values/img/6.png"&gt;View the screenshot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, we've turned the outermost container into a table and its children into table cells.
The vertical alignment of the text is controlled by the &lt;code&gt;vertical-align&lt;/code&gt; property.
The width of each element can be adjusted in order to satisfy particular needs. In this case,
we could change the value 40% with 60%, since the content of a date doesn't require so much space.&lt;/p&gt;






&lt;h3 id="download"&gt;Download&lt;/h3&gt;
&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/table-values/examples.zip"&gt;examples.zip&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-7242249903320676094?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/DQdKYSpCv-4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/DQdKYSpCv-4/css-create-layouts-with-table-values.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/css-create-layouts-with-table-values.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-1765152487891134157</guid><pubDate>Tue, 24 Jan 2012 10:55:00 +0000</pubDate><atom:updated>2012-01-24T02:55:22.448-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">wordpress</category><category domain="http://www.blogger.com/atom/ns#">twitter</category><title>WordPress: publish a tweet as a post</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/01/social-media-icons-wordpress.jpg" alt="" class="aligncenter spaced" /&gt;Twitter is surely one the most popular social networks on the web, and WordPress is surely one the most popular CMS available today. Usually these two platforms interact only in one way: you get something from Twitter, you post something on Twitter. Let's say that you want to publish your latest tweet as a post on your WordPress site, also checking if there is another brand new tweet available. How we can to this?&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;The first thing you need to do is to create a category for your tweets. Let's name this category &lt;code&gt;tweets&lt;/code&gt; and assume that its assigned category ID is 145 (you can see the ID by hovering the category link with your mouse on the WordPress backend).&lt;/p&gt;

&lt;p&gt;Then add the following code to the &lt;code&gt;functions.php&lt;/code&gt; file of your theme:&lt;/p&gt;


&lt;pre&gt;
function get_insert_latest_tweet() {
 global $wpdb;
 $post = array();
 $url = &amp;quot;http://twitter.com/statuses/user_timeline/yourusername.xml?count=1&amp;quot;;
 
 if(file_get_contents($url)) {
 
  $xml = new SimpleXMLElement(file_get_contents($url));
  $status = $xml-&amp;gt;status-&amp;gt;text;
  $time = nice_time(strtotime($xml-&amp;gt;status-&amp;gt;created_at));
  $tweet = preg_replace('/http:\/\/(.*?)\/[^ ]*/', '&amp;lt;a href=&amp;quot;\\0&amp;quot;&amp;gt;\\0&amp;lt;/a&amp;gt;', $status);
  $title = preg_replace('/http:\/\/(.*?)\/[^ ]*/', '', $status);
  
  $result = $wpdb-&amp;gt;get_row(&amp;quot;SELECT * FROM $wpdb-&amp;gt;posts WHERE post_title = '$title'&amp;quot;);
  
  $post['post_title'] = $title;
  $post['post_content'] = '&amp;lt;p&amp;gt;' . $tweet . ' &amp;lt;small&amp;gt;' . $time . '&amp;lt;/small&amp;gt;&amp;lt;/p&amp;gt;';
  $post['post_status'] = 'publish';
  $post['post_category'] = array(145);
  $post['tags_input'] = 'tweet';
  
  if(is_null($result)) {
   wp_insert_post($post);
  }
  
 } else {
 
  return;
 
 }
 
 
 
}

add_action( 'pre_get_posts', 'get_insert_latest_tweet');



function nice_time($time) {
  $delta = time() - $time;
  if ($delta &amp;lt; 60) {
    return 'less than a minute ago.';
  } else if ($delta &amp;lt; 120) {
    return 'about 1 minute ago.';
  } else if ($delta &amp;lt; (45 * 60)) {
    return floor($delta / 60) . ' minutes ago.';
  } else if ($delta &amp;lt; (90 * 60)) {
    return 'about 1 hour ago.';
  } else if ($delta &amp;lt; (24 * 60 * 60)) {
    return 'about ' . floor($delta / 3600) . ' hours ago.';
  } else if ($delta &amp;lt; (48 * 60 * 60)) {
    return '1 day ago.';
  } else {
    return floor($delta / 86400) . ' days ago.';
  }
}
&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;get_insert_latest_tweet()&lt;/code&gt; create a new post from your Twitter feed through the &lt;a href="http://codex.wordpress.org/Function_Reference/wp_insert_post"&gt;wp_insert_post()&lt;/a&gt; function. Before creating a new post, though, it checks whether the current tweet has already been inserted. If so, it does nothing.&lt;/p&gt;

&lt;p&gt;The WordPress action used here is &lt;code&gt;pre_get_posts&lt;/code&gt; which means that the current tweet is fetched within your main WordPress Loop. You can change this behavior by moving the above function in a separate plugin that requires your deliberate action to create a new post from a tweet.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-1765152487891134157?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/YLn1e1SErOU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/YLn1e1SErOU/wordpress-publish-tweet-as-post.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/wordpress-publish-tweet-as-post.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-6259059497409226742</guid><pubDate>Mon, 23 Jan 2012 18:35:00 +0000</pubDate><atom:updated>2012-01-23T10:35:28.262-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">css</category><title>CSS: how to style form elements</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/01/form.jpg" alt="" class="aligncenter spaced" /&gt;In this article I'll explain how to format form elements by using &lt;acronym title="Cascading Style Sheets"&gt;CSS&lt;/acronym&gt;.
Finally, I'll provide a series of screenshots taken from the various browsers.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;The markup&lt;/h2&gt;

&lt;p&gt;We start with the following markup:&lt;/p&gt;


&lt;pre&gt;
&amp;lt;form action=&amp;quot;#&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;
 &amp;lt;fieldset&amp;gt;
 &amp;lt;legend&amp;gt;Personal information&amp;lt;/legend&amp;gt;
 &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;name&amp;quot; id=&amp;quot;name&amp;quot; /&amp;gt;
  &amp;lt;label for=&amp;quot;email&amp;quot;&amp;gt;Email:&amp;lt;/label&amp;gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;email&amp;quot; id=&amp;quot;email&amp;quot; /&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;
  &amp;lt;label for=&amp;quot;male&amp;quot;&amp;gt;Male&amp;lt;/label&amp;gt;
  &amp;lt;input type=&amp;quot;checkbox&amp;quot; value=&amp;quot;male&amp;quot; id=&amp;quot;male&amp;quot; name=&amp;quot;male&amp;quot; /&amp;gt;
  &amp;lt;label for=&amp;quot;female&amp;quot;&amp;gt;Female&amp;lt;/label&amp;gt;
  &amp;lt;input type=&amp;quot;checkbox&amp;quot; value=&amp;quot;female&amp;quot; id=&amp;quot;female&amp;quot; name=&amp;quot;female&amp;quot; /&amp;gt;
  &amp;lt;label for=&amp;quot;country&amp;quot;&amp;gt;Country:&amp;lt;/label&amp;gt;
  &amp;lt;select name=&amp;quot;country&amp;quot; id=&amp;quot;country&amp;quot;&amp;gt;
   &amp;lt;option value=&amp;quot;USA&amp;quot;&amp;gt;USA&amp;lt;/option&amp;gt;
   &amp;lt;option value=&amp;quot;Italy&amp;quot;&amp;gt;Italy&amp;lt;/option&amp;gt;
  &amp;lt;/select&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;
  &amp;lt;h2&amp;gt;Comments&amp;lt;/h2&amp;gt;
  &amp;lt;textarea rows=&amp;quot;10&amp;quot; cols=&amp;quot;40&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; id=&amp;quot;btn&amp;quot; name=&amp;quot;btn&amp;quot; value=&amp;quot;Send&amp;quot; /&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;/fieldset&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/1/1.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We're going to stylize the following elements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;form&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fieldset&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;legend&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;label&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;input&lt;/code&gt; as:
&lt;ul&gt;
&lt;li&gt;text field&lt;/li&gt;
&lt;li&gt;checkbox&lt;/li&gt;
&lt;li&gt;submit button&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;select&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;textarea&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that we've used proper attributes for each element, due to accessibility reasons.&lt;/p&gt;

&lt;h2&gt;General styles&lt;/h2&gt;

&lt;p&gt;The following styles set only the backbone for further and more advanced styles.&lt;/p&gt;


&lt;pre&gt;
form, fieldset {
 margin: 0;
 padding: 0;
}

form {
 width: 500px;
 background: #ffe;
 color: #000;
 font: small Verdana, sans-serif;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/2/2.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've resetted the default margin and padding on the &lt;code&gt;form&lt;/code&gt; and &lt;code&gt;fieldset&lt;/code&gt; elements.
Then we've specified a width for our form, plus font and colors.&lt;/p&gt;

&lt;h2&gt;Adding some padding to the form&lt;/h2&gt;

&lt;p&gt;We need some vertical padding to create a certain amount of vertical spaces above and below the blocks. So
we can write the following:&lt;/p&gt;

&lt;pre&gt;
form {
 padding: 1em 0;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/3/3.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;Fieldset and legend&lt;/h2&gt;

&lt;p&gt;Now we can start stylizing the &lt;code&gt;fieldset&lt;/code&gt; and &lt;code&gt;legend&lt;/code&gt; elements. Styles are the following:&lt;/p&gt;

&lt;pre&gt;
fieldset {
 display: block;
 width: 90%;
 margin: 0 auto;
 border: 1px solid #666;
}

legend {
 padding: 0 0.2em;
 background: #c00;
 color: #fff;
 font-weight: bold;
 text-transform: uppercase;
 margin-left: 0.5em;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/4/4.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;fieldset&lt;/code&gt; is actually a block-level element, but we've declared it explicitly in order to prevent browsers
from applying their internal algorithms for handling form elements. Then we've specified a width and we've centered this
element through horizontal automatic margins. On the contrary, &lt;code&gt;legend&lt;/code&gt; is an inline element, so we've only added
a left margin and some horizontal padding. Just for the record, Internet Explorer 7 (and lower) doesn't need a left margin to
keep this element separated from the &lt;code&gt;fieldset&lt;/code&gt;'s left border, so we've used the following code only for Internet
Explorer:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;!--[if lt IE 8]&amp;gt;
&amp;lt;style type=&amp;quot;text/css&amp;quot; media=&amp;quot;screen&amp;quot;&amp;gt;
legend {margin-left: 0}
&amp;lt;/style&amp;gt;
&amp;lt;![endif]--&amp;gt;
&lt;/pre&gt;

&lt;p&gt;What's more, &lt;code&gt;legend&lt;/code&gt; is one of those elements that is actually &amp;quot;locked&amp;quot; by browser's algorithms so that
we can specify only a few styles on it.&lt;/p&gt;

&lt;h2&gt;Creating centered rows&lt;/h2&gt;

&lt;p&gt;After centering the main content of our form, we want to center the other elements. This can be done very easily.&lt;/p&gt;

&lt;pre&gt;
div.row {
 width: 90%;
 margin: 0 auto;
 padding: 1em 0;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/5/5.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We use vertical padding instead of margins in order to avoid some problems with Internet Explorer 7 (and lower), namely
the wrong computation of margins in a form.&lt;/p&gt;

&lt;h2&gt;Input and label&lt;/h2&gt;

&lt;p&gt;Now we can stylize the text fields and the &lt;code&gt;label&lt;/code&gt; elements.&lt;/p&gt;


&lt;pre&gt;
label {
 vertical-align: middle;
 font-weight: bold;
}

input {
 font: 1em Verdana, sans-serif;
 vertical-align: middle;
}
input#name, input#email {
 width: 100px;
 border: 1px solid #c00;
 background: #fff;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/6/6.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;To vertically align the elements, we've used the &lt;code&gt;vertical-align&lt;/code&gt; property set to &lt;code&gt;middle&lt;/code&gt;.
Another important thing to keep in mind is that the actual dimensions of text fields are determined by the type and
size of the font in use. For that reason, we've specified a font family and a font size on each &lt;code&gt;input&lt;/code&gt; element, so
that the vertical alignment can be handled correctly.&lt;/p&gt;

&lt;p&gt;However, the rendering of checkboxes is really inconsistent, so we've skipped these elements. Again, this kind of elements
seems to be &amp;quot;locked&amp;quot; by the default algorithms of most browsers.&lt;/p&gt;

&lt;h2&gt;Select&lt;/h2&gt;

&lt;p&gt;The styles for the &lt;code&gt;select&lt;/code&gt; element are really simple.&lt;/p&gt;

&lt;pre&gt;
select {
 font: 1em Verdana, sans-serif;
 vertical-align: middle;
 width: 95px;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/7/7.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As for the &lt;code&gt;input&lt;/code&gt; element, we've vertically aligned this element and specified the same
font family and size used above. In this case, Internet Explorer 7 (and lower) has some problems with
the specified width, so it needs the following code:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;!--[if lt IE 8]&amp;gt;
&amp;lt;style type=&amp;quot;text/css&amp;quot; media=&amp;quot;screen&amp;quot;&amp;gt;
select {width: 99px}
&amp;lt;/style&amp;gt;
&amp;lt;![endif]--&amp;gt;
&lt;/pre&gt;

&lt;p&gt;However, the rendering of the &lt;code&gt;option&lt;/code&gt; elements is really inconsistent, so we've skipped these elements. Again, this kind of elements
seems to be &amp;quot;locked&amp;quot; by the default algorithms of most browsers.&lt;/p&gt;

&lt;h2&gt;Textarea and submit button&lt;/h2&gt;

&lt;p&gt;These elements have the following styles:&lt;/p&gt;

&lt;pre&gt;
textarea {
 display: block;
 width: 100%;
 background: #fff;
 border: 1px solid #c00;
 font: 1em Verdana, sans-serif;
 overflow: auto;
}

input#btn {
 background: #c00;
 border: 1px solid #800;
 color: #fff;
 font-weight: bold;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/8/8.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;The &lt;code&gt;textarea&lt;/code&gt; element is an inline-block element, so we've declared it as a block-level
element. The declaration &lt;code&gt;overflow: auto&lt;/code&gt; should prevent browsers from showing the trackbar
for the vertical scrollbar, but this solution doesn't work in all cases. What's more, Internet Explorer
7 (and lower) has some problems with the correct calculation of the width of the element and it needs
the following code:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;!--[if lt IE 8]&amp;gt;
&amp;lt;style type=&amp;quot;text/css&amp;quot; media=&amp;quot;screen&amp;quot;&amp;gt;
textarea {width: 99%}
&amp;lt;/style&amp;gt;
&amp;lt;![endif]--&amp;gt;
&lt;/pre&gt;

&lt;h2&gt;Final result&lt;/h2&gt;

&lt;p&gt;Our &lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/final/final.html"&gt;final layout&lt;/a&gt; appears as follows in the four major browsers.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;div class="picture"&gt;
&lt;img src="http://www.css-zibaldone.com/articles/form-elements/img/firefox.png" alt="Firefox" /&gt;
&lt;p&gt;Firefox&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="picture"&gt;
&lt;img src="http://www.css-zibaldone.com/articles/form-elements/img/ie.png" alt="Internet Explorer" /&gt;
&lt;p&gt;Internet Explorer&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="picture"&gt;
&lt;img src="http://www.css-zibaldone.com/articles/form-elements/img/opera.png" alt="Opera" /&gt;
&lt;p&gt;Opera&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="picture"&gt;
&lt;img src="http://www.css-zibaldone.com/articles/form-elements/img/safari.png" alt="Safari" /&gt;
&lt;p&gt;Safari&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Download examples&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples.zip"&gt;examples.zip&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-6259059497409226742?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/9xyH1qsgWck" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/9xyH1qsgWck/css-how-to-style-form-elements.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/css-how-to-style-form-elements.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-857423399525164555</guid><pubDate>Sun, 22 Jan 2012 15:55:00 +0000</pubDate><atom:updated>2012-01-22T07:55:28.064-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">javascript</category><title>JavaScript syntax highlighting is bad for performance</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/01/syntax-highlighting.png" alt="" class="aligncenter spaced" /&gt;My visitor's satisfaction is one of the top priorities of this blog. For that reason, I decided to remove syntax highlighting completely. I found out that syntax highlighters are bad for performance. In fact, all the syntax highlighters tools used since the very beginning of this blog were actually poor when it comes to performance. Most of my visitors come from the USA, but there's a significant percentage of people who connect to this site from Asia. When the distance increases, it also affects latency and response times.  I'd like to explain why JavaScript syntax highlighters are bad for performance using very simple words.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;Too many GET requests&lt;/h2&gt;

&lt;p&gt;Generally speaking, a JavaScript syntax highlighter is made up of a single core file and several additional language files. Let's say that on your blog your main topics are CSS, JavaScript, HTML5 and PHP.&lt;/p&gt;

&lt;p&gt;Four languages mean four different language files, plus the main core file. The total of five JavaScript files forces a browser to perform five different GET requests.&lt;/p&gt;

&lt;p&gt;These additional requests, added to the overall amount of the HTTP requests of your site, result in an increased loading time of your pages. I didn't take the exact timing of such delays, but I reasonably think that they should be approximately of more that 5-10 seconds, especially on high-traffic web sites.&lt;/p&gt;

&lt;h2&gt;Poor string manipulation&lt;/h2&gt;

&lt;p&gt;In JavaScript, advanced string manipulation is handled by regular expressions (Perl-compatible, with some differences). Usually a syntax highlighter works on a target element by replacing its HTML content with new content created on the fly by searching and replacing some strings which have a special meaning for the code in use.&lt;/p&gt;

&lt;p&gt;For example, a DOM structure like the following:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;pre class=&amp;quot;js&amp;quot;&amp;gt;
function A() {}
&amp;lt;/pre&amp;gt;
&lt;/pre&gt;

&lt;p&gt;becomes:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;pre class=&amp;quot;js&amp;quot;&amp;gt;
&amp;lt;span class=&amp;quot;kwd&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; A() {}
&amp;lt;/pre&amp;gt
&lt;/pre&gt;

&lt;p&gt;This search-and-replace routine is performed several times on each code block on the page. To get an idea of the process behind syntax highlighting, you should measure the duration of a single routine, multiply it for the number of significant strings of each block and finally multiply the result for the number of blocks of a page.&lt;/p&gt;

&lt;h2&gt;DOM loading delays&lt;/h2&gt;

&lt;p&gt;Most of these routines take place on page loading. More specifically, the event used is &lt;code&gt;DOMContentReady&lt;/code&gt; or, if it's not available, the &lt;code&gt;load&lt;/code&gt; event of the &lt;code&gt;body&lt;/code&gt; element is used instead.&lt;/p&gt;

&lt;p&gt;The problem is that if your page contains several other assets, such as media elements or JavaScript widgets, DOM loading will be further delayed. In fact, syntax highlighters don't feature a really flexible way of handling the bootstrapping (so to speak) of the library, meaning that you cannot preload them without affecting the way by which your code blocks will be displayed.&lt;/p&gt;

&lt;p&gt;If you load a library too soon or too late, you won't see the CSS styles applied to your code blocks but only raw code.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-857423399525164555?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/2sJfZ3pQsb8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/2sJfZ3pQsb8/javascript-syntax-highlighting-is-bad.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>3</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/javascript-syntax-highlighting-is-bad.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-2522885338773339683</guid><pubDate>Sat, 21 Jan 2012 12:41:00 +0000</pubDate><atom:updated>2012-01-21T04:41:52.530-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: Mati, professional image gallery</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/07/matilde.jpg" alt="" class="aligncenter spaced" /&gt;&lt;cite&gt;Mati&lt;/cite&gt; is a professional jQuery image gallery that I've created as an homage to my little niece Matilde. It's a grid-based image gallery that allows you to navigate through the image sets and view the full-size image preview. It's free. The only thing you should do is to add an image preloading routine to improve performance. I hope you find it useful.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h3&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-mati-image-gallery/"&gt;Mati image gallery&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Download&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-mati-image-gallery/jquery-mati-image-gallery.zip"&gt;ZIP file&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-2522885338773339683?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/qA2hlmCf2-c" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/qA2hlmCf2-c/jquery-mati-professional-image-gallery.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/jquery-mati-professional-image-gallery.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-2579358297457191967</guid><pubDate>Sun, 08 Jan 2012 07:20:00 +0000</pubDate><atom:updated>2012-01-07T23:20:46.286-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">wordpress</category><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: the moreLink plugin for WordPress</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/08/wordpress_jquery.jpg" alt="" class="aligncenter spaced" /&gt;&lt;cite&gt;moreLink&lt;/cite&gt; is a jQuery plugin written by me that handles the 'More' links of a WordPress site by fetching the linked post via AJAX without refreshing the page.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;Base usage&lt;/h2&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
$('a.more-link').moreLink(options);
&lt;/pre&gt;

&lt;h2&gt;Options&lt;/h2&gt;

&lt;dl&gt;
&lt;dt&gt;&lt;code&gt;target&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;The CSS selector that identifies your post wrapper in the target page (e.g. &lt;code&gt;div.post&lt;/code&gt;).&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;parent&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;The outermost parent of the link in the current page.&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;loader&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;The full path to the animated GIF used while the fetched post is loading.&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;loaderStyles&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;The CSS styles given as an object to the &lt;code&gt;css()&lt;/code&gt; method to stylize the animated spinner.&lt;/dd&gt;
&lt;/dl&gt;

&lt;h2&gt;Demo&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="420" height="315" class="wide" src="http://www.youtube.com/embed/jUCgCfP7jzc?rel=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;

&lt;h3&gt;Download&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-plugin-more-link/jquery-plugin-more-link.zip"&gt;ZIP file&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-2579358297457191967?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/ppfkq4-YPV8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/ppfkq4-YPV8/jquery-morelink-plugin-for-wordpress.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/jUCgCfP7jzc/default.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/jquery-morelink-plugin-for-wordpress.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-8435711570057567245</guid><pubDate>Thu, 05 Jan 2012 08:46:00 +0000</pubDate><atom:updated>2012-01-05T00:46:42.591-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">blogger</category><title>Blogger: inserting social media buttons selectively</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/01/blogging.jpg" alt="" class="wide spaced" /&gt;Blogger already provides a way to include social media buttons on its pages but not selectively. We want that our social buttons appear only on posts and not on the homepage. Fortunately, Blogger also provides a series of tags (all starting with &lt;code&gt;b&lt;/code&gt;) to perform some specific tasks within a template. Let's see how we can accomplish this task.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;From &lt;cite&gt;Template&lt;/cite&gt;, select &lt;cite&gt;Edit HTML&lt;/cite&gt; and put the following conditional expression where you want the social buttons appear:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;b:if cond='data:blog.url != data:blog.homepageUrl'&amp;gt;

  &amp;lt;!-- social buttons code here --&amp;gt;

&amp;lt;/b:if&amp;gt;
&lt;/pre&gt;

&lt;p&gt;The above instruction checks whether the current URL is different from your homepage's URL. Then you can include your social buttons code within that conditional block, as follows:&lt;/p&gt;


&lt;pre class="prettyprint"&gt;
&amp;lt;b:if cond='data:blog.url != data:blog.homepageUrl'&amp;gt;

    &amp;lt;div class='share'&amp;gt;
&amp;lt;span class='twitter'&amp;gt;
&amp;lt;a class='twitter-share-button' data-lang='en' data-via='username' href='https://twitter.com/share'&amp;gt;Tweet&amp;lt;/a&amp;gt;
&amp;lt;script&amp;gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=&amp;quot;//platform.twitter.com/widgets.js&amp;quot;;fjs.parentNode.insertBefore(js,fjs);}}(document,&amp;quot;script&amp;quot;,&amp;quot;twitter-wjs&amp;quot;);&amp;lt;/script&amp;gt;
&amp;lt;/span&amp;gt;
&amp;lt;span class='google-plus'&amp;gt;
&amp;lt;g:plusone annotation='inline' size='small' width='120'/&amp;gt;
&amp;lt;script type='text/javascript'&amp;gt;
  (function() {
    var po = document.createElement(&amp;#39;script&amp;#39;); po.type = &amp;#39;text/javascript&amp;#39;; po.async = true;
    po.src = &amp;#39;https://apis.google.com/js/plusone.js&amp;#39;;
    var s = document.getElementsByTagName(&amp;#39;script&amp;#39;)[0]; s.parentNode.insertBefore(po, s);
  })();
&amp;lt;/script&amp;gt;
&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;/b:if&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Easy enough, isn't it?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-8435711570057567245?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/RQw0d9emeTk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/RQw0d9emeTk/blogger-inserting-social-media-buttons.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/blogger-inserting-social-media-buttons.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-9134349560794359442</guid><pubDate>Tue, 03 Jan 2012 11:34:00 +0000</pubDate><atom:updated>2012-01-03T03:34:38.142-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">css</category><title>The Book of CSS3</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/01/the-book-of-css3.jpg" alt="" class="wide spaced" /&gt;&lt;a href="http://shop.oreilly.com/product/9781593272869.do?sortby=publicationDate"&gt;The Book of CSS3&lt;/a&gt; is the most comprehensive and detailed guide ever written on the subject practically since the creation of this standard. I bought this book myself a couple of days ago and I have to say that I'm actually learning new things on CSS3. The author is &lt;cite&gt;Peter Gasston&lt;/cite&gt;, one of the people behind &lt;a href="http://www.css3.info/"&gt;CSS3.info&lt;/a&gt;. I'd like to explain why you should get this book.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;This book covers all the nuts and bolts of CSS3. I mean, all. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stylize text with fully customizable outlines, drop shadows, and other effects&lt;/li&gt;
&lt;li&gt;Create, position, and resize unlimited background images on the fly&lt;/li&gt; 
&lt;li&gt;Spice up static web pages with event-driven transitions and animations&lt;/li&gt;
&lt;li&gt;Apply 2D and 3D transformations to text and images&lt;/li&gt;
&lt;li&gt;Use linear and radial gradients to create smooth color transitions&lt;/li&gt;
&lt;li&gt;Tailor a website's appearance to smartphones and other devices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this book you won't need to google over and over searching for a tutorial because everything you need to know on CSS3 is already covered here. You'll become more independent and you'll be able to start testing and experimenting on your own.&lt;/p&gt;

&lt;p&gt;I definitely recommend this book.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-9134349560794359442?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/J7s11puwWqE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/J7s11puwWqE/book-of-css3.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/book-of-css3.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-6638781999679239483</guid><pubDate>Tue, 03 Jan 2012 10:25:00 +0000</pubDate><atom:updated>2012-01-03T02:25:16.297-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: how to split images on slideshows</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/01/split.jpg" class="wide spaced" alt="" /&gt;Splitting and dividing images on a jQuery slideshow is not so difficult as it could seem at a first glance. In fact, if you know the technique that works behind the scenes, you'll probably end up with realizing how this feature is simple in its implementation. In a nutshell: it's only a matter of layers and background images. Let's see the details.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;The markup&lt;/h2&gt;

&lt;p&gt;We have a very simple and common slideshow structure:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;div id=&amp;quot;slideshow&amp;quot;&amp;gt;
 &amp;lt;div id=&amp;quot;slideshow-wrapper&amp;quot;&amp;gt;
     &amp;lt;div class=&amp;quot;slide&amp;quot;&amp;gt;
   &amp;lt;img src=&amp;quot;img/1.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;slide&amp;quot;&amp;gt;
   &amp;lt;img src=&amp;quot;img/2.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;slide&amp;quot;&amp;gt;
   &amp;lt;img src=&amp;quot;img/3.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;slide&amp;quot;&amp;gt;
   &amp;lt;img src=&amp;quot;img/4.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;
  &amp;lt;/div&amp;gt;
 &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Each image is 1150 x 400 pixels wide. We have to create a grid made up of 40 blocks and 4 rows to be applied on each slide. Each row is made up of 10 blocks. In turn, each block is 115 x 100 pixels wide, so (115 x 10) and (100 x 4) give us the total image dimensions. Here comes the trick: each of these blocks will have the current image as its background image, but with different x and y values for the CSS &lt;code&gt;background-position&lt;/code&gt; property. Once set the blocks, it's easy to animate them with jQuery.&lt;/p&gt;

&lt;h2&gt;The CSS styles&lt;/h2&gt;

&lt;p&gt;Our CSS styles are as follows:&lt;/p&gt;

&lt;pre class="prettyprint lang-css"&gt;
#slideshow {
 margin: 2em auto;
 width: 90%;
 max-width: 1150px;
 height: 400px;
 border: 5px solid #565656;
 overflow: hidden;
 position: relative;
}

#slideshow-wrapper {
 width: 4600px;
 height: 400px;
 position: relative;
 background: #ccc;
}

#slideshow-wrapper img {
 width: 1150px;
 height: 400px;
 display: none;
}

div.slide {
 float: left;
 width: 1150px;
 height: 400px;
 position: relative;
}

div.overlay {
 width: 1150px;
 height: 400px;
 position: absolute;
 top: 0;
 left: 0;
}

div.row {
 height: 100px;
 position: relative;
}

div.piece {
 height: 100px;
 width: 115px;
 background-repeat: no-repeat;
 float: left;
 display: none;
}
&lt;/pre&gt;

&lt;h2&gt;The jQuery code&lt;/h2&gt;

&lt;p&gt;We start with a singleton object and we declare the properties and variables used throughout its namespace:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var Slideshow = new function() {

 var slideshow = document.getElementById('slideshow'),
  wrapper = $('#slideshow-wrapper', slideshow),
  slides = $('div.slide', wrapper),
  pieces = $('div.piece', slides),
  index = -1,
  timer = null;
  
  // continues

}();
&lt;/pre&gt;

&lt;p&gt;Then we split each slide into pieces using the following private method:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var Slideshow = new function() {

 var slideshow = document.getElementById('slideshow'),
  wrapper = $('#slideshow-wrapper', slideshow),
  slides = $('div.slide', wrapper),
  pieces = $('div.piece', slides),
  index = -1,
  timer = null;
  
 var insertBlocks = function() {
 
  slides.each(function() {
   
   var slide = $(this);
   
   $('&amp;lt;div class=&amp;quot;overlay&amp;quot;/&amp;gt;').appendTo(slide);
   
   var block = '&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;/div&amp;gt;';
   for(var i = 0; i &amp;lt; 4; i += 1) {
   
    $(block).appendTo($('div.overlay', slide));
   
   }
  
  });
 
 
 };

 // continues

}();
&lt;/pre&gt;

&lt;p&gt;Then we set the background images:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var Slideshow = new function() {

 var slideshow = document.getElementById('slideshow'),
  wrapper = $('#slideshow-wrapper', slideshow),
  slides = $('div.slide', wrapper),
  pieces = $('div.piece', slides),
  index = -1,
  timer = null;
  
 var insertBlocks = function() {
 
  slides.each(function() {
   
   var slide = $(this);
   
   $('&amp;lt;div class=&amp;quot;overlay&amp;quot;/&amp;gt;').appendTo(slide);
   
   var block = '&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;/div&amp;gt;';
   for(var i = 0; i &amp;lt; 4; i += 1) {
   
    $(block).appendTo($('div.overlay', slide));
   
   }
  
  });
 
 
 };

 var setBackgroundImages = function() {
 
      
 
  slides.each(function() {
  
   var slide = $(this);
   var src = $('img', slide).attr('src');
   var pieces = $('div.piece', slide);
   pieces.css('backgroundImage', 'url(' + src + ')');
   
   pieces.eq(0).css('backgroundPosition', '0px 0px');
   pieces.eq(1).css('backgroundPosition', '-115px 0px');
   pieces.eq(2).css('backgroundPosition', '-230px 0px');
   pieces.eq(3).css('backgroundPosition', '-345px 0px');
   pieces.eq(4).css('backgroundPosition', '-460px 0px');
   pieces.eq(5).css('backgroundPosition', '-575px 0px');
   pieces.eq(6).css('backgroundPosition', '-690px 0px');
   pieces.eq(7).css('backgroundPosition', '-805px 0px');
   pieces.eq(8).css('backgroundPosition', '-925px 0px');
   pieces.eq(9).css('backgroundPosition', '-1040px 0px');
   
   pieces.eq(10).css('backgroundPosition', '0px -100px');
   pieces.eq(11).css('backgroundPosition', '-115px -100px');
   pieces.eq(12).css('backgroundPosition', '-230px -100px');
   pieces.eq(13).css('backgroundPosition', '-345px -100px');
   pieces.eq(14).css('backgroundPosition', '-460px -100px');
   pieces.eq(15).css('backgroundPosition', '-575px -100px');
   pieces.eq(16).css('backgroundPosition', '-690px -100px');
   pieces.eq(17).css('backgroundPosition', '-805px -100px');
   pieces.eq(18).css('backgroundPosition', '-925px -100px');
   pieces.eq(19).css('backgroundPosition', '-1040px -100px');
   
   pieces.eq(20).css('backgroundPosition', '0px -200px');
   pieces.eq(21).css('backgroundPosition', '-115px -200px');
   pieces.eq(22).css('backgroundPosition', '-230px -200px');
   pieces.eq(23).css('backgroundPosition', '-345px -200px');
   pieces.eq(24).css('backgroundPosition', '-460px -200px');
   pieces.eq(25).css('backgroundPosition', '-575px -200px');
   pieces.eq(26).css('backgroundPosition', '-690px -200px');
   pieces.eq(27).css('backgroundPosition', '-805px -200px');
   pieces.eq(28).css('backgroundPosition', '-925px -200px');
   pieces.eq(29).css('backgroundPosition', '-1040px -200px');
   
   pieces.eq(30).css('backgroundPosition', '0px -300px');
   pieces.eq(31).css('backgroundPosition', '-115px -300px');
   pieces.eq(32).css('backgroundPosition', '-230px -300px');
   pieces.eq(33).css('backgroundPosition', '-345px -300px');
   pieces.eq(34).css('backgroundPosition', '-460px -300px');
   pieces.eq(35).css('backgroundPosition', '-575px -300px');
   pieces.eq(36).css('backgroundPosition', '-690px -300px');
   pieces.eq(37).css('backgroundPosition', '-805px -300px');
   pieces.eq(38).css('backgroundPosition', '-925px -300px');
   pieces.eq(39).css('backgroundPosition', '-1040px -300px');


   
   
     
  
  });
 
 
 };

 // continues
}();
&lt;/pre&gt;

&lt;p&gt;It's verbose but doing so is the best way to help you understand how it works. Now we have to animate the slideshow:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var Slideshow = new function() {

 var slideshow = document.getElementById('slideshow'),
  wrapper = $('#slideshow-wrapper', slideshow),
  slides = $('div.slide', wrapper),
  pieces = $('div.piece', slides),
  index = -1,
  timer = null;
  
 var insertBlocks = function() {
 
  slides.each(function() {
   
   var slide = $(this);
   
   $('&amp;lt;div class=&amp;quot;overlay&amp;quot;/&amp;gt;').appendTo(slide);
   
   var block = '&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;/div&amp;gt;';
   for(var i = 0; i &amp;lt; 4; i += 1) {
   
    $(block).appendTo($('div.overlay', slide));
   
   }
  
  });
 
 
 };

 var setBackgroundImages = function() {
 
      
 
  slides.each(function() {
  
   var slide = $(this);
   var src = $('img', slide).attr('src');
   var pieces = $('div.piece', slide);
   pieces.css('backgroundImage', 'url(' + src + ')');
   
   pieces.eq(0).css('backgroundPosition', '0px 0px');
   pieces.eq(1).css('backgroundPosition', '-115px 0px');
   pieces.eq(2).css('backgroundPosition', '-230px 0px');
   pieces.eq(3).css('backgroundPosition', '-345px 0px');
   pieces.eq(4).css('backgroundPosition', '-460px 0px');
   pieces.eq(5).css('backgroundPosition', '-575px 0px');
   pieces.eq(6).css('backgroundPosition', '-690px 0px');
   pieces.eq(7).css('backgroundPosition', '-805px 0px');
   pieces.eq(8).css('backgroundPosition', '-925px 0px');
   pieces.eq(9).css('backgroundPosition', '-1040px 0px');
   
   pieces.eq(10).css('backgroundPosition', '0px -100px');
   pieces.eq(11).css('backgroundPosition', '-115px -100px');
   pieces.eq(12).css('backgroundPosition', '-230px -100px');
   pieces.eq(13).css('backgroundPosition', '-345px -100px');
   pieces.eq(14).css('backgroundPosition', '-460px -100px');
   pieces.eq(15).css('backgroundPosition', '-575px -100px');
   pieces.eq(16).css('backgroundPosition', '-690px -100px');
   pieces.eq(17).css('backgroundPosition', '-805px -100px');
   pieces.eq(18).css('backgroundPosition', '-925px -100px');
   pieces.eq(19).css('backgroundPosition', '-1040px -100px');
   
   pieces.eq(20).css('backgroundPosition', '0px -200px');
   pieces.eq(21).css('backgroundPosition', '-115px -200px');
   pieces.eq(22).css('backgroundPosition', '-230px -200px');
   pieces.eq(23).css('backgroundPosition', '-345px -200px');
   pieces.eq(24).css('backgroundPosition', '-460px -200px');
   pieces.eq(25).css('backgroundPosition', '-575px -200px');
   pieces.eq(26).css('backgroundPosition', '-690px -200px');
   pieces.eq(27).css('backgroundPosition', '-805px -200px');
   pieces.eq(28).css('backgroundPosition', '-925px -200px');
   pieces.eq(29).css('backgroundPosition', '-1040px -200px');
   
   pieces.eq(30).css('backgroundPosition', '0px -300px');
   pieces.eq(31).css('backgroundPosition', '-115px -300px');
   pieces.eq(32).css('backgroundPosition', '-230px -300px');
   pieces.eq(33).css('backgroundPosition', '-345px -300px');
   pieces.eq(34).css('backgroundPosition', '-460px -300px');
   pieces.eq(35).css('backgroundPosition', '-575px -300px');
   pieces.eq(36).css('backgroundPosition', '-690px -300px');
   pieces.eq(37).css('backgroundPosition', '-805px -300px');
   pieces.eq(38).css('backgroundPosition', '-925px -300px');
   pieces.eq(39).css('backgroundPosition', '-1040px -300px');


   
   
     
  
  });
 
 
 };
 
 var autoSlide = function() {
     
 
  timer = setInterval(function() {
  
   index++;
   
   if(index == (slides.length - 1)) {
   
    index = -1;
   
   }
   
   
   wrapper.animate({
    left: - slides.eq(index).position().left
   }, 0, function() {
   
    var slide = slides.eq(index);
    var parts = $('div.piece', slide);
    var counter = -1;
    var slicer = null;
    
    slicer = setInterval(function() {
    
     counter++;
     
     if(counter == (parts.length)) {
     
      clearInterval(slicer);
      
      parts.fadeOut();
     
     }
     
     parts.eq(counter).fadeIn(75);
    
    
    }, 75); 
    
   
   
   });
  
  
  
  }, 3000);
 
 
 
 };


 // continues
}();
&lt;/pre&gt;

&lt;p&gt;Finally, we create an initialization public method:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var Slideshow = new function() {

 var slideshow = document.getElementById('slideshow'),
  wrapper = $('#slideshow-wrapper', slideshow),
  slides = $('div.slide', wrapper),
  pieces = $('div.piece', slides),
  index = -1,
  timer = null;
  
 var insertBlocks = function() {
 
  slides.each(function() {
   
   var slide = $(this);
   
   $('&amp;lt;div class=&amp;quot;overlay&amp;quot;/&amp;gt;').appendTo(slide);
   
   var block = '&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;div class=&amp;quot;piece&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' +
      '&amp;lt;/div&amp;gt;';
   for(var i = 0; i &amp;lt; 4; i += 1) {
   
    $(block).appendTo($('div.overlay', slide));
   
   }
  
  });
 
 
 };

 var setBackgroundImages = function() {
 
      
 
  slides.each(function() {
  
   var slide = $(this);
   var src = $('img', slide).attr('src');
   var pieces = $('div.piece', slide);
   pieces.css('backgroundImage', 'url(' + src + ')');
   
   pieces.eq(0).css('backgroundPosition', '0px 0px');
   pieces.eq(1).css('backgroundPosition', '-115px 0px');
   pieces.eq(2).css('backgroundPosition', '-230px 0px');
   pieces.eq(3).css('backgroundPosition', '-345px 0px');
   pieces.eq(4).css('backgroundPosition', '-460px 0px');
   pieces.eq(5).css('backgroundPosition', '-575px 0px');
   pieces.eq(6).css('backgroundPosition', '-690px 0px');
   pieces.eq(7).css('backgroundPosition', '-805px 0px');
   pieces.eq(8).css('backgroundPosition', '-925px 0px');
   pieces.eq(9).css('backgroundPosition', '-1040px 0px');
   
   pieces.eq(10).css('backgroundPosition', '0px -100px');
   pieces.eq(11).css('backgroundPosition', '-115px -100px');
   pieces.eq(12).css('backgroundPosition', '-230px -100px');
   pieces.eq(13).css('backgroundPosition', '-345px -100px');
   pieces.eq(14).css('backgroundPosition', '-460px -100px');
   pieces.eq(15).css('backgroundPosition', '-575px -100px');
   pieces.eq(16).css('backgroundPosition', '-690px -100px');
   pieces.eq(17).css('backgroundPosition', '-805px -100px');
   pieces.eq(18).css('backgroundPosition', '-925px -100px');
   pieces.eq(19).css('backgroundPosition', '-1040px -100px');
   
   pieces.eq(20).css('backgroundPosition', '0px -200px');
   pieces.eq(21).css('backgroundPosition', '-115px -200px');
   pieces.eq(22).css('backgroundPosition', '-230px -200px');
   pieces.eq(23).css('backgroundPosition', '-345px -200px');
   pieces.eq(24).css('backgroundPosition', '-460px -200px');
   pieces.eq(25).css('backgroundPosition', '-575px -200px');
   pieces.eq(26).css('backgroundPosition', '-690px -200px');
   pieces.eq(27).css('backgroundPosition', '-805px -200px');
   pieces.eq(28).css('backgroundPosition', '-925px -200px');
   pieces.eq(29).css('backgroundPosition', '-1040px -200px');
   
   pieces.eq(30).css('backgroundPosition', '0px -300px');
   pieces.eq(31).css('backgroundPosition', '-115px -300px');
   pieces.eq(32).css('backgroundPosition', '-230px -300px');
   pieces.eq(33).css('backgroundPosition', '-345px -300px');
   pieces.eq(34).css('backgroundPosition', '-460px -300px');
   pieces.eq(35).css('backgroundPosition', '-575px -300px');
   pieces.eq(36).css('backgroundPosition', '-690px -300px');
   pieces.eq(37).css('backgroundPosition', '-805px -300px');
   pieces.eq(38).css('backgroundPosition', '-925px -300px');
   pieces.eq(39).css('backgroundPosition', '-1040px -300px');


   
   
     
  
  });
 
 
 };
 
 var autoSlide = function() {
     
 
  timer = setInterval(function() {
  
   index++;
   
   if(index == (slides.length - 1)) {
   
    index = -1;
   
   }
   
   
   wrapper.animate({
    left: - slides.eq(index).position().left
   }, 0, function() {
   
    var slide = slides.eq(index);
    var parts = $('div.piece', slide);
    var counter = -1;
    var slicer = null;
    
    slicer = setInterval(function() {
    
     counter++;
     
     if(counter == (parts.length)) {
     
      clearInterval(slicer);
      
      parts.fadeOut();
     
     }
     
     parts.eq(counter).fadeIn(75);
    
    
    }, 75); 
    
   
   
   });
  
  
  
  }, 3000);
 
 
 
 };


 this.init = function() {
 
  insertBlocks();
  setBackgroundImages();
  autoSlide();
 
 };
}();
&lt;/pre&gt;

&lt;p&gt;And we kick things off:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
$(function() {

 Slideshow.init();

});
&lt;/pre&gt;

&lt;p&gt;You can see the demo below.&lt;/p&gt;

&lt;h3&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-scomposizione-avanzata-immagini-slideshow/"&gt;Live demo&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Download&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-scomposizione-avanzata-immagini-slideshow/jquery-scomposizione-avanzata-immagini-slideshow.zip"&gt;ZIP file&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-6638781999679239483?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/kc_JcgnQibM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/kc_JcgnQibM/jquery-how-to-split-images-on.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/jquery-how-to-split-images-on.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-4942245941346233696</guid><pubDate>Sat, 24 Dec 2011 10:55:00 +0000</pubDate><atom:updated>2011-12-24T02:55:59.533-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: closing gate effect on a slideshow</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/12/gate.jpg" alt="" class="wide spaced" /&gt;A closing gate-like effect on a jQuery slideshow takes only two opposite, positioned elements to be executed on each slide in order to show the current image. These two panels slide in opposite directions, thus creating the effect of a closing and opening gate. Let's see the details.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;We start with the following markup:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;div id=&amp;quot;slideshow&amp;quot;&amp;gt;
 &amp;lt;img src=&amp;quot;img/1.jpg&amp;quot; alt=&amp;quot;&amp;quot;/&amp;gt;
 &amp;lt;img src=&amp;quot;img/2.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;
 &amp;lt;img src=&amp;quot;img/3.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;
 &amp;lt;img src=&amp;quot;img/4.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;
 &amp;lt;div id=&amp;quot;panel-left&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
 &amp;lt;div id=&amp;quot;panel-right&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;And here are our CSS rules:&lt;/p&gt;

&lt;pre class="prettyprint lang-css"&gt;
#slideshow {
 margin: 2em auto;
 width: 650px;
 height: 430px;
 position: relative;
 overflow: hidden;
 border: 6px double #bbb;
}

#slideshow img {
 width: 650px;
 height: 430px;
 display: none;
}

#panel-left, #panel-right {
 width: 325px;
 height: 430px;
 background: #000;
 position: absolute;
 top: 0;
}

#panel-left {
 left: -325px;
}

#panel-right {
 right: -325px;
}
&lt;/pre&gt;

&lt;p&gt;As you can see, both panels are initially hidden by setting their offsets to negative values. Since their container has its &lt;code&gt;overflow&lt;/code&gt; property set to &lt;code&gt;hidden&lt;/code&gt;, they won't be visible until a jQuery action takes place.&lt;/p&gt;


&lt;p&gt;Here's our jQuery code:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var Slideshow = new function() {

 var slideshow = document.getElementById('slideshow'),
  images = $('img', slideshow),
  panelLeft = $('#panel-left', slideshow),
  panelRight = $('#panel-right', slideshow),
  index = -1,
  timer = null;
 
 var autoSlide = function() {
 
  timer = setInterval(function() {
  
   index++;
   
   if(index == (images.length - 1)) {
   
    index = -1;
    images.hide();
   
   }
   
   panelLeft.animate({
    left: 0
   }, 250);
   panelRight.animate({
    right: 0
   }, 250);
   panelLeft.animate({
    left: - 325
   }, 250);
   panelRight.animate({
    right: - 325
   }, 250);
   
   images.eq(index).fadeIn(1000).siblings('img').hide();
  
  
  }, 2000);
 
 };
 
 this.init = function() {
 
  autoSlide();
 
 };


}();

$(function() {

 Slideshow.init();

});
&lt;/pre&gt;

&lt;p&gt;We use a cyclic timer with a progressive internal counter to select the current image. Before showing the current image, both panels are first shown and then hidden again by adjusting their offsets. It's a pretty interesting effect to be added on a slideshow. You can see the demo below.&lt;/p&gt;

&lt;h3&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-effetto-apertura-chiusura-saracinesca-slideshow/"&gt;Live demo&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Download&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-effetto-apertura-chiusura-saracinesca-slideshow/jquery-effetto-apertura-chiusura-saracinesca-slideshow.zip"&gt;ZIP file&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-4942245941346233696?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/ykbK9qp4ID0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/ykbK9qp4ID0/jquery-closing-gate-effect-on-slideshow.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2011/12/jquery-closing-gate-effect-on-slideshow.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-2536200951713913594</guid><pubDate>Fri, 16 Dec 2011 09:27:00 +0000</pubDate><atom:updated>2011-12-17T00:27:17.043-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">usability</category><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: a usability lesson</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/12/usability-graph.jpg" alt="" class="wide spaced" /&gt;Why jQuery is one of the most used JavaScript libraries available on the web? Perhaps it has more features than other libraries or more flexibility. Perhaps its design is better conceived. Nothing like that: jQuery is a successful project simply because it has usability in mind. Usability is a too often neglected aspect of library development. jQuery fills this gap by providing a simple way to perform tasks that other libraries tend to make too complicated for the average user. That's the jQuery's secret.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;Usability and productivity&lt;/h2&gt;

&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/09/usability.jpg" alt="" class="wide spaced" /&gt;Developers want to be ready and productive as soon as possible. jQuery provides a simple interface to work with. Most JavaScript libraries tend to create a complex namespace hierarchy which is surely great from an OOP perspective, but it turns out to be difficult to remember and use when it comes to productivity.&lt;/p&gt;

&lt;p&gt;For example, to hide an element in Prototype you have to write the following:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
Element('test').hide();
&lt;/pre&gt;

&lt;p&gt;whereas in jQuery you have only to write a simpler line:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
$('#test').hide();
&lt;/pre&gt;

&lt;p&gt;jQuery uses CSS selectors to match DOM elements. This is really, really useful because even beginners can actually start to work with this library only knowing CSS and a little of JavaScript, whereas other libraries require that a user must have a firm knowledge of JavaScript and the DOM.&lt;/p&gt;

&lt;p&gt;Also chaining is a vital aspect of jQuery's usability: instead of using a syntax like this:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
Library.namespace.method(element, function() {

 //...

});
&lt;/pre&gt;

&lt;p&gt;you can use the following:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
$('#test').addClass('test').find('p').removeClass('para');
&lt;/pre&gt;

&lt;p&gt;Event the method and property names used by jQuery is intuitive and easy: &lt;code&gt;bind()&lt;/code&gt; is easy to understand and remember, but what exactly &lt;code&gt;Event.observe()&lt;/code&gt; does? And what is its exact syntax?&lt;/p&gt;

&lt;p&gt;The more a namespace hierarchy gets complex and deeper, the more is difficult to remember and use.&lt;/p&gt;

&lt;h2&gt;Hiding the DOM&lt;/h2&gt;

&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/10/dom-tree.gif" alt="" class="spaced" /&gt;DOM methods and properties are generally verbose and inconsistent across browsers. jQuery succeeds in hiding the underlying DOM procedures and structures by providing some really useful methods to work with the DOM without knowing all the nuts and bolts of the DOM:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;CSS selectors&lt;/li&gt;
&lt;li&gt;DOM traversing methods&lt;/li&gt;
&lt;li&gt;DOM manipulation methods&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By hiding the underlying DOM structure to the average user, jQuery aids usability with a simple interface that is very easy to understand even for the absolute beginner:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
$('#test').prev().wrap('&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;').end().find('p').wrapAll('&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;');
&lt;/pre&gt;

&lt;h2&gt;Extensibility&lt;/h2&gt;

&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/08/wordpress-plugins.jpg" alt="" class="spaced" /&gt;Unless other libraries, jQuery is fully extensible through plugins. From a pure user perspective, this is really handy. In fact, jQuery itself cannot encompass all the possible use cases that you may encounter during the development process of a web site.&lt;/p&gt;

&lt;p&gt;Extending jQuery is easy:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
(function($) {

 $.fn.plugin = function(options) {
 
  options = $.extend({
   option1: defaultValue1,
   option2: defaultValue2,
   optionN: //...
  }, options);
  
  return this.each(function() {
  
   //...
  
  
  });
 
 };

})(jQuery);
&lt;/pre&gt;

&lt;p&gt;The way by which jQuery handles plugins is very simple in itself: once defined, your plugin is available on all elements in the set, unless you restrict its usage only on a particular element.&lt;/p&gt;

&lt;h2&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;jQuery is a great example of how JavaScript library development meets usability to provide users with some tools which are not only powerful in their design, but also easy to use.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-2536200951713913594?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/K2sDPBdlJRs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/K2sDPBdlJRs/jquery-usability-lesson.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2011/12/jquery-usability-lesson.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-3443046701954561855</guid><pubDate>Wed, 14 Dec 2011 11:16:00 +0000</pubDate><atom:updated>2011-12-14T03:16:52.868-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: using timers with animations</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/12/sequence.jpg" alt="" class="wide spaced" /&gt;JavaScript timers constitute the inner engine of any good automated jQuery slideshow. Although timers can be really handy in most situations and case-scenarios, their rules are somewhat obscure to many developers. The point is that timers can be used in a wide range of use cases, not only in animations. For that reason, you should understand how timers work when applied to jQuery animations before developing any practical implementation that makes use of them.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;Delays: setTimeout()&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;setTimeout()&lt;/code&gt; method is primarily used to create a delay between an action and the subsequent one or to prevent an action from being executed immediately:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
function appear(element) {

 $(element).fadeIn(1000); 

}

setTimeout(function() {

 appear('#test');

}, 1000);
&lt;/pre&gt;

&lt;p&gt;This is a wait-and-go action: the timer delays the execution of the function for one second (1,000 milliseconds) but the function itself uses an effect whose duration is of another second. Globally, the whole action takes 2 seconds to finish its task.&lt;/p&gt;

&lt;p&gt;As a rule of thumb, you should always add up the duration of your animation to the overall duration of the timer you're using. By doing this, you have the exact duration of the entire action.&lt;/p&gt;

&lt;p&gt;Delays can be applied on many scenarios. One of the most interesting examples is the animation chain created through deferred objects:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
$.Deferred(function(def) {

 def.pipe(function() {
 
  return $('#a').animate({
   left: 100
  }, 1000);
 
 }).pipe(function() {
 
  return setTimeout(function() {
  
   $('#b').animate({
    left: 200
   }, 1000);
  
  }, 1000);
 
 });


}).resolve();
&lt;/pre&gt;

&lt;p&gt;The second animation must wait until the first one is complete. Since the first animation has a duration of 1,000 milliseconds, then the timer must have a delay of exactly 1,000 milliseconds to create the effect of an animation chain where every animation follows the previous one. If you don't do so, both animations will start simultaneously.&lt;/p&gt;

&lt;p&gt;Speaking of delays, another practical application can be found in the dropdown menu handling where you can prevent a submenu from disappearing too fast:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
$('ul.sub-menu').mouseleave(function() {

    var $menu = $(this);

 setTimeout(function() {
 
  $menu.slideUp(800); 
 
 }, 500);

});
&lt;/pre&gt;

&lt;h2&gt;Intervals: setInterval()&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;setInterval()&lt;/code&gt; has exactly the same syntax as &lt;code&gt;setTimeout()&lt;/code&gt;. The main difference between these two methods is that &lt;code&gt;setInterval()&lt;/code&gt; creates a cyclic timer whose execution is virtually infinite if you don't stop it once it has reached a certain limit:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var timer = setInterval(function() {

 index++;
 
 if(index == limit) {
 
  index = 0;
 
 }

}, 1000);
&lt;/pre&gt;

&lt;p&gt;In this case the inner counter is incremented by 1 every second. When the counter reaches its limit (say, 5), it will be reset to 0 so that the cycle can start again. And so on.&lt;/p&gt;

&lt;p&gt;This method can be useful on automated slideshows:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var autoSlide = function() {

 timer = setInterval(function() {
 
  index++;
  
  if(index == slides.length) {
  
   index = 0;
  
  }
  
  var position = slides.eq(index).position().left;
  
  wrapper.animate({
   left: - position
  }, 1000);
 
 }, 1000);


};
&lt;/pre&gt;

&lt;p&gt;Be careful with the duration of your animations within a timer: you should always make sure that the overall duration of your animations match the duration of the interval defined by the timer (in this case, 1 second for both the animation and the interval).&lt;/p&gt;

&lt;p&gt;For that reason, &lt;code&gt;setInterval()&lt;/code&gt; is not very practical when you have to deal with multiple animations, because you'll probably end up with an interval that is too long for your needs. Nicholas Zakas proposes the following alternate solution:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
timer = setTimeout(function() {

 // various animations that last 5,000 milliseconds
 
 setTimeout(arguments.callee, 5000);

}, 1000);
&lt;/pre&gt;

&lt;p&gt;The above timer will also repeat itself because of the second call to &lt;code&gt;setTimeout()&lt;/code&gt; but with a significant difference: you have only to wait one second between each execution whereas &lt;code&gt;setInterval()&lt;/code&gt; requires you to wait 5 seconds.&lt;/p&gt;

&lt;h2&gt;Clearing timers and animations&lt;/h2&gt;

&lt;p&gt;To clear the aforementioned methods you can use &lt;code&gt;clearTimeout()&lt;/code&gt; and &lt;code&gt;clearInterval()&lt;/code&gt;, respectively. Is that all? Unfortunately not, because you have also to clear the animation queue.&lt;/p&gt;

&lt;p&gt;Consider this example: you have a jQuery slideshow which features both an autosliding effect and navigation buttons. When you click on a button, you should stop the automatic sliding effect:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
$('#prev').click(function(event) {

 clearInterval(timer);
 timer = null;
 
 var position = slides.eq(index).position().left; // index belongs to the global namespace of your slideshow
 
 wrapper.animate({
  left: - position
 }, 1000, autoSlide);

 event.preventDefault();

});
&lt;/pre&gt;

&lt;p&gt;Once the action bound to the button is complete, you can restart your timer. But this is not enough. In fact, if you click twice on that button, everything will fall apart. That's because the animation queue is still active. You have to reset it as well:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
$('#prev').click(function(event) {

 clearInterval(timer);
 timer = null;
 $(':animated', slideshow).clearQueue();
 
 var position = slides.eq(index).position().left; // index belongs to the global namespace of your slideshow
 
 wrapper.animate({
  left: - position
 }, 1000, autoSlide);

 event.preventDefault();

});
&lt;/pre&gt;

&lt;p&gt;By doing so, you've normalized everything so you can start with a clean slate again.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-3443046701954561855?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/bU_fshbOeys" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/bU_fshbOeys/jquery-using-timers-with-animations.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2011/12/jquery-using-timers-with-animations.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-8192760036682576510</guid><pubDate>Wed, 30 Nov 2011 12:08:00 +0000</pubDate><atom:updated>2011-11-30T04:09:03.088-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery slideLeft plugin</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/11/jquery-tshirt.jpg" alt="" class="wide spaced" /&gt;jQuery doesn't provide natively a method to slide an element from left to right, so here's a lightweight and simple plugin to accomplish this task. &lt;code&gt;slideLeft()&lt;/code&gt; is intelligent enough to calculate the width of an element by referencing it to the width of its parent element and animate such property accordingly. I hope you find it useful.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h3&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-plugin-slideleft/"&gt;Live demo&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Download&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-plugin-slideleft/jquery-plugin-slideleft.zip"&gt;ZIP file&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-8192760036682576510?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/MpdAMW6kezc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/MpdAMW6kezc/jquery-slideleft-plugin.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2011/11/jquery-slideleft-plugin.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-4259058013558228771</guid><pubDate>Tue, 29 Nov 2011 11:23:00 +0000</pubDate><atom:updated>2011-11-29T03:24:07.651-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: scanner effect on a slideshow</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/images/jquery.png" alt="" class="alignright" /&gt;An interesting effect that we can achieve with jQuery on a slideshow is the scanner effect. Basically, it's simply a vertical bar that moves from left to right on each slide. The effect is even more interesting if we use an expanding movement on each slide. Let's see how.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;We start with the following markup:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;div id=&amp;quot;slideshow&amp;quot;&amp;gt;
 &amp;lt;div id=&amp;quot;slideshow-wrapper&amp;quot;&amp;gt;
  &amp;lt;img src=&amp;quot;img/1.jpg&amp;quot; alt=&amp;quot;Alba tra gli alberi&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;img/2.jpg&amp;quot; alt=&amp;quot;Natura morta con conchiglia&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;img/3.jpg&amp;quot; alt=&amp;quot;Natura morta con conchiglia 2&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;img/4.jpg&amp;quot; alt=&amp;quot;Battigia e conchiglie&amp;quot; /&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;div id=&amp;quot;slideshow-cursor&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;slideshow-cursor&lt;/code&gt; is our bar. We'll use CSS contextual positioning to prepare our layout:&lt;/p&gt;

&lt;pre class="prettyprint lang-css"&gt;
#slideshow {
 width: 600px;
 height: 400px;
 position: relative;
 overflow: hidden;
 border: 5px solid #222;
 border-radius: 5px;
 margin: 2em auto;
}

#slideshow-wrapper {
 width: 600px;
 height: 400px;
 position: relative;
 overflow: hidden;
 background: #bbb;
}

#slideshow-wrapper img {
 height: 400px;
 width: 0px;
 display: none;
}

#slideshow-cursor {
 position: absolute;
 top: 0;
 width: 30px;
 height: 400px;
 left: 0;
 z-index: 1;
 background: #333;
 display: none;
}
&lt;/pre&gt;

&lt;p&gt;Notice how all the images have also a zeroed width. This will allow us to create an expanding effect from left to right. Now jQuery:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var Slider = new function() {


 var slideshow = document.getElementById('slideshow'),
     wrapper = $('#slideshow-wrapper', slideshow),
     images = $('img', wrapper),
     cursor = $('#slideshow-cursor', slideshow),
     timer = null,
     index = -1;
     
 var prepare = function() {
 
  cursor.css('opacity', 0.5);
 
 };
 
 var autoSlide = function() {
 
  timer = setInterval(function() {
  
   index++;
   
   if(index == (images.length -1)) {
   
    index = -1;
   
   }
   
   var img = images.eq(index);
   
   
   img.show()
   .animate({
    width: 600
   }, 1500, function() {
   
    cursor.show().
   animate({
    left: 570
   }, 1500, 
      function() {
      
        $(this).hide().
        css('left', 0);
        
        img.hide().
     css('width', '0px');
      
   });
   
     
   
   
   });
   
   
   
  
  
  }, 3000);
 
 };
 
 this.init = function() {
 
  prepare();
  autoSlide();
 
 };

}();

$(function() {

 Slider.init();

});
&lt;/pre&gt;

&lt;p&gt;The scanner bar and the current image are first revealed: the image will expand in width, while the scanner bar will change its position moving towards right. Once both animations are complete, we reset all the CSS properties involved in the animations and we hide again the elements.&lt;/p&gt;

&lt;p&gt;You can see the demo below.&lt;/p&gt;


&lt;h3&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-slideshow-immagini-effetto-scanner/"&gt;Live demo&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Download&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-slideshow-immagini-effetto-scanner/jquery-slideshow-immagini-effetto-scanner.zip"&gt;ZIP file&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-4259058013558228771?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/sa8mWXWcRmA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/sa8mWXWcRmA/jquery-scanner-effect-on-slideshow.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2011/11/jquery-scanner-effect-on-slideshow.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-5544717544431463021</guid><pubDate>Fri, 25 Nov 2011 16:53:00 +0000</pubDate><atom:updated>2011-11-25T08:54:10.158-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><category domain="http://www.blogger.com/atom/ns#">css</category><title>Pure CSS3 content slider</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/images/css.png" alt="" class="alignright" /&gt;My friend Francesca has recently started 
&lt;a href="http://www.noiragazze.it/"&gt;her web site&lt;/a&gt; which features a nice content slider on the home page. I decided to create a similar slider using jQuery, but I soon realized that the main effect could be actually achieved using only CSS3 transitions. Let's see how.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;First, our markup:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;div id=&amp;quot;slideshow&amp;quot;&amp;gt;
 &amp;lt;div class=&amp;quot;slide s1&amp;quot;&amp;gt;
  &amp;lt;img src=&amp;quot;img/1.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;
  &amp;lt;div class=&amp;quot;caption&amp;quot;&amp;gt;1. Lorem ipsum dolor sit amet&amp;lt;/div&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;div class=&amp;quot;slide s2&amp;quot;&amp;gt;
  &amp;lt;img src=&amp;quot;img/2.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;
  &amp;lt;div class=&amp;quot;caption&amp;quot;&amp;gt;2. Lorem ipsum dolor sit amet&amp;lt;/div&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;div class=&amp;quot;slide s3&amp;quot;&amp;gt;
  &amp;lt;img src=&amp;quot;img/3.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;
  &amp;lt;div class=&amp;quot;caption&amp;quot;&amp;gt;3. Lorem ipsum dolor sit amet&amp;lt;/div&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;div class=&amp;quot;slide s4&amp;quot;&amp;gt;
  &amp;lt;img src=&amp;quot;img/4.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;
  &amp;lt;div class=&amp;quot;caption&amp;quot;&amp;gt;4. Lorem ipsum dolor sit amet&amp;lt;/div&amp;gt;
 &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Each slide has a different left offset within the main container, so we'll use contextual positioning. We also need to register our transition on each slide:&lt;/p&gt;

&lt;pre class="prettyprint lang-css"&gt;
#slideshow {
 width: 500px;
 height: 330px;
 margin: 2em auto;
 overflow: hidden;
 position: relative;
 background: #ccc;
 border: 1px solid #000;
}

#slideshow div.slide {
 width: 500px;
 height: 330px;
 position: absolute;
 top: 0;
 cursor: pointer;
 z-index: 1;
 -moz-transition: all 1s ease-out;
 -webkit-transition: all 1s ease-out;
 -o-transition: all 1s ease-out;
 -ms-transition: all 1s ease-out;
 transition: all 1s ease-out;
}

#slideshow div.slide img {
 position: absolute;
 top: 0;
 left: 0;
 width: 500px;
 height: 330px;
}

#slideshow div.slide div.caption {
 height: 2em;
 width: 100%;
 position: absolute;
 bottom: 0;
 left: 0;
 background: rgba(0, 0, 0, 0.5);
 color: #fff;
 line-height: 2;
 text-indent: 0.5em;
}

#slideshow div.s1 {
 left: 100px;
}
#slideshow div.s2 {
 left: 200px;
}
#slideshow div.s3 {
 left: 300px;
}
#slideshow div.s4 {
 left: 400px;
}
&lt;/pre&gt;

&lt;p&gt;On &lt;code&gt;:hover&lt;/code&gt;, we only have to change the &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;z-index&lt;/code&gt; property on each slide. Here is where the magic of CSS3 transitions takes place:&lt;/p&gt;

&lt;pre class="prettyprint lang-css"&gt;
#slideshow div.slide:hover {
 left: 0;
 z-index: 2;
}
&lt;/pre&gt;

&lt;p&gt;You can see the demo below.&lt;/p&gt;

&lt;h3&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/css/slideshow-css3/"&gt;Live demo&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Download&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/css/slideshow-css3/slideshow-css3.zip"&gt;ZIP file&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-5544717544431463021?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/vYkAti9e1mE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/vYkAti9e1mE/pure-css3-content-slider.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2011/11/pure-css3-content-slider.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-1658991915700576663</guid><pubDate>Fri, 25 Nov 2011 09:41:00 +0000</pubDate><atom:updated>2011-11-25T01:41:37.887-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><category domain="http://www.blogger.com/atom/ns#">css</category><title>jQuery: a slideshow with a side navigation menu</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/images/jquery.png" alt="" class="alignright" /&gt;I always take inspiration from desktop applications to create new jQuery demos. In this post I'd like to show you how to create an image slideshow which features a vertical thumbnail-based menu on its left side. This menu is initially hidden and it will be shown by clicking on a tab. Let's see the details.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;The markup&lt;/h2&gt;

&lt;p&gt;The underlying HTML structure is as follows:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;div id=&amp;quot;slideshow&amp;quot;&amp;gt;
 &amp;lt;div id=&amp;quot;slideshow-wrapper&amp;quot;&amp;gt;
  &amp;lt;img src=&amp;quot;img/1.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s1&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;img/2.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s2&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;img/3.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s3&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;img/4.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s4&amp;quot; /&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;ul id=&amp;quot;slideshow-nav&amp;quot;&amp;gt;
  &amp;lt;li&amp;gt;
   &amp;lt;a href=&amp;quot;#s1&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;img/1-thumb.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;
  &amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;
   &amp;lt;a href=&amp;quot;#s2&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;img/2-thumb.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;
  &amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;
   &amp;lt;a href=&amp;quot;#s3&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;img/3-thumb.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;
  &amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;
   &amp;lt;a href=&amp;quot;#s4&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;img/4-thumb.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;
  &amp;lt;/li&amp;gt;
 &amp;lt;/ul&amp;gt;
 &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;open&amp;quot;&amp;gt;Apri&amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;We have three main elements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;slideshow-wrapper&lt;/code&gt;: the full-width image container&lt;/li&gt;
&lt;li&gt;&lt;code&gt;slideshow-nav&lt;/code&gt;: the thumbnail-based vertical menu&lt;/li&gt;
&lt;li&gt;&lt;code&gt;open&lt;/code&gt;: the tab for showing/hiding the menu&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;The CSS&lt;/h2&gt;

&lt;p&gt;Our CSS design is all based on contextual positioning:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
#slideshow {
 width: 700px;
 height: 400px;
 position: relative;
 margin: 0 auto;
 overflow: hidden;
}

#slideshow-wrapper {
 width: 2400px;
 height: 400px;
 position: absolute;
 left: 100px;
 z-index: 3;
}

#slideshow-wrapper img {
 float: left;
 width: 600px;
 height: 400px;
 position: relative;
}

#slideshow-nav {
 width: 100px;
 height: 276px;
 margin: 0;
 padding: 0;
 list-style: none;
 position: absolute;
 top: 50%;
 margin-top: -138px;
 left: 100px;
 z-index: 2;
}

#slideshow-nav li,
#slideshow-nav li a,
#slideshow-nav li a img {
 display: block;
 width: 100%;
}

#open {
 display: block;
 width: 18px;
 height: 150px;
 background: url(img/open-off.png) no-repeat;
 text-indent: -1000em;
 position: absolute;
 top: 50%;
 left: 82px;
 margin-top: -75px;
 z-index: 2;
}

#open:hover {
 background: url(img/open-on.png) no-repeat;
}
&lt;/pre&gt;

&lt;p&gt;We've used z-index to initially hide the vertical menu just behind the main image wrapper. Bear in mind that an element with a greater z-index value will be always displayed on the top of another element with a lower z-index value.&lt;/p&gt;

&lt;h2&gt;The jQuery code&lt;/h2&gt;

&lt;p&gt;We have to associate a sliding action to each thumbnail link and a show/hide effect to the tab control:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var Slider = {

 slide: function() {
 
  $('a', '#slideshow-nav').each(function() {
  
   var $a = $(this);
   var href = $a.attr('href');
   var $img = $(href);
   var left = $img.position().left;
   
   $a.click(function(event) {
   
       $('img', '#slideshow-wrapper').not($img).css('left', 0);
   
    $img.animate({
     left: - left
    }, 1000);
    
    event.preventDefault();
   
   });
  
  
  });
 
 
 },
 
 control: function() {
 
  var $control = $('#open', '#slideshow');
  var $nav = $('#slideshow-nav', '#slideshow');
  
  $control.click(function(event) {
  
   if(parseInt($nav.css('left')) == 100) {
   
    $nav.animate({
     left: 0
    }, 1000); 
   
   } else {
   
    $nav.animate({
     left: 100
    }, 1000);
   
   }
  
  
   event.preventDefault();
  
  });
 
 
 },
 
 init: function() {
 
  this.slide();
  this.control();
 
 
 }

};

$(function() {

 Slider.init();

});
&lt;/pre&gt;

&lt;p&gt;Each link has an anchor which is equal to the corresponding ID of the current image, so we'll use this anchor to select the images. The action on the tab control is different: here we have to check whether the vertical menu is actually positioned behind the main image wrapper by testing its &lt;code&gt;left&lt;/code&gt; property to see if its current value is 100 or not. After testing this value, we can finally show or hide the menu.&lt;/p&gt;

&lt;p&gt;You can see the demo below.&lt;/p&gt;


&lt;h3&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-slideshow-navigazione-comparsa-laterale/"&gt;Live demo&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Download&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-slideshow-navigazione-comparsa-laterale/jquery-slideshow-navigazione-comparsa-laterale.zip"&gt;ZIP file&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-1658991915700576663?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/k0KaGNMEY_A" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/k0KaGNMEY_A/jquery-slideshow-with-side-navigation.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>2</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2011/11/jquery-slideshow-with-side-navigation.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-7958657723344370248</guid><pubDate>Fri, 25 Nov 2011 08:49:00 +0000</pubDate><atom:updated>2011-11-25T00:51:18.998-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">css</category><title>CSS: fluid grid systems</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/11/css-grid.png" alt="" class="wide spaced" height="360" /&gt;I'm currently testing some of the recent and new possibilities offered by &lt;a href="http://www.thegridsystem.org/"&gt;CSS grids&lt;/a&gt; and I have to say that I still haven't found what I'm looking for. Most of these grids are based on fixed sizes, meaning that the current base grid is made up of lengths measured in pixels. Pixels are a bad approach to CSS design because this approach actually doesn't take into account the problem of screen resolution. In fact, a 960 pixels grid system fails spectacularly on the most recent versions of PC and Mac monitors: simply put, it doesn't fill well the screen. A better approach is to use percentages. Let's see how.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;How percentages work&lt;/h2&gt;

&lt;p&gt;Percentages in CSS are calculated by taking the width and height of the parent element as a reference. The base value is always 100%. For example, if you want to have five boxes on the same line, you could write something like this:&lt;/p&gt;

&lt;pre class="prettyprint lang-css"&gt;
#container {
 width: 100%; 
}

div.box {
 display: inline-block;
 width: 20%;
}
&lt;/pre&gt;

&lt;p&gt;20 multiplied by 5 gives 100, so you have five boxes that fill completely the width of their parent element. On the other hand, heights work better when they're previously defined on the parent element:&lt;/p&gt;

&lt;pre class="prettyprint lang-css"&gt;
#container {
 width: 100%;
 height: 200px; 
}

div.box {
 display: inline-block;
 width: 20%;
 height: 90%;
}
&lt;/pre&gt;

&lt;p&gt;In this case, 90% must be calculated by taking 200 pixels as its reference.&lt;/p&gt;

&lt;h2&gt;Using minimum and maximum lengths&lt;/h2&gt;

&lt;p&gt;CSS provides four powerful properties that can be combined with percentages, namely:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;min-width&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max-width&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;min-height&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max-height&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can use these properties to keep your layout proportions when the screen resolution is too high or too low. Example:&lt;/p&gt;

&lt;pre class="prettyprint lang-css"&gt;
#site {
 width: 90%;
 margin: 0 auto;
 max-width: 1000px;
 min-width: 700px;
}
&lt;/pre&gt;

&lt;p&gt;This technique is widely used by some of the newest WordPress themes, including TwentyEleven. It simply tells browsers that the overall width of the main container should not exceed 1000 pixels and should not be less than 700 pixels. Try to resize the browser's window to see the effect.&lt;/p&gt;

&lt;h2&gt;Rounding problems&lt;/h2&gt;

&lt;p&gt;Suppose that you have a container with three floated boxes inside. You want to equally redistribute the horizontal space so that all the boxes fit their container's width:&lt;/p&gt;

&lt;pre class="prettyprint lang-css"&gt;
#container {
 width: 100%;
 overflow: hidden;
}

div.box {
 float: left;
 width: 33.3%;
}
&lt;/pre&gt;

&lt;p&gt;33.3 multiplied by 3 gives 99.9, but you can use more decimal points if you want. The problem with all this rounding is that some versions of Internet Explorer (namely 6 and 7) tend to round up your values. The final result in these browsers is rather ugly: floated boxes are pushed on the next line. To fix this, always remember to round down your values for IE 6 and 7.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-7958657723344370248?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/iGiO9gFKxDo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/iGiO9gFKxDo/css-fluid-grid-systems.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2011/11/css-fluid-grid-systems.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-2351800466789573334</guid><pubDate>Thu, 24 Nov 2011 09:43:00 +0000</pubDate><atom:updated>2011-11-24T01:44:44.504-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: expanding tabs content slider</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/images/jquery.png" alt="" class="alignright" /&gt;I recently had to modify the &lt;a href="http://themeforest.net/item/ventura-wordpress-corporate-business-theme/378380?WT.ac=category_item&amp;WT.seg_1=category_item&amp;WT.z_author=OllieMcCarthy"&gt;Ventura&lt;/a&gt; WordPress theme which features an interesting content slider based on expanding tabs. I decided to recreate the basic expanding effect of the tabs with a simple combination of jQuery and CSS. Let's see the results.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;We start with the following markup:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;div id=&amp;quot;slideshow&amp;quot;&amp;gt;
 &amp;lt;div id=&amp;quot;slideshow-wrapper&amp;quot;&amp;gt;
  &amp;lt;img src=&amp;quot;img/1.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s1&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;img/2.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s2&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;img/3.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s3&amp;quot; /&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;div id=&amp;quot;slides&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;slide&amp;quot;&amp;gt;
   &amp;lt;h3&amp;gt;Titolo 1&amp;lt;/h3&amp;gt;
   &amp;lt;p&amp;gt;Lorem ipsum dolor sit amet.&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;slide&amp;quot;&amp;gt;
   &amp;lt;h3&amp;gt;Titolo 2&amp;lt;/h3&amp;gt;
   &amp;lt;p&amp;gt;Lorem ipsum dolor sit amet.&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;slide&amp;quot;&amp;gt;
   &amp;lt;h3&amp;gt;Titolo 3&amp;lt;/h3&amp;gt;
   &amp;lt;p&amp;gt;Lorem ipsum dolor sit amet.&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
 &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Each tab should be initially visible only in its top section (the heading). Then, when a user clicks on the heading's icon, the tab expands vertically and shows the corresponding image. Here's the CSS:&lt;/p&gt;

&lt;pre class="prettyprint lang-css"&gt;
#slideshow {
 margin: 2em auto;
 width: 980px;
 height: 740px;
 position: relative;
 overflow: hidden;
}

#slideshow-wrapper {
 width: 2940px;
 height: 740px;
 position: absolute;
 top: 0;
 left: 0;
 z-index: 1;
 background: #ddd;
}

#slideshow-wrapper img {
 float: left;
 width: 980px;
 height: 740px;
 display: none;
}

#slides {
 width: 980px;
 height: 740px;
 position: absolute;
 top: 0;
 left: 0;
 z-index: 2;
 overflow: hidden;
}

div.slide {
 width: 200px;
 float: left;
 font: 90% Arial, sans-serif;
 position: relative;
 top: 721px;
 margin-left: 100px;
}

div.slide h3 {
 margin: 0;
 font-size: 18px;
 background-color: #fff;
 background-image: url(img/arrows.png); 
 background-repeat: no-repeat; 
 background-position: 100% 0;
 color: #c30;
 height: 18px;
 cursor: pointer;
 padding: 0 5px;
 border: 1px solid #999;
 border-radius: 5px 5px 0 0;
}

div.slide h3.active {
 background-position: 100% 100%;
}

div.slide p {
 margin: 0;
 padding: 1em;
 line-height: 1.3;
 background: #000;
 color: #fff;
}
&lt;/pre&gt;

&lt;p&gt;Each &lt;code&gt;slide&lt;/code&gt; element is pushed outside the content's area by adjusting its &lt;code&gt;top&lt;/code&gt; property. Since the container has the declaration &lt;code&gt;overflow: hidden&lt;/code&gt;, the exceeding content will be always kept hidden.&lt;/p&gt;

&lt;p&gt;With jQuery we have only to associate an expanding/revealing action to each tab's heading. At the same time, we have also to prevent the other slides from overlapping the current one:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var Slider = new function() {

 var wrapper = $('#slideshow-wrapper', '#slideshow');
 var images = $('img', wrapper);
 var slides = $('#slides', '#slideshow');
 
 var prepare = function() {
 
  $('h3', slides).each(function(i) {
  
   $(this).attr('rel', '#s' + (i+1));
  
  });
 
 };
 
 var reset = function() {
 
  images.hide();
  wrapper.css('left', 0);
 
 };
 
 var slideAndShow = function(slide) {
 
  wrapper.animate({
   left: - slide.position.left
  }, 100, function() {
  
   slide.fadeIn(1000);
  
  });
 
 
 };
 
 var showHideSlides = function() {
 
  $('h3', slides).each(function() {
  
   var $h3 = $(this);
   var slide = $($h3.attr('rel'));
   
   $h3.click(function() {
   
    reset();
   
    if(!$h3.hasClass('active')) {
    
     $h3.parent().animate({
      top: 660
     }, 500);
     
     slideAndShow(slide);
     
     $h3.addClass('active');
    
    } else {
    
     $h3.parent().animate({
      top: 721
     }, 500);
     
     $h3.removeClass('active');
    
    }
   
   });
   
  
  });
 
 
 };
 
 this.init = function() {
 
  prepare();
 
  showHideSlides();
 
 };


}();

$(function() {

 Slider.init();

});
&lt;/pre&gt;

&lt;p&gt;We've set a &lt;code&gt;rel&lt;/code&gt; attribute on each tab's heading so that the current heading is actually linked to the corresponding image through the ID previously defined on the image itself.&lt;/p&gt;

&lt;p&gt;Also, we're using a dynamic CSS class on headings just to make sure that the current element is active. The effect on the tabs is simple: we only adjust their &lt;code&gt;top&lt;/code&gt; property and then we reset it to its default value.&lt;/p&gt;

&lt;p&gt;You can see the demo below.&lt;/p&gt;


&lt;h3&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-slideshow-professionale-tab-espandibili/"&gt;Live demo&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Download&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-slideshow-professionale-tab-espandibili/jquery-slideshow-professionale-tab-espandibili.zip"&gt;ZIP file&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-2351800466789573334?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/TCdPjxzJE7I" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/TCdPjxzJE7I/jquery-expanding-tabs-content-slider.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2011/11/jquery-expanding-tabs-content-slider.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-6582258710581584002</guid><pubDate>Tue, 15 Nov 2011 17:38:00 +0000</pubDate><atom:updated>2011-11-15T09:38:51.328-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: deferred objects and animated slideshows</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/images/jquery.png" alt="" class="alignright" /&gt;Today I had to write my weekly post on &lt;a href="http://blog.html.it/"&gt;the Html.it blog&lt;/a&gt; and I suddenly start mumbling on the recent possibilities offered by jQuery's deferred objects. When we deal with content sliders we usually have to perform two main tasks: sliding and animating. If you take a look at one of my past works, namely &lt;a href="http://www.btmagazine.it/"&gt;BTMagazine&lt;/a&gt;, you'll surely notice that each slide has a lot of effects and animations. You'd probably be worried by knowing that each animation set has been created by using a long chain of nested callback functions that span on several lines. In short, the code works but it's a mess. Deferred objects, instead, allow us to create all the effects we need without having to use callback functions. Let's see how.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;In the traditional, chained model, you use callbacks like this:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
$('#slideshow-wrapper').animate({
 left: - $('div.slide').eq(index).position().left
}, 1000, function() {

 $('div.slide').eq(index).
 find('div.desc').fadeIn(1000);

});
&lt;/pre&gt;

&lt;p&gt;If you're lucky, two or three additional animations is enough, but sometimes (just like in my case) you have to deal with dozens nested effects. Here's when deferred objects come into play.&lt;/p&gt;

&lt;p&gt;Deferred objects allow us to concatenate actions, but in a radically different way: each code section has its own life which is contained within the &lt;code&gt;Deferred&lt;/code&gt; wrapper.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var Slider = new function() {
    
    var timer = null,
        index = 0,
        wrapper = $('#slideshow-wrapper'),
        slides = $('div.slide', wrapper);
    
    var slide = function() {
        
        timer = setInterval(function() {
            
            index++;
            
            if(index == slides.length) {
             
                index = 0;
               
                $('div.desc', wrapper).hide(); 
                
            }
            
            $.Deferred(function(def) {
                
                def.pipe(function() {
                  
                    return wrapper.animate({
                        left: - slides.eq(index).position().left
                       
                    }, 1000); 
                    
                }).pipe(function() {
                   
                   return slides.eq(index).
                      find('div.desc').fadeIn(1000); 
                    
                });
                
            }).resolve();
            
        }, 2000);
        
    };
    
    this.init = function() {
        
      slide();  
        
    };
        
    
    
}();
  
  
$(function() {
   
  Slider.init();
   
}); 
&lt;/pre&gt;

&lt;p&gt;There are two separate actions in the following code, not a chain:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
$.Deferred(function(def) {
                
                def.pipe(function() {
                  
                    return wrapper.animate({
                        left: - slides.eq(index).position().left
                       
                    }, 1000); 
                    
                }).pipe(function() {
                   
                   return slides.eq(index).
                      find('div.desc').fadeIn(1000); 
                    
                });
                
}).resolve();
&lt;/pre&gt;

&lt;p&gt;You can also write two separate functions or methods to be executed within each call to the &lt;code&gt;pipe()&lt;/code&gt; method. This practice allows us to write clear, concise, organized and compact code.&lt;/p&gt;

&lt;p&gt;You can see the live example on &lt;a href="http://jsfiddle.net/gabrieleromanato/kp3dE/3/"&gt;JSFiddle&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-6582258710581584002?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/jTDbtPvwvhA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/jTDbtPvwvhA/jquery-deferred-objects-and-animated.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2011/11/jquery-deferred-objects-and-animated.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-6860464985683283656</guid><pubDate>Fri, 11 Nov 2011 18:41:00 +0000</pubDate><atom:updated>2011-11-11T10:42:44.057-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: creating a slideshow from scratch</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/10/atwork.jpg" class="wide spaced" alt="" /&gt;The theory behind a jQuery slideshow is one of the most neglected topics in a million. Many web sites provide excellent tutorials on how to create specific slideshows for specific scenarios, but there are no tutorials covering the theory and the basics of a jQuery slideshow. In short, you're a developer who wants to create a slideshow for his/her client. You've tried to use an existing plugin but the client's needs are very specific and the chosen plugin doesn't fit the bill. So you need to understand how a jQuery slideshow works in order to create a custom one. Let's get to work.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;Choosing the right markup&lt;/h2&gt;

&lt;p&gt;A slideshow is made up of solid and robust HTML markup. It doesn't matter if you choose to use HTML5, XHTML or HTML 4: it's the structure that makes the difference, not the preferred DTD.&lt;/p&gt;

&lt;p&gt;There are several parts that make up a slideshow, which include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Outer container&lt;/strong&gt;: this is the general wrapper of your slideshow that you can stylize with CSS to exactly position the whole slideshow on a specific section of a page.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inner container&lt;/strong&gt;: this is the wrapper of your slide elements, which can either be images or other elements.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Slides&lt;/strong&gt;: slides can be either &lt;code&gt;img&lt;/code&gt; or &lt;code&gt;div&lt;/code&gt; elements, depending on the slideshow type.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Controls&lt;/strong&gt;: controls are the canonical "Next" and "Previous" buttons or a series of links containing thumbnails used for navigating the slides.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's the structure of a recent demo of mine:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;div id=&amp;quot;slideshow-container&amp;quot;&amp;gt;
&amp;lt;div id=&amp;quot;slideshow&amp;quot;&amp;gt;
 &amp;lt;div id=&amp;quot;slideshow-wrapper&amp;quot;&amp;gt;
  &amp;lt;img src=&amp;quot;1.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s1&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;2.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s2&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;3.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s3&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;4.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s4&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;5.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s5&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;6.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s6&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;7.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s7&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;8.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s8&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;9.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s9&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;10.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s10&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;11.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s11&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;12.jpg&amp;quot; alt=&amp;quot;&amp;quot; id=&amp;quot;s12&amp;quot; /&amp;gt;
  
  
 &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div id=&amp;quot;slideshow-thumbs&amp;quot;&amp;gt;
 &amp;lt;a href=&amp;quot;#&amp;quot; rel=&amp;quot;s1&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;1.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;
 &amp;lt;a href=&amp;quot;#&amp;quot; rel=&amp;quot;s2&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;2.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;
 &amp;lt;a href=&amp;quot;#&amp;quot; rel=&amp;quot;s3&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;3.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;
 &amp;lt;a href=&amp;quot;#&amp;quot; rel=&amp;quot;s4&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;4.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;
 &amp;lt;a href=&amp;quot;#&amp;quot; rel=&amp;quot;s5&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;5.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;
 &amp;lt;a href=&amp;quot;#&amp;quot; rel=&amp;quot;s6&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;6.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;
 &amp;lt;a href=&amp;quot;#&amp;quot; rel=&amp;quot;s7&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;7.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;
 &amp;lt;a href=&amp;quot;#&amp;quot; rel=&amp;quot;s8&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;8.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;
 &amp;lt;a href=&amp;quot;#&amp;quot; rel=&amp;quot;s9&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;9.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;
 &amp;lt;a href=&amp;quot;#&amp;quot; rel=&amp;quot;s10&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;10.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;
 &amp;lt;a href=&amp;quot;#&amp;quot; rel=&amp;quot;s11&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;11.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;
 &amp;lt;a href=&amp;quot;#&amp;quot; rel=&amp;quot;s12&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;12.jpg&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div id=&amp;quot;controls&amp;quot;&amp;gt;
   &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;previous&amp;quot;&amp;gt;Previous&amp;lt;/a&amp;gt;
   &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;next&amp;quot;&amp;gt;Next&amp;lt;/a&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Let's make this code a little bit clearer. This is an image slideshow and is made up of the following parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;slideshow-container&lt;/code&gt; is the outermost wrapper of the whole slideshow&lt;/li&gt;
&lt;li&gt;&lt;code&gt;slideshow&lt;/code&gt; is the outermost wrapper of the slides&lt;/li&gt;
&lt;li&gt;&lt;code&gt;slideshow-wrapper&lt;/code&gt; is the innermost wrapper of the slides&lt;/li&gt;
&lt;li&gt;each slide has a progressive ID (&lt;code&gt;s1&lt;/code&gt;, &lt;code&gt;s2&lt;/code&gt;, etc.) which uniquely identifies each image&lt;/li&gt;
&lt;li&gt;&lt;code&gt;slideshow-thumbs&lt;/code&gt; contains a series of linked thumbnails of the images; each link has a &lt;code&gt;rel&lt;/code&gt; attribute set on the same value of the corresponding ID of each image so that now thumbnails and images are linked together&lt;/li&gt;
&lt;li&gt;&lt;code&gt;controls&lt;/code&gt; contains the traditional "Previous" and "Next" buttons.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The above structure is surely one of the most widely used in the overwhelming majority of slideshows. In this case the controls and navigation sections come after the slide series, but you can revert this structure by inserting them just before the outermost slide wrapper.&lt;/p&gt;

&lt;h2&gt;Using CSS&lt;/h2&gt;

&lt;p&gt;CSS performs a preparatory task: it simply lays out the slideshow in the way you want it to appear. As you surely noticed from the code above, we have 12 images. Each image is approximately 650 pixels wide and 440 pixels tall. But we want to display only one large image at time, so how we can do?&lt;/p&gt;

&lt;p&gt;We could use floating to align images on the same line, but our wrapper should be 7,800 pixels wide, so how this could be? It could be one way: we use the &lt;code&gt;overflow&lt;/code&gt; property combined with floating so that only one image will be always visible:&lt;/p&gt;

&lt;pre class="prettyprint lang-css"&gt;
#slideshow-container {
 width: 650px;
 margin: 2em auto;
 position: relative;
}

#slideshow {
 width: 100%;
 height: 440px;
 position: relative; 
 z-index: 1;
 overflow: hidden;
}

#slideshow-wrapper {
 width: 7800px;
 height: 440px;
 position: relative;
}

#slideshow-wrapper img {
 width: 650px;
 height: 440px;
 float: left;
}
&lt;/pre&gt;

&lt;p&gt;Our innermost image wrapper is actually 7,800 pixels wide, but only a 650 x 440 box will be visible thanks to the hidden overflow. Now our images are all laid out on the same line, but we can see only one image at time when the slideshow slides (no pun intended).&lt;/p&gt;

&lt;p&gt;Now you may ask: "Why &lt;code&gt;position: relative&lt;/code&gt;?". This is due to two reasons: first, IE 6 and 7 have a problem with the overflowing content and this declaration fixes the bug; second, we need to create a contextual positioning for our next/previous buttons:&lt;/p&gt;

&lt;pre class="prettyprint lang-css"&gt;
#controls a {
 display: block;
 width: 29px;
 height: 78px;
 text-indent: -1000em;
 background-repeat: no-repeat;
}

#controls #previous {
 background-image: url(arrow-left.png);
 float: left;
 position: relative;
 left: -29px;
}

#controls #previous:hover {
 background-position: 0 -78px;
}

#controls #next {
 background-image: url(arrow-right.png);
 float: right;
 position: relative;
 right: 0;
}

#controls #next:hover {
 background-position: 0 -78px;
}
&lt;/pre&gt;

&lt;p&gt;We've simply vertically centered our controls and put them on the opposite edges of the main content area so that they will be shown each one on a different image side ("Previous" on the left, "Next" on the right).&lt;/p&gt;

&lt;p&gt;Finally, our thumbnail navigation:&lt;/p&gt;

&lt;pre class="prettyprint lang-css"&gt;
#slideshow-thumbs {
 margin-top: 1em;
 width: 100%;
 height: 50px;
}

#slideshow-thumbs a {
 float: left;
 width: 54px;
 height: 100%;
}

#slideshow-thumbs a img {
 display: block;
 width: 100%;
 height: 100%;
 border: none;
}
&lt;/pre&gt;

&lt;h2&gt;Adding jQuery&lt;/h2&gt;

&lt;p&gt;We have to implement three actions with jQuery:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An automatic sliding&lt;/li&gt;
&lt;li&gt;Next/Previous navigation&lt;/li&gt;
&lt;li&gt;Thumbnail navigation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's focus on the sliding first. As you remember, we've a series of floated images. Each image is 650 x 440 pixels wide and its wrapper is globally 7,800 pixels wide. Since the wrapper is relatively positioned, each image has its own left offset calculated from the left edge of the container. So the first images has an offset of 0, the second has 650, the third 1300 and so on. So far so good. Each image has an offset, but what's the point with knowing this?&lt;/p&gt;

&lt;p&gt;Here's the point: we want to make the slide wrapper move from right to left and from left to right by adjusting its &lt;code&gt;left&lt;/code&gt; property. By doing so, we'll use the left offset of each image to make the current image appear. Very simple.&lt;/p&gt;

&lt;p&gt;But first things first: let's wrap our code with an object:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var Slideshow = new function() {

 // code here

}();
&lt;/pre&gt;

&lt;p&gt;Now we need to define some initial variables for later use:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;a reference to a JavaScript timer defined later and used for the automatic sliding&lt;/li&gt;
&lt;li&gt;a global index initially set to 0 to get the current image&lt;/li&gt;
&lt;li&gt;a reference to the image wrapper&lt;/li&gt;
&lt;li&gt;a reference to the images themselves&lt;/li&gt;
&lt;li&gt;a reference to the thumbnail links&lt;/li&gt;
&lt;li&gt;a reference to the previous/next buttons&lt;/li&gt;
&lt;/ol&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var timer = null,
     index = 0,
     wrapper = $('#slideshow-wrapper', '#slideshow'),
     slides = $('img', wrapper),
     thumbs = $('a', '#slideshow-thumbs'),
     previous = $('#previous', '#controls'),
     next = $('#next', '#controls');

&lt;/pre&gt;

&lt;p&gt;Next step is to store all the image offsets in an array that can be accessed through our global index:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var getSlidePositions = function() {
 
  var positions = [];
  slides.each(function(i) {
  
   var left = $(this).position().left;
   
   positions[i] = left;
  
  });
  
  return positions;
 
};
&lt;/pre&gt;

&lt;p&gt;Thumbnail links are associated with the large images through the &lt;code&gt;rel&lt;/code&gt; attribute but they're not aware of the offset of each image, so we need now to associate each image with its left offset through the jQuery's &lt;code&gt;attr()&lt;/code&gt; method:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var addOffsetsToImages = function() {
 
  slides.each(function() {
  
   $(this).attr('position', $(this).position().left);
  
  });
 
};
&lt;/pre&gt;

&lt;p&gt;The preparatory work is done. Now we can create our automatic sliding by incrementing and decrementing our global index to access the offsets array in a JavaScript timer:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var autoSlide = function() {
 
  var offsets = getSlidePositions();
  timer = setInterval(function() {
  
      index++;
      
      if(index == offsets.length) {
      
       index = 0;
      
      }
  
   wrapper.animate({
    left: - offsets[index]
   }, 1000, function() {
   
    thumbs.eq(index).animate({
     opacity: 0.5
    }, 500, function() {
    
     $(this).animate({
      opacity: 1
     }, 500);
    
    }); 
   
   });
  
  
  
  }, 2000);
  
 
 
};
&lt;/pre&gt;

&lt;p&gt;Together with making the image wrapper slide, this timer also animates the current image thumbnail by adjusting its opacity. Thumbnails are our next step. We need to associate an action that makes the current image slide into view. In this case, our timer needs to be stopped when we click on a thumbnail and restarted when the sliding movement ends:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var handleThumbLinks = function() {
 
  thumbs.each(function() {
  
   var $a = $(this);
   var imgId = $('#' + $a.attr('rel'));
   var $offset = imgId.attr('position');
   
   $a.click(function(event) {
   
    clearInterval(timer);
    
    wrapper.animate({
     left: - $offset
    }, 1000, function() {
    
     autoSlide();
    
    });
   
    event.preventDefault();
   
   });
  
  });
 
};
&lt;/pre&gt;

&lt;p&gt;The triggered action uses as left offset the current's image &lt;code&gt;position&lt;/code&gt; attribute previously set. It also uses the link's &lt;code&gt;rel&lt;/code&gt; attribute to target the current ID of the image.&lt;/p&gt;

&lt;p&gt;The last action we need to implement is the handling of next/previous buttons:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
var handlePrevNextButtons = function() {
 
     var offsets = getSlidePositions();
 
  previous.click(function(event) {
      
      clearInterval(timer);
  
      index--;
  
   if(index == 0) {
   
    index = 0;
   
   }
   
   wrapper.animate({
    left: - offsets[index]
   }, 1000, function() {
   
    autoSlide();
   
   });
   
  
   event.preventDefault();
  
  });
  
  next.click(function(event) {
      
      clearInterval(timer);
  
      index++;
  
   if(index == offsets.length) {
   
    index = 0;
   
   }
   
   wrapper.animate({
    left: - offsets[index]
   }, 1000, function() {
   
    autoSlide();
   
   });
   
  
   event.preventDefault();
  
  });

 
 
};
&lt;/pre&gt;

&lt;p&gt;In this case we also need to check whether our global index is within the range given by the number of images and act accordingly. Finally, we have to define a public function to kicks things off:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
this.init = function() {
 
  addOffsetsToImages();
 
  autoSlide();
  
  handleThumbLinks();
  
  handlePrevNextButtons();
 
};
&lt;/pre&gt;

&lt;p&gt;Usage:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
$(function() {

 Slideshow.init();

});
&lt;/pre&gt;

&lt;p&gt;You can see the demo below.&lt;/p&gt;

&lt;h3&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-prototipo-slideshow-professionale/"&gt;Live demo&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-6860464985683283656?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/bxF3bcUjoEU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/bxF3bcUjoEU/jquery-creating-slideshow-from-scratch.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2011/11/jquery-creating-slideshow-from-scratch.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-454753559990421531</guid><pubDate>Thu, 03 Nov 2011 11:08:00 +0000</pubDate><atom:updated>2011-11-03T04:08:55.461-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">wordpress</category><category domain="http://www.blogger.com/atom/ns#">css</category><title>WordPress: creating a custom CSS</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/images/wordpress.png" alt="" class="alignright" /&gt;The recommended way of customizing your default WordPress theme is to create a child theme. However, sometimes we only need to add just a few style rules to override some default styles of our theme, so what we really need is to create a custom style sheet for our theme. Let's see how.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;You shouldn't add your custom CSS to the theme directory, because you'll probably end up with having files which don't belong to the theme. A good solution is to put your CSS file just under your &lt;code&gt;/uploads&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Add the following code to the &lt;code&gt;functions.php&lt;/code&gt; file of your theme (create one if it doesn't exist):&lt;/p&gt;


&lt;pre class="php-f"&gt;
add_action('wp_print_styles', 'add_custom_css');

function add_custom_css() {

    $uploads = wp_upload_dir();

 $url = $uploads['baseurl'] . '/custom.css';
    wp_register_style('custom', $url);
    wp_enqueue_style('custom');

}
&lt;/pre&gt;

&lt;p&gt;If you open your home page now and take a look at the source code inside the &lt;code&gt;head&lt;/code&gt; tag, you'll see the new CSS file properly linked. The new CSS file comes just after the main style sheet of your theme. This is a must: in order to make your new style rules to override the preceding ones, a custom style sheet must come after the main style sheet. This is due to the CSS cascade: a CSS file that comes later in the source has an higher precedence over all the preceding ones.&lt;/p&gt;

&lt;p&gt;For example, if you have the following rule in your main &lt;code&gt;style.css&lt;/code&gt; file:&lt;/p&gt;

&lt;pre class="prettyprint lang-css"&gt;
#header {
 height: 150px;
 background: #000;
}
&lt;/pre&gt;

&lt;p&gt;you can override it in your custom CSS as follows:&lt;/p&gt;

&lt;pre class="prettyprint lang-css"&gt;
#header {
 height: 100px;
 background: #c30;
}
&lt;/pre&gt;

&lt;p&gt;The quickest way to achieve this is to copy the original style rules you want to change into your custom CSS file and modify them there. By doing so, you make sure that cascading and specificity will work as intended.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-454753559990421531?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/YkZ61EsVUBQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/YkZ61EsVUBQ/wordpress-creating-custom-css.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2011/11/wordpress-creating-custom-css.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-6323903253975857972</guid><pubDate>Tue, 01 Nov 2011 18:55:00 +0000</pubDate><atom:updated>2011-11-01T11:55:08.920-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><category domain="http://www.blogger.com/atom/ns#">html5</category><title>jQuery: emulating the placeholder attribute</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/images/jquery.png" alt="" class="alignright" /&gt;Internet Explorer 8 doesn't support the HTML5 &lt;code&gt;placeholder&lt;/code&gt; attribute that we can use to label our text fields. Fortunately, we can emulate this attribute with jQuery. Let's see how.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;We have to create a plugin to exactly position an element with its text label just over a text field:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
(function($) {

 $.fn.placeholder = function(options) {
 
  var that = this;
  
  if(!that.is('input[type=text]')) {
  
   return;
  
  }
  
  var defaults = {
  
   text: 'Placeholder'
  
  };
  
  options = $.extend(defaults, options);
  
  var top = that.offset().top;
  var left = that.offset().left;
  
  return that.each(function() {
  
   $('&amp;lt;span class=&amp;quot;placeholder&amp;quot;/&amp;gt;').text(options.text).
   css({
    position: 'absolute',
    top: top,
    left: left
   }).insertAfter(that);
   
   that.focus(function() {
   
   
    that.next('span.placeholder').hide();
   
   });
   
   that.blur(function() {
   
    if(that.val() == '') {
    
     that.next('span.placeholder').show();
    
    }
   
   }); 
  
  });
 
 };

})(jQuery);
&lt;/pre&gt;

&lt;p&gt;We use the top and left offsets of the text field to position our element. We use then &lt;code&gt;focus&lt;/code&gt; and &lt;code&gt;blur&lt;/code&gt; to hide the placeholder while a user is typing and to show it again if the field's value is empty, respectively.&lt;/p&gt;


&lt;p&gt;An example:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
$(function() {

 $('#text', '#form').placeholder({text: 'Lorem'});
 $('#text2', '#form').placeholder({text: 'Lorem ipsum'});

});
&lt;/pre&gt;

&lt;p&gt;You can see the demo below.&lt;/p&gt;

&lt;h4&gt;Demo&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-simulare-attributo-placeholder/"&gt;Live demo&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-6323903253975857972?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/x-9cJqizfVY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/x-9cJqizfVY/jquery-emulating-placeholder-attribute.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2011/11/jquery-emulating-placeholder-attribute.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-500633042737746094</guid><pubDate>Tue, 01 Nov 2011 17:19:00 +0000</pubDate><atom:updated>2011-11-01T10:19:40.447-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">wordpress</category><title>WordPress: adding social buttons with iframes</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/images/wordpress.png" alt="" class="alignright" /&gt;JavaScript social buttons are evil. They may cause major hiccups in the overall performance of your sites, not to mention that they may actually block the rendering of your pages. Iframes are better, because they load simple HTML snippets. In this post I'll show you how to add the Twitter, Facebook and Google Plus buttons to your WordPress theme.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;Add the following code to the &lt;code&gt;functions.php&lt;/code&gt; file of your theme (create one if it doesn't exist):&lt;/p&gt;

&lt;pre class="php-f"&gt;
function tweet_button() {

 $title = get_the_title();
 $link = get_permalink();
 
 $html = '&amp;lt;iframe allowtransparency=&amp;quot;true&amp;quot; frameborder=&amp;quot;0&amp;quot; scrolling=&amp;quot;no&amp;quot; src=&amp;quot;http://platform.twitter.com/widgets/tweet_button.html?';
 $html .= 'url=' . $link . '&amp;amp;text=' . $title . '&amp;amp;count=vertical&amp;via=username&amp;quot;&amp;gt;&amp;lt;/iframe&amp;gt;';
 
 return $html;

}

function facebook_button() {

 $title = get_the_title();
 $link = get_permalink();
 
 $html = '&amp;lt;iframe allowtransparency=&amp;quot;true&amp;quot; frameborder=&amp;quot;0&amp;quot; scrolling=&amp;quot;no&amp;quot; src=&amp;quot;http://www.facebook.com/plugins/like.php?';
 $html .= 'href=' . $link . '&amp;amp;title=' . $title . '&amp;layout=box_count&amp;quot;&amp;gt;&amp;lt;/iframe&amp;gt;';
 
 return $html;

}


function google_plus_button() {

 $link = get_permalink();
 
 $html = '&amp;lt;iframe src=&amp;quot;https://plusone.google.com/u/0/_/+1/fastbutton?url=';
 $html .= $link . '&amp;amp;size=tall&amp;amp;count=true&amp;amp;annotation=bubble&amp;lang=it&amp;quot; scrolling=&amp;quot;no&amp;quot; frameborder=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;/iframe&amp;gt;';
 
 return $html;

}
&lt;/pre&gt;

&lt;p&gt;Then you can use such functions directly in your theme files, as follows:&lt;/p&gt;

&lt;pre class="php-f"&gt;
&amp;lt;div id=&amp;quot;social&amp;quot;&amp;gt;
 &amp;lt;span class=&amp;quot;twitter&amp;quot;&amp;gt;&amp;lt;?php echo tweet_button();?&amp;gt;&amp;lt;/span&amp;gt;
 &amp;lt;span class=&amp;quot;facebook&amp;quot;&amp;gt;&amp;lt;?php echo facebook_button();?&amp;gt;&amp;lt;/span&amp;gt;
 &amp;lt;span class=&amp;quot;google-plus&amp;quot;&amp;gt;&amp;lt;?php echo google_plus_button();?&amp;gt;&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Bear in mind that the above functions must be called in The Loop.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-500633042737746094?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/FO7yjJvyMZo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/FO7yjJvyMZo/wordpress-adding-social-buttons-with.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2011/11/wordpress-adding-social-buttons-with.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-2190245532905168919</guid><pubDate>Tue, 01 Nov 2011 16:14:00 +0000</pubDate><atom:updated>2011-11-01T09:14:58.002-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: notification message system</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/images/jquery.png" alt="" class="alignright" /&gt;The most stimulating part of my job with jQuery is to turn ideas into code. Today I needed to create a notification system for a web site. A user can fill out a form by specifying if he's writing a project or a task. jQuery collects all the data and populate the corresponding item on a top menu. The most important part is that you can further extend the basic code to work with AJAX. Let's see now our implementation.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;First, the markup:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;ul id=&amp;quot;notifications&amp;quot;&amp;gt;
 &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;projects&amp;quot;&amp;gt;Progetti &amp;lt;span&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
 &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;tasks&amp;quot;&amp;gt;Compiti &amp;lt;span&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;form action=&amp;quot;#&amp;quot; method=&amp;quot;post&amp;quot; id=&amp;quot;message&amp;quot;&amp;gt;
 &amp;lt;div&amp;gt;
  &amp;lt;label for=&amp;quot;category&amp;quot;&amp;gt;Categoria&amp;lt;/label&amp;gt;
  &amp;lt;select name=&amp;quot;category&amp;quot; id=&amp;quot;category&amp;quot;&amp;gt;
   &amp;lt;option&amp;gt;Seleziona:&amp;lt;/option&amp;gt;
   &amp;lt;option value=&amp;quot;progetti&amp;quot;&amp;gt;Progetti&amp;lt;/option&amp;gt;
   &amp;lt;option value=&amp;quot;compiti&amp;quot;&amp;gt;Compiti&amp;lt;/option&amp;gt;
  &amp;lt;/select&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;div&amp;gt;
  &amp;lt;label for=&amp;quot;title&amp;quot;&amp;gt;Titolo&amp;lt;/label&amp;gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;title&amp;quot; id=&amp;quot;title&amp;quot; /&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;div&amp;gt;
  &amp;lt;label for=&amp;quot;description&amp;quot;&amp;gt;Descrizione&amp;lt;/label&amp;gt;
  &amp;lt;textarea name=&amp;quot;description&amp;quot; id=&amp;quot;description&amp;quot; rows=&amp;quot;15&amp;quot; cols=&amp;quot;15&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;p&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; name=&amp;quot;send&amp;quot; id=&amp;quot;send&amp;quot; value=&amp;quot;Invia&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Then a couple of CSS rules to display our main elements:&lt;/p&gt;

&lt;pre class="prettyprint lang-css"&gt;
body {
 margin: 0;
 padding: 0;
 font: 95% Arial, sans-serif;
}

#notifications {
 height: 2em;
 margin: 0;
 padding: 0 0.5em;
 list-style: none;
 background: #222;
}

#notifications &amp;gt; li {
 float: left;
 height: 100%;
 margin-right: 0.5em;
 position: relative;
}

#notifications &amp;gt; li &amp;gt; a {
 float: left;
 height: 100%;
 line-height: 2;
 padding: 0 1em;
 font-weight: bold;
 text-decoration: none;
 color: #fff;
}

#notifications #projects {
 background: #c30;
}

#notifications #tasks {
 background: #282;
}

#message {
 width: 35em;
 margin: 1em auto;
 padding: 0;
}

#message input,
#message select,
#message textarea {
 font: 1em Arial, sans-serif;
 display: block;
}

#message label {
 display: block;
 font-weight: bold;
 padding-bottom: 4px;
}

#message div input {
 width: 150px;
 border: 1px solid #bbb;
 margin-bottom: 0.5em;
}

#message div select {
 width: 150px;
 margin-bottom: 0.5em;
}

#message div textarea {
 width: 380px;
 height: 280px;
 border: 1px solid #bbb;
}

#message p input {
 width: 100px;
 background: #ddd;
 border: 1px solid #aaa;
 font-weight: bold;
 padding: 5px;
 border-radius: 5px;
}

ul.messages {
 width: 15em;
 padding: 0.8em;
 margin: 0;
 list-style: none;
 background: #222;
 color: #fff;
 position: absolute;
 top: 2em;
 left: 0;
 display: none;
}

ul.messages li {
 margin-bottom: 0.4em;
 padding-bottom: 4px;
 border-bottom: 1px dotted #ccc;
 text-align: right;
}

ul.messages li a {
 color: #f90;
 font-size: 1.2em;
 font-weight: bold;
 text-decoration: none;
}

ul.messages li div.message {
 text-align: left;
}

ul.messages li div.message h4 {
 font: normal 1.2em Arial, sans-serif;
 margin: 0;
}

ul.messages li div.message p {
 margin: 0.3em 0;
 line-height: 1.4;
}
&lt;/pre&gt;

&lt;p&gt;With jQuery, we first need to attach an hidden list to all our items in the notification menu. Then we need to populate the corresponding list based on the user's choice. In fact, users can either select tasks or projects:&lt;/p&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
$(function() {

 $('li', '#notifications').each(function() {
 
  var $ul = $('&amp;lt;ul class=&amp;quot;messages&amp;quot;/&amp;gt;');
  
  $ul.appendTo($(this));
 
 });
  
    
  $('a.delete').live('click', function(event) {
  
      var $a = $(this);
   var $ul = $a.parents('ul.messages');
   var $message = $a.parent();
   var $li = $ul.parent();
   var $span = $('a span', $li);
   var no = new Number($span.text());

  
   $ul.slideUp(500);
   $message.remove();
   
   $span.text(no - 1);
 
  
   event.preventDefault();
  
  });
 

 
 $('#message').submit(function(event) {
 
     var $form = $(this);
     var category = $('#category', $form).val();
     var title = $('#title', $form).val();
     var description = $('#description', $form).val();
     
     var projects = $('#projects', '#notifications');
     var projectsNo = $('span', projects);
     var tasks = $('#tasks', '#notifications');
     var tasksNo = $('span', tasks);
     
     var projectsNumber = new Number(projectsNo.text());
     var tasksNumber = new Number(tasksNo.text());
     
     var projectMessages = projects.parent().find('ul.messages');
     var taskMessages = tasks.parent().find('ul.messages');
     
     var html = '&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;delete&amp;quot;&amp;gt;X&amp;lt;/a&amp;gt;&amp;lt;div class=&amp;quot;message&amp;quot;&amp;gt;';
     
     switch(category) {
     
      case 'progetti':
      
         html += '&amp;lt;h4&amp;gt;' + title + '&amp;lt;/h4&amp;gt;&amp;lt;p&amp;gt;' + description + '&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;';
         
         $(html).appendTo(projectMessages);
         
         projectsNo.text(projectsNumber + 1);
      
         break;
         
      case 'compiti':
      
       html += '&amp;lt;h4&amp;gt;' + title + '&amp;lt;/h4&amp;gt;&amp;lt;p&amp;gt;' + description + '&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/li&amp;gt;';
         
         $(html).appendTo(taskMessages);
         
         tasksNo.text(tasksNumber + 1);
      
         break;
         
      default:
      
         break;
     
     
     }
  
 
  event.preventDefault();
 });
 
 $('#projects').click(function(event) {
 
     var $a = $(this);
     
     var $ul = $a.parent().find('ul.messages');
     
     if($ul.is(':hidden')) {
     
      $ul.slideDown(500);
     
     } else {
     
      $ul.slideUp(500);
     
     }
  
 
  event.preventDefault();
 
 });
 
 $('#tasks').click(function(event) {
 
     var $a = $(this);
     
     var $ul = $a.parent().find('ul.messages');
     
     if($ul.is(':hidden')) {
     
      $ul.slideDown(500);
     
     } else {
     
      $ul.slideUp(500);
     
     }
  
 
  event.preventDefault();
 
 });
 
 
 


});
&lt;/pre&gt;

&lt;p&gt;You can see the demo below.&lt;/p&gt;

&lt;h4&gt;Demo&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-sistema-notifiche-tempo-reale/"&gt;Live demo&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-2190245532905168919?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/lHZf9xlbemg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/lHZf9xlbemg/jquery-notification-message-system.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2011/11/jquery-notification-message-system.html</feedburner:origLink></item></channel></rss>

