<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="http://www.developer.nokia.com/Community/Blogs/styles/rss.css" type="text/css"?>
<rdf:RDF
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
  xmlns:admin="http://webns.net/mvcb/"
  xmlns="http://purl.org/rss/1.0/"
>
 <channel rdf:about="http://www.developer.nokia.com/Community/Blogs/rss.php?blogId=300144&amp;profile=rss10">
  <title>Web Dev</title>
  <link>http://www.developer.nokia.com/Community/Blogs/blog/web-dev</link>
  <description>&lt;p&gt;The Nokia Web Dev Blog is here to highlight some of the most interesting and most useful techniques, tools and toys on the web.&lt;/p&gt;
</description>
    <dc:creator>simonmadine</dc:creator>
  <dc:date>2013-05-22T03:46:58Z</dc:date>
  <admin:generatorAgent rdf:resource="http://www.lifetype.net" />
  <items>
   <rdf:Seq>
       <rdf:li rdf:resource="http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/05/03/dynamic-backgrounds-without-artifacts" />
       <rdf:li rdf:resource="http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/04/19/new-nokia-maps-api-url-creation" />
       <rdf:li rdf:resource="http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/04/12/left-click-handler" />
       <rdf:li rdf:resource="http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/04/05/reliable-image-replacement" />
       <rdf:li rdf:resource="http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/03/29/carousel" />
       <rdf:li rdf:resource="http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/03/23/simple-servers" />
       <rdf:li rdf:resource="http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/03/16/background-size-cover" />
       <rdf:li rdf:resource="http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/03/14/web-development-nokia" />
      </rdf:Seq>
  </items> 
 </channel>
  <item rdf:about="http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/05/03/dynamic-backgrounds-without-artifacts">
  <title>Dynamic backgrounds without artifacts</title>
  <link>http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/05/03/dynamic-backgrounds-without-artifacts</link>
  <dc:description>&lt;p&gt;
&lt;em&gt;This is the second part of &lt;a href=&quot;http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/03/16/background-size-cover&quot;&gt;the post on the City Pages header images&lt;/a&gt;. If you want to read more about &lt;code&gt;background-size:cover&lt;/code&gt;, start there.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Now you have your large, dynamically scaling image, it&#039;s time to make it better. You might have noticed that when you scale an image up, it can appear low quality. When images are &#039;upscaled&#039;, it can have a bad effect on your users&#039; perception of your page. Even if the effect is subtle, it can detract from any benefits gained in using &lt;code&gt;background-size: cover&lt;/code&gt;. Fortunately, there are a couple of techniques we employ to lessen this problem.
&lt;/p&gt;
&lt;h2&gt;Image rendering algorithm&lt;/h2&gt;
&lt;p&gt;
It is possible to specify the algorithm the browser uses when it scales your image. The &lt;code&gt;image-rendering&lt;/code&gt; attribute lets you choose, amongst other options, between &#039;faster, lower quality&#039; and &#039;slower, higher quality&#039;. In this use-case, we have only a single header image so there won&#039;t be a performance hit if we specified the higher quality option. Even though this isn&#039;t available in IE, we can use the IE-specific property &lt;code&gt;-ms-interpolation-mode&lt;/code&gt; to achieve something similar.
&lt;/p&gt;
&lt;ul class=&quot;example-pair&quot;&gt;
	&lt;li&gt;
	&lt;h3&gt;With:&lt;/h3&gt;
	&lt;div class=&quot;scale-example-box&quot; id=&quot;example-with-oq&quot; style=&quot;width: 180px; height: 180px&quot;&gt;
	&lt;img src=&quot;http://www.developer.nokia.com/Community/Blogs/data/blogs/resources/300144/example-icon.png&quot; /&gt;
	&lt;/div&gt;
	&lt;/li&gt;
	&lt;li&gt;
	&lt;h3&gt;Without:&lt;/h3&gt;
	&lt;div class=&quot;scale-example-box&quot; id=&quot;example-with-os&quot; style=&quot;width: 180px; height: 180px&quot;&gt;
	&lt;img src=&quot;http://www.developer.nokia.com/Community/Blogs/data/blogs/resources/300144/example-icon.png&quot; /&gt;
	&lt;/div&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
&lt;code&gt;
div {
&amp;nbsp;width: 180px;
&amp;nbsp;height: 180px;
&amp;nbsp;background-size: cover;
&amp;nbsp;image-rendering: optimizeQuality;
&amp;nbsp;-ms-interpolation-mode: bicubic;
}
&lt;/code&gt;
&lt;/pre&gt;
&lt;h2&gt;Pattern overlay&lt;/h2&gt;
&lt;p&gt;
Another possible way to minimise problems with upscaling is to add a subtle checkerboard effect on top of the image so it breaks up the artifacts and makes the image look better. When we first implemented this, we built it using a checkerboard pattern background-gradient (similar to &lt;a href=&quot;http://lea.verou.me/css3patterns/#checkerboard&quot;&gt;this one&lt;/a&gt; but much, much smaller). This worked well in WebKit-based browsers but slowed down terribly in Firefox. On top of that, the CSS required to specify the gradient pattern was actually larger than the image itself would be. We decided in the end to use a transparent PNG included in our main sprite. It turns out that the clever answer is not always the best answer.
&lt;/p&gt;
&lt;p&gt;
We add the pattern to the page by setting it as the background of the &lt;code&gt;:after&lt;/code&gt; &lt;a href=&quot;http://css-tricks.com/pseudo-element-roundup/&quot;&gt;pseudo element&lt;/a&gt;
&lt;/p&gt;
&lt;ul class=&quot;example-pair&quot;&gt;
	&lt;li&gt;
	&lt;h3&gt;Example:&lt;/h3&gt;
	&lt;div class=&quot;scale-example-box&quot; id=&quot;example-with-after&quot; style=&quot;width: 100px; height: 100px&quot;&gt;
	&lt;img src=&quot;http://www.developer.nokia.com/Community/Blogs/data/blogs/resources/300144/example-icon.png&quot; /&gt;
	&lt;/div&gt;
	&lt;/li&gt;
	&lt;li&gt;
	&lt;h3&gt;What it should look like:&lt;/h3&gt;
	&lt;img src=&quot;http://www.developer.nokia.com/Community/Blogs//data/blogs/resources/300144/check-example.png&quot; alt=&quot;Upscaling Example &quot; /&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
&lt;code&gt;
div:after {
display: block;
background: transparent url(check.png) 0 0 repeat;
width: 100%;
height: 100%;
margin: 0;
position: absolute;
content: &amp;quot;&amp;quot;;
&lt;/code&gt;
&lt;/pre&gt;
&lt;h3&gt;Selective solution&lt;/h3&gt;
&lt;p&gt;
Adding a pattern like this can be a good solution when the image is upscaled but we don&#039;t want it to happen all the time. When the image isn&#039;t upscaled or when it is only minimally larger than the original size, it can be distracting. To avoid this, we specify these styles in a media-query block. We&#039;ll go into them in more detail in a future article.
&lt;/p&gt;
&lt;style&gt;
.example-pair {overflow:hidden;margin:0 auto !important; width:400px;}
.example-pair li {float:right;list-style:none;}
.example-pair li:first-child {float:left;}
.scale-example-box {margin: 0px;border-width: 1px; border-color: #444444; border-style: solid;}
.scale-example-box img {width:100%;height:100%;}
p code {padding:0 !important;border:none !important;}
#example-with-oq img {
image-rendering: optimizeQuality;
-ms-interpolation-mode: bicubic;
}
#example-with-os img {
image-rendering: optimizeSpeed;
-ms-interpolation-mode: nearest-neighbor;
}
#example-with-after {
position:relative;
}
#example-with-after:after {
display: block;
background: transparent url(&#039;http://www.developer.nokia.com/Community/Blogs//data/blogs/resources/300144/check.png&#039;) 0 0 repeat;
width: 100%;
height: 100%;
margin: 0;
position: absolute;
top:0;
content: &quot;&quot;;
}
pre code {border:none !important;padding:0 !important;}
pre {position: relative;}
pre:before {content: attr(data-syntax);position: absolute;right: 15px;font-weight: bold;font-size: 1.5em;}
&lt;/style&gt;</dc:description>
      
    <dc:subject>UI</dc:subject>
      
    <dc:subject>Web Technology</dc:subject>
      
    <dc:subject>Web</dc:subject>
     
    
  <dc:date>2012-05-03T09:00:38Z</dc:date>
    <dc:creator>simonmadine</dc:creator>
 </item>
  <item rdf:about="http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/04/19/new-nokia-maps-api-url-creation">
  <title>Search-based Deep-link Formats: Places and Routes</title>
  <link>http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/04/19/new-nokia-maps-api-url-creation</link>
  <dc:description>&lt;p&gt;
&lt;a href=&quot;http://maps.nokia.com/&quot;&gt;Nokia Maps&lt;/a&gt; allows &amp;ldquo;deep links&amp;rdquo; to be created externally from the application which link to specific places, routes, addresses, etc. These deep links can be created by any other service and link directly into our application.
&lt;/p&gt;
&lt;h2&gt;Where is this place?&lt;/h2&gt;
&lt;p&gt;
This URL format will open maps.nokia.com and show a single address result directly on the map with a nice little bubble and everything.
&lt;/p&gt;
&lt;p&gt;
&lt;img src=&quot;http://www.developer.nokia.com/Community/Blogs/data/blogs/resources/300144/addressPreview.png&quot; /&gt;
&lt;/p&gt;
&lt;p&gt;
The address is formed by concatenating the various parameters of the address.
&lt;/p&gt;
&lt;code&gt;http://maps.nokia.com/whereis/address&lt;/code&gt;
&lt;h3&gt;Example&lt;/h3&gt;
&lt;p&gt;
&lt;a href=&quot;http://maps.nokia.com/whereis/unter%20den%20linden,%2021,%20berlin,%2010117,%20germany&quot;&gt;http://maps.nokia.com/whereis/unter den linden, 21, berlin, 10117, germany&lt;/a&gt;
&lt;/p&gt;
&lt;h2&gt;Getting from A to B&lt;/h2&gt;
&lt;p&gt;
This URL format will open maps.nokia.com and show a route and maneuvers on the map, and a detailed maneuver list on the left-hand panel.
&lt;/p&gt;
&lt;p&gt;
&lt;img src=&quot;http://www.developer.nokia.com/Community/Blogs//data/blogs/resources/300144/routePreview.png&quot; /&gt;
&lt;/p&gt;
&lt;h3&gt;URL Format&lt;/h3&gt;
&lt;p&gt;
The address is formed by concatenating the various parameters of the address. We support up to 6 waypoints.
&lt;/p&gt;
&lt;pre&gt;
http://maps.nokia.com/drive/address(start)/ address(waypoint1)/.../address(waypoint2)/address(destination)
&lt;/pre&gt;
&lt;h3&gt;Example&lt;/h3&gt;
&lt;p&gt;
&lt;a href=&quot;http://maps.nokia.com/drive/unter%20den%20linden,21,berlin,10117,germany/invalidenstr,117,berlin,10115,germany&quot;&gt;http://maps.nokia.com/drive/unter den linden,21,berlin,10117,germany/invalidenstr,117,berlin,10115,germany&lt;/a&gt;
&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;
We strongly believe that this new API will make our users very happy. You only need one link to create route or to show the location. We hope you will have a lot of fun with it!
&lt;/p&gt;
&lt;style&gt;
img {max-width:100%;}&lt;/style&gt;</dc:description>
      
    <dc:subject>Web</dc:subject>
     
    
  <dc:date>2012-04-19T14:25:27Z</dc:date>
    <dc:creator>w.weglinska</dc:creator>
 </item>
  <item rdf:about="http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/04/12/left-click-handler">
  <title>Little Touches - Left Click</title>
  <link>http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/04/12/left-click-handler</link>
  <dc:description>&lt;p&gt;
One of the most fulfilling aspects of web development is being able to add nice little touches that most people wouldn&#039;t even notice. These are the kind of things that web devs put in for professional pride and knowledge of a job well done. 
&lt;/p&gt;
&lt;p&gt;
One of my favourite minor additions that we&#039;ve sprinkled liberally around&amp;nbsp;&lt;a href=&quot;http://maps.nokia.com/uk/edinburgh&quot;&gt;City Pages&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href=&quot;http://maps.nokia.com&quot;&gt;Nokia Maps&lt;/a&gt;&amp;nbsp;is the &#039;Left Click Handler&#039;. 
&lt;/p&gt;
&lt;h2&gt;Background&lt;/h2&gt;
&lt;p&gt;
When you&#039;re attaching events to elements, whether using standard JS or jQuery, the standard technique is to attach to &#039;click&#039;. 
&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;jQuery:
&amp;nbsp;$(element).on(&#039;click&#039;, function() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;doSomething();
}
);&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
By default, this attaches to every variation of the click event &amp;ndash; left-click, right-click, middle-click, click while holding shift, while holding control, while holding command &amp;ndash; everything. From the developer point-of-view, this might be the easiest solution but from the user point-of-view, this isn&#039;t necessarily what you&#039;d expect. The standard browser behaviour on right-click is to show the context menu while the standard shift-click is to open a new window or tab. There are several different kinds of clicks that all fire that same event and you need to figure out which one the user actually did. Middle-click? They want the current content or application state to stay in whatever form it is in the current tab and they want whatever your handler does to happen in a new tab in the background. Are they holding down control? Alt? Command? They could be intending to do any of the above things or a number of other things. Can you guarantee you want your event handler to run for all of them?
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
jQuery has handy normalisation for events. You can use this to make a simple little check for the probable intention of the user and be a bit smart about how you handle your handlers.&amp;nbsp;
&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;
As good, conscientious developers (as I know you all are), the &#039;right thing to do&#039; is to allow the user to maintain control over their actions. Whenever a click event is detected, the first thing the code should do is check whether it was a simple left-click or something more complicated. If it was a left-click, handle it they way you always intended to, if it was anything else, handle it the way the user expects &amp;ndash; if they are trying to open the link in a new background window, let the link open in a new background window. If they want to see the right-click context menu, show them the right-click context menu. The jQuery snippet below will only call the attached event if it is a standard left-click event. Anything else will proceed according to the standard browser behaviour. 
&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;/** Attach event to element */
$(&#039;a&#039;).on(&#039;click&#039;, function(evt) {
&amp;nbsp;handleLeftClick(evt,function(evt){ // our new call
&amp;nbsp;&amp;nbsp;alert(&#039;left-click&#039;)
&amp;nbsp;}); // closing our call
});&lt;/code&gt;
&lt;/pre&gt;
&lt;pre&gt;
&lt;code&gt;
/** Wrap call to click handler to filter out non-left clicks */ 
handleLeftClick = function (evt, func, context) { 
&amp;nbsp;// Normalize Event - ensure the event is the same in all browsers 
&amp;nbsp;evt = $.event.fix(evt); 
&amp;nbsp;// Only show overlay on left click so middle click/shift-click/etc can open new tab 
&amp;nbsp;if (evt.which !== 2 &amp;amp;&amp;amp; !evt.metaKey &amp;amp;&amp;amp; !evt.shiftKey) { 
&amp;nbsp;&amp;nbsp;evt.preventDefault(); 
&amp;nbsp;&amp;nbsp;func.call(context); 
&amp;nbsp;} 
};&lt;/code&gt;&lt;style&gt;
p code {padding:0 !important;border:none !important;}
pre code {border:none !important;padding:0 !important;line-height:1.6;}
pre {position: relative;}
pre:before {content: attr(data-syntax);position: absolute;right: 15px;font-weight: bold;font-size: 1.5em;}&lt;/style&gt;
&lt;/pre&gt;</dc:description>
      
    <dc:subject>Web Technology</dc:subject>
      
    <dc:subject>Web</dc:subject>
      
    <dc:subject>Web Apps</dc:subject>
     
    
  <dc:date>2012-04-12T13:55:12Z</dc:date>
    <dc:creator>simonmadine</dc:creator>
 </item>
  <item rdf:about="http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/04/05/reliable-image-replacement">
  <title>Reliable Image Replacement</title>
  <link>http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/04/05/reliable-image-replacement</link>
  <dc:description>&lt;p class=&quot;p1&quot;&gt;
Web developers hardly have to deal with network-related issues. Most of the time the resources they have to deal with are completely under their control: images are served from a directory in the web server where the web site is hosted and perhaps cached by a content delivery network; CSS files and sprites are where they expect them to be, as well as all the other resources that contribute to the smooth functioning and good looks of their application.
&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;
Unfortunately, this is not necessarily the case when scaling up to big and complex systems. At Nokia maps we have a number of non-homogeneus systems and API that we use to retrieve the data to generate maps, routes and city and place pages. Moreover, we often deal with user-generated and 3rd-party-generated content such as reviews and photos. This normally leads to two types of issues: data consistency across different domain and missing resources. In this post I will be focusing on this last problem. More specifically I will describe how we deal with missing recommendation images in&amp;nbsp;&lt;a href=&quot;http://maps.nokia.com/city/spain/barcelona&quot; title=&quot;Barcelona City Page on Nokia Maps&quot;&gt;City Pages&lt;/a&gt;.
&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;
When a City Page for a city is generated, one important piece of information that we show to our users is a number of recommended places to visit in such city. Recommendations are then presented in a grid with name, category and a picture of the place, as shown in the picture below.
&lt;/p&gt;
&lt;p class=&quot;p1 image&quot;&gt;
&lt;img src=&quot;http://www.developer.nokia.com/Community/Blogs//data/blogs/resources/300144/recommendation-grid-small.png&quot; /&gt;
&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;
One problem that we have seen every now and then is that some of these pictures are missing. The complication is that we don&#039;t have any control on those resources: when the API we rely on tells us there is a picture for a place, we cannot do anything else but trust it. Unfortunately, sometimes the picture is simply no longer there: either the user that posted it decided to remove it, or the 3rd party provider deleted it or moved it somewhere else. Checking picture by picture in the back-end would slow down the page load quite a bit so for this reason we decided to tackle the problem on the front-end side.
&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;
Our template&amp;nbsp;delivered by the server normally contains a list of places, each of them with the related picture or a placeholder for the place category in case there are no picture for that place. The URLs to photo and placeholders are normally inserted into the DOM as&amp;nbsp;&lt;a href=&quot;http://dev.w3.org/html5/spec/global-attributes.html#embedding-custom-non-visible-data-with-the-data-attributes&quot; title=&quot;Embedding custom non-visible data with the data-* attributes&quot;&gt;data-* attributes&lt;/a&gt;&amp;nbsp;and displayed with a simple CSS rule for browsers that support&amp;nbsp;&lt;a href=&quot;http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/03/16/background-size-cover&quot;&gt;background-size: cover&lt;/a&gt;&amp;nbsp;and as an img element for non-modern browsers. This means that if the photo does not exist the user sees an empty grayish box in the best case and the little &amp;quot;missing image icon&amp;quot; in the worst case. This conveys a bad user experience.
&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;
The solution is very simple, but at the same time very effective. We basically rely on the browser to determine whether or not an image can be loaded. If the browser can&#039;t load it, then it probably does not exist, therefore we show the placeholder. In terms of code, we have the following.
&lt;/p&gt;
&lt;h3&gt;
HTML&amp;nbsp;
&lt;/h3&gt;
&lt;pre&gt;
&lt;code&gt;
&amp;lt;ul&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&amp;nbsp;data-image=&amp;quot;http://lorempixel.com/120/100/sports&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data-placeholder=&amp;quot;http://placehold.it/120x100&amp;quot;&amp;gt;&amp;lt;h3&amp;gt;Sport&amp;lt;/h3&amp;gt;&amp;lt;/li&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&amp;nbsp;data-image=&amp;quot;http://lorempixel.com/120/100/food&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data-placeholder=&amp;quot;http://placehold.it/120x100&amp;quot;&amp;gt;&amp;lt;h3&amp;gt;Food&amp;lt;/h3&amp;gt;&amp;lt;/li&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&amp;nbsp;data-image=&amp;quot;http://lorempixel.com/120/100/people&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data-placeholder=&amp;quot;http://placehold.it/120x100&amp;quot;&amp;gt;&amp;lt;h3&amp;gt;People&amp;lt;/h3&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;​
&lt;/code&gt;
&lt;/pre&gt;
&lt;h3&gt;
CSS
&lt;/h3&gt;
&lt;pre&gt;
&lt;code&gt;
ul&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;overflow:&amp;nbsp;hidden;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;width:&amp;nbsp;260px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;margin:&amp;nbsp;20px&amp;nbsp;auto;
}
li&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;width:&amp;nbsp;120px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;height:&amp;nbsp;100px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float:&amp;nbsp;left;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;background-color:&amp;nbsp;#ccc;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;position:&amp;nbsp;relative;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;border:&amp;nbsp;1px&amp;nbsp;solid&amp;nbsp;#999;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;margin:&amp;nbsp;2px;
}
li&amp;nbsp;h3&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;font-family:&amp;nbsp;&#039;Oleo&amp;nbsp;Script&#039;,&amp;nbsp;cursive;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;position:&amp;nbsp;absolute;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;top:&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;left:&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;right:&amp;nbsp;0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;height:&amp;nbsp;32px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;font-size:&amp;nbsp;24px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;line-height:&amp;nbsp;32px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;background-color:&amp;nbsp;rgba(0,0,0,0.7);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;color:&amp;nbsp;#fff;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;text-align:&amp;nbsp;center;
}
​
&lt;/code&gt;
&lt;/pre&gt;
&lt;h3&gt;
JavaScript
&lt;/h3&gt;
&lt;p class=&quot;p1&quot;&gt;
Again I used jQuery to simplify, but it easy very easy to do this without relying on frameworks.
&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
$(function()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Go&amp;nbsp;through&amp;nbsp;all&amp;nbsp;the&amp;nbsp;elements&amp;nbsp;that&amp;nbsp;should&amp;nbsp;have&amp;nbsp;a&amp;nbsp;background
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&#039;li&#039;).each(function()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;$this&amp;nbsp;=&amp;nbsp;$(this),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;img&amp;nbsp;=&amp;nbsp;$this.data(&#039;image&#039;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ph&amp;nbsp;=&amp;nbsp;$this.data(&#039;placeholder&#039;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;imgObject;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//First&amp;nbsp;of&amp;nbsp;all,&amp;nbsp;by&amp;nbsp;default&amp;nbsp;assign&amp;nbsp;the&amp;nbsp;placeholder&amp;nbsp;image&amp;nbsp;to&amp;nbsp;all&amp;nbsp;of&amp;nbsp;them
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//This&amp;nbsp;way&amp;nbsp;if&amp;nbsp;an&amp;nbsp;image&amp;nbsp;fails&amp;nbsp;to&amp;nbsp;load&amp;nbsp;the&amp;nbsp;UI&amp;nbsp;is&amp;nbsp;not&amp;nbsp;affected
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$this.css(&#039;background-image&#039;,&amp;nbsp;&#039;url(&#039;&amp;nbsp;+&amp;nbsp;ph&amp;nbsp;+&amp;nbsp;&#039;)&#039;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Now&amp;nbsp;create&amp;nbsp;an&amp;nbsp;empty&amp;nbsp;Image&amp;nbsp;object&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;imgObject&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Image();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Should&amp;nbsp;an&amp;nbsp;image&amp;nbsp;fail&amp;nbsp;to&amp;nbsp;load&amp;nbsp;(e.g.&amp;nbsp;404),&amp;nbsp;replace&amp;nbsp;the&amp;nbsp;image&amp;nbsp;data&amp;nbsp;with&amp;nbsp;the&amp;nbsp;placeholder
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//in&amp;nbsp;case&amp;nbsp;we&amp;nbsp;need&amp;nbsp;to&amp;nbsp;use&amp;nbsp;it&amp;nbsp;later
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;imgObject.onerror&amp;nbsp;=&amp;nbsp;function()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$this.data(&#039;image&#039;,&amp;nbsp;ph);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//When&amp;nbsp;the&amp;nbsp;image&amp;nbsp;finally&amp;nbsp;loads,&amp;nbsp;replace&amp;nbsp;the&amp;nbsp;background&amp;nbsp;with&amp;nbsp;the&amp;nbsp;final&amp;nbsp;one
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;imgObject.onload&amp;nbsp;=&amp;nbsp;function()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$this.css(&#039;background-image&#039;,&amp;nbsp;&#039;url(&#039;&amp;nbsp;+&amp;nbsp;img&amp;nbsp;+&amp;nbsp;&#039;)&#039;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Assign&amp;nbsp;the&amp;nbsp;src&amp;nbsp;property:&amp;nbsp;this&amp;nbsp;forces&amp;nbsp;the&amp;nbsp;browser&amp;nbsp;to&amp;nbsp;preload&amp;nbsp;and
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//possibly&amp;nbsp;cache&amp;nbsp;the&amp;nbsp;image&amp;nbsp;and&amp;nbsp;eventually&amp;nbsp;either&amp;nbsp;the&amp;nbsp;onload&amp;nbsp;or&amp;nbsp;the&amp;nbsp;onerror
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//event&amp;nbsp;will&amp;nbsp;be&amp;nbsp;triggered.
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;imgObject.src&amp;nbsp;=&amp;nbsp;img;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
});​
​&lt;/code&gt;
&lt;/pre&gt;
&lt;p class=&quot;p1&quot;&gt;
The JavaScript code as I said is very simple and it is pretty well commented, so I believe it does not need any further explanation. If you have any questions though, feel free to ask in the comments section.
&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;
In the&amp;nbsp;&lt;a href=&quot;http://jsfiddle.net/mmarcon/PRFS7/show/&quot; title=&quot;Reliable Image Replacement Demo&quot;&gt;full demo&lt;/a&gt;&amp;nbsp;I included an additional list element in the HTML that points to an image with invalid URL. The bottom-right element will therefore show the placeholder. All the code is available as a&amp;nbsp;&lt;a href=&quot;http://jsfiddle.net/mmarcon/PRFS7/&quot; title=&quot;Reliable Image Replacement JSFiddle&quot;&gt;JSFiddle&lt;/a&gt;.
&lt;/p&gt;
&lt;style&gt;
.example-pair {overflow:hidden;margin:0 auto !important; width:400px;}
.example-pair li {float:right;list-style:none;}
.example-pair li:first-child {float:left;}
.example-box {margin: 0px;background-position: 50% 50%; background-repeat: no-repeat no-repeat; background-color: black; border-width: 1px; border-color: #444444; border-style: solid; background-image: url(&#039;http://www.developer.nokia.com/Community/Blogs/data/blogs/resources/300144/example-icon.png&#039;); }
p code {padding:0 !important;border:none !important;}
pre code {border:none !important;padding:0 !important;}
pre {position: relative;}
pre:before {content: attr(data-syntax);position: absolute;right: 15px;font-weight: bold;font-size: 1.5em;}
p.image{text-align: center;}
&lt;/style&gt;</dc:description>
      
    <dc:subject>UI</dc:subject>
      
    <dc:subject>Web Technology</dc:subject>
      
    <dc:subject>Web</dc:subject>
     
    
  <dc:date>2012-04-05T00:13:22Z</dc:date>
    <dc:creator>mmarcon</dc:creator>
 </item>
  <item rdf:about="http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/03/29/carousel">
  <title>Build your own carousel</title>
  <link>http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/03/29/carousel</link>
  <dc:description>&lt;p&gt;
Nowadays, whatever effect or component a developer may need for a website or web application is available in the form of a jQuery plugin. Every other day I see a blog post with a title like &amp;quot;The best 25 jQuery carousels&amp;quot; or &amp;quot;The best 50 photo gallery plugins for jQuery&amp;quot;.
Alright, I get it, one should not reinvent the wheel: if somebody builds a plugin that suits your needs it makes sense to use it rather than spending time reimplementing the whole thing from scratch by yourself.
Unfortunately too many times developers are willing to adapt their markup or even their layout to accommodate the requirements of the plugin they use. Often plugins expose several features and support endless options for customization: while this may result very convenient, the price is a quite large amount of code that in most cases is unnecessary. This translates to more bytes (or kilobytes) delivered to the user&#039;s browser and possibly an increased perceived loading time for the web page containing the widget.
&lt;/p&gt;
&lt;p&gt;
In situations where keeping the codebase small and efficient is crucial, it is probably worth to invest a little time and write a completely customized component from scratch, strictly based on the needs. Eventually with a few bytes more the widget can be converted to a simple plugin in case it has to be used in other pages or application components.
In the last few weeks at&amp;nbsp;&lt;a href=&quot;http://maps.nokia.com/city/germany/berlin&quot; title=&quot;Berlin City Page&quot;&gt;City Pages&lt;/a&gt;&amp;nbsp;we have been working on a new feature that required a carousel to nicely display some information to the user. After a quick analysis of the problem we chose to implement our own little carousel instead of relying on any of the thousands of plugins out there: this way we could quickly come up with a completely customized carousel component with only a few lines of JavaScript and some small changes to our CSS file.
In this post I am going to explain how to build a carousel using jQuery and some CSS tricks, following the steps we took when developing the one for City Pages.
&lt;/p&gt;
&lt;h3&gt;The idea&lt;/h3&gt;
&lt;p&gt;
Here is what the final carousel will look like.
&lt;/p&gt;
&lt;p class=&quot;image&quot;&gt;
&lt;img src=&quot;http://www.developer.nokia.com/Community/Blogs//data/blogs/resources/300144/shot.png&quot; alt=&quot;Carousel Screenshot&quot; align=&quot;middle&quot; /&gt;&amp;nbsp;&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The carousel will slide horizontally with a nice sliding animation and will be a circular carousel in the sense that after the last item the first one is shown. In order to obtain this circular effect the carousel items will be arranged by the script as follows:
&lt;/p&gt;
&lt;p class=&quot;image&quot;&gt;
&lt;img src=&quot;http://www.developer.nokia.com/Community/Blogs//data/blogs/resources/300144/CarouselDiagram.png&quot; alt=&quot;Carousel Diagram&quot; /&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The last item is cloned and placed before all the other items and the first item is cloned and appended at the end. When the viewport is showing number 1, sliding backwards animates to the cloned version of number 3 and then seamlessly changes the viewport to the actual number 3.
The next sections describe in details the markup and CSS for the carousel and the JavaScript code that creates the interaction.
&lt;/p&gt;
&lt;h3&gt;The markup&lt;/h3&gt;
&lt;p&gt;
First of all we need some markup. It can be either generated on the server side - good for SEO purpose - or dynamically created front-end side, but here is what it should look like:
&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
&amp;lt;!--&amp;nbsp;A&amp;nbsp;container&amp;nbsp;for&amp;nbsp;the&amp;nbsp;carousel&amp;nbsp;--&amp;gt;
&amp;lt;div&amp;nbsp;class=&amp;quot;carousel-wrapper&amp;quot;&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;!--&amp;nbsp;The&amp;nbsp;actual&amp;nbsp;carousel&amp;nbsp;--&amp;gt;
&amp;lt;ul&amp;nbsp;class=&amp;quot;carousel&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&amp;nbsp;class=&amp;quot;item&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;img&amp;nbsp;src=&amp;quot;some/image/here.png&amp;quot;&amp;nbsp;alt=&amp;quot;&amp;quot;/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;nbsp;class=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;!--&amp;nbsp;Item&amp;nbsp;text&amp;nbsp;here&amp;nbsp;--&amp;gt;&amp;lt;/p&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/li&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&amp;nbsp;class=&amp;quot;item&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;img&amp;nbsp;src=&amp;quot;some/image/here.png
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;nbsp;class=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;!--&amp;nbsp;Item&amp;nbsp;text&amp;nbsp;here&amp;nbsp;--&amp;gt;&amp;lt;/p&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/li&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&amp;nbsp;class=&amp;quot;item&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;img&amp;nbsp;src=&amp;quot;some/image/here.png
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;nbsp;class=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;!--&amp;nbsp;Item&amp;nbsp;text&amp;nbsp;here&amp;nbsp;--&amp;gt;&amp;lt;/p&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/li&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&amp;nbsp;class=&amp;quot;item&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;img&amp;nbsp;src=&amp;quot;some/image/here.png
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;p&amp;nbsp;class=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;!--&amp;nbsp;Item&amp;nbsp;text&amp;nbsp;here&amp;nbsp;--&amp;gt;&amp;lt;/p&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;!--&amp;nbsp;The&amp;nbsp;prev/next&amp;nbsp;controls&amp;nbsp;--&amp;gt;
&amp;lt;div&amp;nbsp;class=&amp;quot;carousel-nav&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;a&amp;nbsp;href=&amp;quot;&amp;quot;&amp;nbsp;class=&amp;quot;prev&amp;quot;&amp;gt;&amp;amp;lt;&amp;lt;/a&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;a&amp;nbsp;href=&amp;quot;&amp;quot;&amp;nbsp;class=&amp;quot;next&amp;quot;&amp;gt;&amp;amp;gt;&amp;lt;/a&amp;gt;&amp;nbsp;&amp;nbsp;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
There is not much to say here: we have a wrapper block that contains the carousel itself and the navigation controls. The carousel is a ul element and the carousel items as expected are li elements in a perfectly semantic and SEO friendly fashion.
&lt;/p&gt;
&lt;h3&gt;The CSS&lt;/h3&gt;
&lt;p&gt;
As shown in the diagram above, the idea is to place the items horizontally, and set the viewport size so only one of them at the time is visible. In our case the viewport is the wrapper element, and what we want to obtain is a wide ul that slides left and right within the wrapper to show the active item and hide all the others. The images will always represent the background of the carousel items and the text will be displayed on the right. We also want the carousel controls to be always shown on the left and on the right of the wrapper horizontally centered. Additionally we will add some rules to make it beautiful.
&lt;/p&gt;
&lt;p&gt;
In order to accomplish that we&#039;ll add the following CSS rules:
&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
.carousel-wrapper&amp;nbsp;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;position:&amp;nbsp;relative;&amp;nbsp;/*Reference&amp;nbsp;for&amp;nbsp;absolutely&amp;nbsp;positioned&amp;nbsp;descendants*/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;width:&amp;nbsp;800px;&amp;nbsp;/*Actual&amp;nbsp;width&amp;nbsp;each&amp;nbsp;item&amp;nbsp;should&amp;nbsp;have*/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;height:&amp;nbsp;240px;&amp;nbsp;/*Actual&amp;nbsp;height&amp;nbsp;each&amp;nbsp;item&amp;nbsp;should&amp;nbsp;have*/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;overflow:&amp;nbsp;hidden;&amp;nbsp;/*So&amp;nbsp;only&amp;nbsp;one&amp;nbsp;item&amp;nbsp;is&amp;nbsp;visible*/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;border-top:&amp;nbsp;1px&amp;nbsp;dotted&amp;nbsp;#ccc;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;border-bottom:&amp;nbsp;1px&amp;nbsp;dotted&amp;nbsp;#ccc;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;margin:&amp;nbsp;20px&amp;nbsp;0;
}
.carousel&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;position:&amp;nbsp;absolute;&amp;nbsp;/*This&amp;nbsp;way&amp;nbsp;we&amp;nbsp;can&amp;nbsp;dynamically&amp;nbsp;&amp;quot;move&amp;quot;&amp;nbsp;the&amp;nbsp;ul&amp;nbsp;from&amp;nbsp;the&amp;nbsp;JavaScript&amp;nbsp;by&amp;nbsp;changing&amp;nbsp;the&amp;nbsp;left*/
}
.carousel&amp;nbsp;li&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;display:&amp;nbsp;block;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float:&amp;nbsp;left;&amp;nbsp;/*Place&amp;nbsp;items&amp;nbsp;horizontally*/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;width:&amp;nbsp;800px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;height:&amp;nbsp;240px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;position:&amp;nbsp;relative;&amp;nbsp;/*Reset&amp;nbsp;the&amp;nbsp;reference&amp;nbsp;to&amp;nbsp;absolutely&amp;nbsp;position&amp;nbsp;children*/
}
.carousel&amp;nbsp;img&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;position:&amp;nbsp;absolute;&amp;nbsp;/*Goes&amp;nbsp;top-left&amp;nbsp;(note&amp;nbsp;that&amp;nbsp;we&amp;nbsp;work&amp;nbsp;under&amp;nbsp;the&amp;nbsp;assumption&amp;nbsp;that&amp;nbsp;the&amp;nbsp;image&amp;nbsp;is&amp;nbsp;the&amp;nbsp;right&amp;nbsp;size)*/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;z-index:&amp;nbsp;0;&amp;nbsp;/*Goes&amp;nbsp;below&amp;nbsp;everything*/
}
.carousel&amp;nbsp;p.text&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;position:&amp;nbsp;absolute;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;z-index:&amp;nbsp;1;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;font-size:&amp;nbsp;24px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;width:&amp;nbsp;340px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;right:&amp;nbsp;80px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;top:&amp;nbsp;10px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;color:&amp;nbsp;#ff6347;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;background-color:&amp;nbsp;#111111;&amp;nbsp;/*IE&amp;nbsp;tolerant*/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;background-color:&amp;nbsp;rgba(0,0,0,0.7);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;padding:&amp;nbsp;5px;
}
.carousel-nav&amp;nbsp;a&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;display:&amp;nbsp;block;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;height:&amp;nbsp;40px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;width:&amp;nbsp;30px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;font-size:&amp;nbsp;24px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;line-height:&amp;nbsp;1.6;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;font-weight:&amp;nbsp;800;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;color:&amp;nbsp;#222222;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;background-color:&amp;nbsp;rgb(255,99,71);&amp;nbsp;/*IE&amp;nbsp;tolerant*/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;background-color:&amp;nbsp;rgba(255,99,71,0.7);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;text-decoration:&amp;nbsp;none;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;padding:&amp;nbsp;0&amp;nbsp;4px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;position:&amp;nbsp;absolute;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;top:&amp;nbsp;50%;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;margin-top:&amp;nbsp;-20px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;text-align:&amp;nbsp;center;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;z-index:&amp;nbsp;10;&amp;nbsp;/*Always&amp;nbsp;on&amp;nbsp;top*/
}
.carousel-nav&amp;nbsp;a.prev&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;left:&amp;nbsp;0;&amp;nbsp;/*Prev&amp;nbsp;goes&amp;nbsp;on&amp;nbsp;the&amp;nbsp;left*/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-webkit-border-top-right-radius:&amp;nbsp;4px;&amp;nbsp;/*Some&amp;nbsp;rounded&amp;nbsp;corners&amp;nbsp;fanciness*/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-webkit-border-bottom-right-radius:&amp;nbsp;4px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-moz-border-radius-topright:&amp;nbsp;4px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-moz-border-radius-bottomright:&amp;nbsp;4px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;border-top-right-radius:&amp;nbsp;4px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;border-bottom-right-radius:&amp;nbsp;4px;
}
.carousel-nav&amp;nbsp;a.next&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;right:&amp;nbsp;0;&amp;nbsp;/*Next&amp;nbsp;goes&amp;nbsp;on&amp;nbsp;the&amp;nbsp;right*/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-webkit-border-top-left-radius:&amp;nbsp;4px;&amp;nbsp;/*Some&amp;nbsp;rounded&amp;nbsp;corners&amp;nbsp;fanciness*/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-webkit-border-bottom-left-radius:&amp;nbsp;4px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-moz-border-radius-topleft:&amp;nbsp;4px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-moz-border-radius-bottomleft:&amp;nbsp;4px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;border-top-left-radius:&amp;nbsp;4px;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;border-bottom-left-radius:&amp;nbsp;4px;
}
&lt;/code&gt;
&lt;/pre&gt;
&lt;h3&gt;The JavaScript&lt;/h3&gt;
&lt;p&gt;
We will use jQuery for simplicity. The following code registers event handlers for the carousel controls, handles sliding animation and repositions the ul element when necessary.
&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
//We&amp;nbsp;don&#039;t&amp;nbsp;want&amp;nbsp;to&amp;nbsp;poison&amp;nbsp;the&amp;nbsp;global&amp;nbsp;scope
//therefore&amp;nbsp;we&amp;nbsp;wrap&amp;nbsp;everything&amp;nbsp;into&amp;nbsp;an&amp;nbsp;anonymous&amp;nbsp;self-executing&amp;nbsp;function
(function()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;first&amp;nbsp;=&amp;nbsp;$(&#039;.item&#039;).first(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;last&amp;nbsp;=&amp;nbsp;$(&#039;.item&#039;).last(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;itemWidth&amp;nbsp;=&amp;nbsp;first.width(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;carousel&amp;nbsp;=&amp;nbsp;$(&#039;.carousel&#039;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Adds&amp;nbsp;the&amp;nbsp;clones&amp;nbsp;of&amp;nbsp;the&amp;nbsp;first&amp;nbsp;and&amp;nbsp;last&amp;nbsp;items,&amp;nbsp;as&amp;nbsp;shown&amp;nbsp;in&amp;nbsp;reddish&amp;nbsp;in&amp;nbsp;the&amp;nbsp;picture&amp;nbsp;above
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;carousel.prepend(last.clone()).append(first.clone());
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Determine&amp;nbsp;the&amp;nbsp;width&amp;nbsp;the&amp;nbsp;carousel&amp;nbsp;ul&amp;nbsp;should&amp;nbsp;have
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;carousel.width(itemWidth&amp;nbsp;*&amp;nbsp;$(&#039;.item&#039;).length);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Scroll&amp;nbsp;to&amp;nbsp;the&amp;nbsp;right&amp;nbsp;position&amp;nbsp;to&amp;nbsp;show&amp;nbsp;the&amp;nbsp;first&amp;nbsp;element
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;carousel.css({left:&amp;nbsp;-itemWidth});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Setup&amp;nbsp;handlers...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&#039;.prev&#039;).on(&#039;click&#039;,&amp;nbsp;function(e){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.preventDefault();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Some&amp;nbsp;nice&amp;nbsp;sliding&amp;nbsp;animation
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;carousel.animate({left:&amp;nbsp;&#039;+=&#039;&amp;nbsp;+&amp;nbsp;itemWidth},&amp;nbsp;300,&amp;nbsp;function(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(Math.abs(carousel.position().left)&amp;nbsp;&amp;lt;&amp;nbsp;2)&amp;nbsp;{&amp;nbsp;//See Note below
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Handles&amp;nbsp;circular&amp;nbsp;carousel&amp;nbsp;when&amp;nbsp;we&amp;nbsp;get&amp;nbsp;to&amp;nbsp;the&amp;nbsp;left&amp;nbsp;as&amp;nbsp;much&amp;nbsp;as&amp;nbsp;possible
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;carousel.css({left:&amp;nbsp;-itemWidth&amp;nbsp;*&amp;nbsp;(carousel.children().length&amp;nbsp;-&amp;nbsp;2)});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;false;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&#039;.next&#039;).on(&#039;click&#039;,&amp;nbsp;function(e){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.preventDefault();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;carousel.animate({left:&amp;nbsp;&#039;-=&#039;&amp;nbsp;+&amp;nbsp;itemWidth},&amp;nbsp;300,&amp;nbsp;function(){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(Math.abs(carousel.position().left&amp;nbsp;+&amp;nbsp;itemWidth&amp;nbsp;*&amp;nbsp;(carousel.children().length&amp;nbsp;-&amp;nbsp;1))&amp;nbsp;&amp;lt;&amp;nbsp;2)&amp;nbsp;{&amp;nbsp;//See Note below
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Handles&amp;nbsp;circular&amp;nbsp;carousel&amp;nbsp;when&amp;nbsp;we&amp;nbsp;get&amp;nbsp;to&amp;nbsp;the&amp;nbsp;right&amp;nbsp;as&amp;nbsp;much&amp;nbsp;as&amp;nbsp;possible
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;carousel.css({left:&amp;nbsp;-itemWidth});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;false;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
})();
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
&lt;strong&gt;
Note:&lt;/strong&gt;&amp;nbsp;instead of comparing the current position with 0 in the &lt;em&gt;previous &lt;/em&gt;case and to itemWidth * (carousel.children().length - 1) in the &lt;em&gt;next &lt;/em&gt;case we compare the absolute value and the absolute value of the difference with 2 (2px) respectively. The reason for this is that we noticed older versions of IE do some sort of approximation and the value was never 0 as one would expect. This way the code is more tolerant to this sort of browser weirdnesses.
&lt;/p&gt;
&lt;p&gt;
And finally the&amp;nbsp;&lt;a href=&quot;http://jsfiddle.net/mmarcon/UWbrQ/show/&quot; title=&quot;Carousel Demo&quot;&gt;working demo&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href=&quot;http://jsfiddle.net/mmarcon/UWbrQ/&quot; title=&quot;jQuery Carousel JSFiddle&quot;&gt;all the code&lt;/a&gt;. The page was tested with Chrome, Firefox 9+, Safari, IE8 and IE9.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update:&lt;/strong&gt;&amp;nbsp;we just released an updated version of City Pages, where you can see the carousel in action for displaying&amp;nbsp;&lt;a href=&quot;http://maps.nokia.com/city/italy/rome&quot; title=&quot;Rome City Page with City Facts&quot;&gt;City Facts&lt;/a&gt;.
&lt;/p&gt;
&lt;style&gt;
.example-pair {overflow:hidden;margin:0 auto !important; width:400px;}
.example-pair li {float:right;list-style:none;}
.example-pair li:first-child {float:left;}
.example-box {margin: 0px;background-position: 50% 50%; background-repeat: no-repeat no-repeat; background-color: black; border-width: 1px; border-color: #444444; border-style: solid; background-image: url(&#039;http://www.developer.nokia.com/Community/Blogs/data/blogs/resources/300144/example-icon.png&#039;); }
p code {padding:0 !important;border:none !important;}
pre code {border:none !important;padding:0 !important;}
pre {position: relative;}
pre:before {content: attr(data-syntax);position: absolute;right: 15px;font-weight: bold;font-size: 1.5em;}
p.image{text-align: center}
&lt;/style&gt;</dc:description>
      
    <dc:subject>UI</dc:subject>
      
    <dc:subject>Web Technology</dc:subject>
      
    <dc:subject>Web</dc:subject>
      
    <dc:subject>Web Apps</dc:subject>
     
    
  <dc:date>2012-03-29T09:00:28Z</dc:date>
    <dc:creator>mmarcon</dc:creator>
 </item>
  <item rdf:about="http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/03/23/simple-servers">
  <title>Quick Tip: Simple Servers</title>
  <link>http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/03/23/simple-servers</link>
  <dc:description>&lt;p&gt;
Often, when hacking around with various APIs, you&#039;ll find yourself needing to load in some data via &lt;acronym title=&quot;Asynchronous JavaScript And XML&quot;&gt;AJAX&lt;/acronym&gt; or load a script from another domain. Depending on which technique or library you&#039;re using at the time, this can cause a security error. This error is due to the fact that the file you&#039;re hacking away at comes direct from the local file system (&lt;code&gt;file://&lt;/code&gt;) while the data or external library you&#039;re loading comes from somewhere out there on the internet (&lt;code&gt;http://&lt;/code&gt;). Browsers, quite sensibly, prevent local JS files from pulling in remote ones to avoid all manner of potential security issues. If you&#039;ve ever seen an error in the console about &lt;code&gt;access-control-allow-origin&lt;/code&gt; or &#039;&lt;code&gt;Cross-origin requests are only supported for HTTP&lt;/code&gt;&#039;, you now know why. 
&lt;/p&gt;
&lt;p&gt;
The simplest way to avoid this is to access your files via a web server running on your own machine and there are many ways to do this - &lt;a href=&quot;http://www.apachefriends.org/en/xampp.html&quot;&gt;XAMPP&lt;/a&gt;, &lt;a href=&quot;https://gist.github.com/701407&quot;&gt;node.js&lt;/a&gt;, etc. Apache is even built into OS X and can be enabled under System Preferences &amp;gt; Sharing &amp;gt; Web Sharing. For the absolute simplest method on OS X, however, I find nothing can beat python. Just open Terminal, cd to the directory you&#039;re developing in and run:
&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;python -m SimpleHTTPServer&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
This starts the Python interpreter with the &lt;a href=&quot;http://docs.python.org/library/simplehttpserver.html&quot;&gt;SimpleHTTPServer module&lt;/a&gt; - an extremely simple web server - running on port 8000 by default. You can now access your project at:
&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;http://localhost:8000/filename.html&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
The benefit of this technique over using OS X&#039;s built-in Apache Server is that you don&#039;t need to worry about moving files around or creating local host aliases or anything like that.
&lt;/p&gt;
&lt;p&gt;
A cross-platform alternative to this is &lt;a href=&quot;http://code.google.com/p/mongoose/&quot;&gt;Mongoose&lt;/a&gt; which functions in much the same way but also runs on Windows and Linux as well as OS X.
&lt;/p&gt;
&lt;p&gt;
Learn more about &lt;a href=&quot;https://developer.mozilla.org/en/http_access_control&quot;&gt;HTTP access control&lt;/a&gt; and &lt;a href=&quot;https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript&quot;&gt;cross-origin errors&lt;/a&gt; on the MDN site.
&lt;/p&gt;
&lt;style&gt;
.example-pair {overflow:hidden;margin:0 auto !important; width:400px;}
.example-pair li {float:right;list-style:none;}
.example-pair li:first-child {float:left;}
.example-box {margin: 0px;background-position: 50% 50%; background-repeat: no-repeat no-repeat; background-color: black; border-width: 1px; border-color: #444444; border-style: solid; background-image: url(&#039;http://www.developer.nokia.com/Community/Blogs/data/blogs/resources/300144/example-icon.png&#039;); }
p code {padding:0 !important;border:none !important;}
pre code {border:none !important;padding:0 !important;}
pre {position: relative;}
pre:before {content: attr(data-syntax);position: absolute;right: 15px;font-weight: bold;font-size: 1.5em;}
&lt;/style&gt;</dc:description>
      
    <dc:subject>Web Technology</dc:subject>
      
    <dc:subject>Web</dc:subject>
      
    <dc:subject>Web Apps</dc:subject>
     
    
  <dc:date>2012-03-23T08:00:32Z</dc:date>
    <dc:creator>simonmadine</dc:creator>
 </item>
  <item rdf:about="http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/03/16/background-size-cover">
  <title>Dynamic backgrounds with background-size: cover</title>
  <link>http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/03/16/background-size-cover</link>
  <dc:description>&lt;p&gt;
&lt;em&gt;This is a two-part article. The second part will be covered in a future post.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
There are some fantastic styles available now in CSS3. Apart from anything else, border-radius and box-shadow alone are the greatest tools to be added to the web developer&#039;s toolbox since &lt;code&gt;float:left&lt;/code&gt;. Alongside these highly important and commonly used attributes, there are also some new values for existing rules like background-size:cover.
&lt;/p&gt;
&lt;p&gt;
When we started developing the &lt;a href=&quot;http://maps.nokia.com/city/germany/berlin&quot;&gt;City pages&lt;/a&gt;, The large header image lent itself perfectly to using background cover.  What this attribute does is tell the browser to scale the background image proportionally so that it is always &lt;em&gt;at least&lt;/em&gt; covers the entire area. This usually means that in one dimension (horizontal, for example), the left edge of the image will be at the left edge of the box and the right will be at the right. The top and bottom of the image will most likely disappear off the top and bottom of the area as it is scaled up:
&lt;/p&gt;
&lt;ul class=&quot;example-pair&quot;&gt;
	&lt;li&gt;
	&lt;h3&gt;Example:&lt;/h3&gt;
	&lt;div class=&quot;example-box&quot; style=&quot;width: 180px; height: 100px; background-size: cover&quot;&gt;
	&lt;/div&gt;
	&lt;/li&gt;
	&lt;li&gt;
	&lt;h3&gt;What it should look like:&lt;/h3&gt;
	&lt;img src=&quot;http://www.developer.nokia.com/Community/Blogs/data/blogs/resources/300144/bg-cover-1.png&quot; alt=&quot;Background Cover Example 1&quot; /&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
&lt;code&gt;
div {
&amp;nbsp;width: 180px;
&amp;nbsp;height: 100px;
&amp;nbsp;background-size: cover;
}
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
However, if the box were to be narrower, the cropped bits would come back:
&lt;/p&gt;
&lt;ul class=&quot;example-pair&quot;&gt;
	&lt;li&gt;
	&lt;h3&gt;Example:&lt;/h3&gt;
	&lt;div class=&quot;example-box&quot; style=&quot;width: 100px; height: 100px; background-size: cover&quot;&gt;
	&lt;/div&gt;
	&lt;/li&gt;
	&lt;li&gt;
	&lt;h3&gt;What it should look like:&lt;/h3&gt;
	&lt;img src=&quot;http://www.developer.nokia.com/Community/Blogs/data/blogs/resources/300144/bg-cover-2.png&quot; alt=&quot;Background Cover Example 2&quot; /&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
&lt;code&gt;
div {
&amp;nbsp;width: 100px;
&amp;nbsp;height: 100px;
&amp;nbsp;background-size: cover;
}
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
Narrower still and the left and right would disappear while the top and bottom remained:
&lt;/p&gt;
&lt;ul class=&quot;example-pair&quot;&gt;
	&lt;li&gt;
	&lt;h3&gt;Example:&lt;/h3&gt;
	&lt;div class=&quot;example-box&quot; style=&quot;width: 75px; height: 100px; background-size: cover&quot;&gt;
	&lt;/div&gt;
	&lt;/li&gt;
	&lt;li&gt;
	&lt;h3&gt;What it should look like:&lt;/h3&gt;
	&lt;img src=&quot;http://www.developer.nokia.com/Community/Blogs/data/blogs/resources/300144/bg-cover-3.png&quot; alt=&quot;Background Cover Example 3&quot; /&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
&lt;code&gt;
div {
&amp;nbsp;width: 75px;
&amp;nbsp;height: 100px;
&amp;nbsp;background-size: cover;
}
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
The opposite of background-size: cover is background-size: contain. This makes the &#039;longest&#039; edge stay inside the box meaning that nothing is clipped:
&lt;/p&gt;
&lt;ul class=&quot;example-pair&quot;&gt;
	&lt;li&gt;
	&lt;h3&gt;Example:&lt;/h3&gt;
	&lt;div class=&quot;example-box&quot; style=&quot;width: 75px; height: 100px; background-size: contain&quot;&gt;
	&lt;/div&gt;
	&lt;/li&gt;
	&lt;li&gt;
	&lt;h3&gt;What it should look like:&lt;/h3&gt;
	&lt;img src=&quot;http://www.developer.nokia.com/Community/Blogs/data/blogs/resources/300144/bg-cover-4.png&quot; alt=&quot;Background Cover Example 4&quot; /&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
&lt;code&gt;
div {
&amp;nbsp;width: 75px;
&amp;nbsp;height: 100px;
&amp;nbsp;background-size: contain;
}
&lt;/code&gt;
&lt;/pre&gt;
&lt;h3&gt;Fallback&lt;/h3&gt;
&lt;p&gt;
Obviously, when you&#039;re using new features of CSS3, you&#039;ve got to make sure browsers which don&#039;t support those features don&#039;t end up being ignored. In most cases, little touches like a subtle border-radius won&#039;t degrade the experience but for larger effects like the behaviour of our main header image, we drop in some JS-powered alternatives.
&lt;/p&gt;
&lt;p&gt;
If the browser doesn&#039;t support background-size:cover, we create a new image element, set its src attribute to the same as the normal background-image url and insert it into the document. By setting its width to be 100%, it will scale correctly, pretty much matching the original intended behaviour.
&lt;/p&gt;
&lt;p&gt;
This can be accomplished various ways but you can do it simply with jQuery along these lines:
&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;
if ($.browser.msie &amp;amp;&amp;amp; $.browser.version &amp;lt; 10) {
&amp;nbsp;var $backgroundReplacement = $(&#039;&amp;lt;img class=&amp;quot;background-replacement&amp;quot; /&amp;gt;&#039;),
&amp;nbsp;$header = $(&#039;div.header&#039;),
&amp;nbsp;imgURL = $header.css(&#039;background-image&#039;);
&amp;nbsp;$header.css(&#039;background-image&#039;, &#039;none&#039;);
&amp;nbsp;imgURL = imgURL.substring(5, imgURL.length - 2);
&amp;nbsp;$backgroundReplacement.attr(&#039;src&#039;, imgURL);
&amp;nbsp;$header.append($backgroundReplacement);
}
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
While the CSS is like this:
&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;.background-replacement {
&amp;nbsp;width: 100%;
&amp;nbsp;display: block;
&amp;nbsp;position: absolute;
&amp;nbsp;min-width: 1280px;
&amp;nbsp;min-height: 390px;
}&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
Where &lt;code&gt;min-width&lt;/code&gt; and &lt;code&gt;min-height&lt;/code&gt; are the dimensions of your  container. Handily, there&#039;s a jQuery plugin which can also do this for you:&amp;nbsp;&lt;a href=&quot;https://github.com/danmillar/jquery-anystretch&quot;&gt;jQuery Anystretch&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Of course, once you start scaling images up, things can start to get a little messy. Having a low-resolution image stretched across your page can end up looking quite bad so the second part of this article will cover a technique you can use to get around this.
&lt;/p&gt;
&lt;style&gt;
.example-pair {overflow:hidden;margin:0 auto !important; width:400px;}
.example-pair li {float:right;list-style:none;}
.example-pair li:first-child {float:left;}
.example-box {margin: 0px;background-position: 50% 50%; background-repeat: no-repeat no-repeat; background-color: black; border-width: 1px; border-color: #444444; border-style: solid; background-image: url(&#039;http://www.developer.nokia.com/Community/Blogs/data/blogs/resources/300144/example-icon.png&#039;); }
p code {padding:0 !important;border:none !important;}
pre code {border:none !important;padding:0 !important;}
pre {position: relative;}
pre:before {content: attr(data-syntax);position: absolute;right: 15px;font-weight: bold;font-size: 1.5em;}
&lt;/style&gt;</dc:description>
      
    <dc:subject>Web</dc:subject>
     
    
  <dc:date>2012-03-16T09:00:54Z</dc:date>
    <dc:creator>simonmadine</dc:creator>
 </item>
  <item rdf:about="http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/03/14/web-development-nokia">
  <title>Web Development at Nokia</title>
  <link>http://www.developer.nokia.com/Community/Blogs/blog/web-dev/2012/03/14/web-development-nokia</link>
  <dc:description>&lt;p&gt;
&lt;em&gt;&amp;quot;Prevention is imperfect. Even the most disciplined development team, knowing the best principles, using the best patterns, and following the best practices will create messes from time to time.&amp;quot;&lt;/em&gt;&amp;nbsp;[Robert C. Martin]
&lt;/p&gt;
&lt;p&gt;
In Nokia, in our teams we are consantly looking for improvement. Improvement of knowledge, work process and ourselves. We decided to start this blog because we want to share our experiences with others. We want to write about difficulties we face and the solutions to them. We want to discuss problems, show best practices and the way we work every day. We are not always perfect in what we do but we want to be as close to perfection as we can. This involves the fact that we really care about what we are doing - the applications we create, how we write the code and how we test it.
&lt;/p&gt;
&lt;p&gt;
We put a lot of effort in improving our application and&amp;nbsp;developing new cool features to make&amp;nbsp;&lt;a href=&quot;http://maps.nokia.com/&quot;&gt;Nokia Maps&lt;/a&gt;,&amp;nbsp;&lt;a href=&quot;http://pulse.nokia.com/&quot;&gt;Nokia Pulse&lt;/a&gt;&amp;nbsp;and the&amp;nbsp;&lt;a href=&quot;http://api.maps.nokia.com/&quot;&gt;Nokia Maps API&lt;/a&gt;&amp;nbsp;the best experience for our users. We deal on a daily basis with problems that are familiar to all web developers: we want our code to be fast and small in size, we strive to provide a great user experience in any browser that is out there and at the same time we try to be innovative and take advantage&amp;nbsp;as much as possible&amp;nbsp;of the most recent technologies and&amp;nbsp;techniques. The fact that we have to design our code to be deployed in large scale makes everything even more interesting.&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
With this blog we want to discuss with the web development community&amp;nbsp;problems and solutions that we see on a daily basis. We want to spread our knowledge and expertise as a contribution for a better web. We want to share with you the journey we experience every day at Nokia.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;</dc:description>
      
    <dc:subject>Web Technology</dc:subject>
      
    <dc:subject>Web</dc:subject>
      
    <dc:subject>Web Apps</dc:subject>
     
    
  <dc:date>2012-03-14T12:20:44Z</dc:date>
    <dc:creator>w.weglinska</dc:creator>
 </item>
 </rdf:RDF>