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

<channel>
	<title>Creunabloggen &#187; Fredrik Gustafsson</title>
	<atom:link href="http://blogs.creuna.se/author/fredrikgustafsson/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.creuna.se</link>
	<description>Creunas medarbetare tycker till om stort och smått i webbranschen</description>
	<lastBuildDate>Fri, 11 May 2012 10:54:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Playing mobile &#8211; gallery web app</title>
		<link>http://blogs.creuna.se/2011/03/playing-mobile-gallery-web-app/</link>
		<comments>http://blogs.creuna.se/2011/03/playing-mobile-gallery-web-app/#comments</comments>
		<pubDate>Thu, 03 Mar 2011 10:56:06 +0000</pubDate>
		<dc:creator>Fredrik Gustafsson</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[media-queries]]></category>
		<category><![CDATA[mobilt]]></category>
		<category><![CDATA[responsible design]]></category>
		<category><![CDATA[webbapp]]></category>

		<guid isPermaLink="false">http://blogs.creuna.se/?p=467</guid>
		<description><![CDATA[Nu när mobildebatten är som hetast tänkte jag passa på att slänga in ett projekt som jag byggde i helgen. Det är en webapp för att visa mitt privata bildgalleri på telefoner och tablets.
Idén var att bygga ett flexibelt ramverk som fungerar bra på alla devices och som anpassar sitt utseende efter skärmens storlek på ett [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-468" src="http://blogs.creuna.se/wp-content/uploads/2011/03/icon.png" alt="" width="73" height="88" />Nu när mobildebatten är som hetast tänkte jag passa på att slänga in ett projekt som jag byggde i helgen. Det är en webapp för att visa mitt privata bildgalleri på telefoner och tablets.</p>
<p>Idén var att bygga ett flexibelt ramverk som fungerar bra på alla devices och som anpassar sitt utseende efter skärmens storlek på ett responsibelt sätt.</p>
<p>På en iphone ser resultatet ut så här</p>
<p><a href="http://blogs.creuna.se/wp-content/uploads/2011/03/splash.png"><img class="alignnone size-medium wp-image-475" src="http://blogs.creuna.se/wp-content/uploads/2011/03/splash-156x300.png" alt="" width="156" height="300" /></a><a href="http://blogs.creuna.se/wp-content/uploads/2011/03/folders-iphone.png"><img class="alignnone size-medium wp-image-476" src="http://blogs.creuna.se/wp-content/uploads/2011/03/folders-iphone-154x300.png" alt="" width="154" height="300" /></a><a href="http://blogs.creuna.se/wp-content/uploads/2011/03/list-iphone.png"><img class="alignnone size-medium wp-image-472" src="http://blogs.creuna.se/wp-content/uploads/2011/03/list-iphone-156x300.png" alt="" width="156" height="300" /></a><a href="http://blogs.creuna.se/wp-content/uploads/2011/03/image-iphone.png"><img class="alignnone size-medium wp-image-470" src="http://blogs.creuna.se/wp-content/uploads/2011/03/image-iphone-154x300.png" alt="" width="154" height="300" /></a></p>
<p>För att deklarera beteendet av en app använder jag några smidiga meta-taggar</p>
<div>
<pre class="brush: xml;">&lt;meta name=&quot;apple-mobile-web-app-capable&quot; content=&quot;yes&quot;&gt;</pre>
</div>
<div>Vilket talar om för webbläsaren att detta är en webbapplikatioon och att vi inte vill att den ska ladda menyerna som tillbaka, bokmärk</div>
<div>
<pre class="brush: xml;">&lt;meta name=&quot;apple-mobile-web-app-status-bar-style&quot; content=&quot;default&quot;&gt;</pre>
</div>
<div>Vi vill att statusbaren på iphone ska vara lite snyggare svart istället för den vanliga grå.</div>
<div>
<pre class="brush: xml;">&lt;meta name=&quot;viewport&quot; content=&quot;initial-scale=1.0; maximum-scale=1.0; user-scalable=no&quot;&gt;</pre>
</div>
<div>Vi vill inte att den ska vara zoombar eftersom den redan är anpassad för mobiltelefoner</div>
<div>För att se ut som en app måste den givetvis ha en ikon och startskärm</div>
<div>
<pre class="brush: xml;">&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;link rel=&quot;apple-touch-icon&quot; href=&quot;apple-touch-icon.png&quot;/&gt;&lt;/div&gt;
&lt;div&gt;&lt;link rel=&quot;apple-touch-startup-image&quot; href=&quot;splash.png&quot; /&gt;&lt;/div&gt;
&lt;div&gt;</pre>
</div>
<div>Och eftersom detta i förstahand är en mobil webbapp så låter vi huvudstilmallen gälla för alla men lägger in anpassade stilmallar för de enheter som förstår media-queries samt har en skärmstorlek som är bredare än 640px</div>
<div>
<pre class="brush: xml;">&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;link rel=&quot;stylesheet&quot; href=&quot;styles/main.css&quot;&gt;&lt;/div&gt;
&lt;div&gt;&lt;link rel=&quot;stylesheet&quot; href=&quot;styles/ipad.css&quot;␣ media=&quot;only screen and (min-width:640px)&quot;&gt;&lt;/div&gt;
&lt;div&gt;&lt;link rel=&quot;stylesheet&quot; href=&quot;styles/gallery.css&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;</pre>
</div>
<div>För bredare enheter kan innehållet alltså struktureras om och resulterar i detta.</div>
<div><a href="http://blogs.creuna.se/wp-content/uploads/2011/03/list-portrait.png"><img class="alignnone size-medium wp-image-474" src="http://blogs.creuna.se/wp-content/uploads/2011/03/list-portrait-229x299.png" alt="" width="229" height="299" /></a><a href="http://blogs.creuna.se/wp-content/uploads/2011/03/image-portrait.png"><img class="alignnone size-medium wp-image-471" src="http://blogs.creuna.se/wp-content/uploads/2011/03/image-portrait-230x300.png" alt="" width="230" height="300" /></a><a href="http://blogs.creuna.se/wp-content/uploads/2011/03/list-landscape.png"><img class="alignnone size-medium wp-image-473" src="http://blogs.creuna.se/wp-content/uploads/2011/03/list-landscape-300x232.png" alt="" width="300" height="232" /></a></div>
<div>På enheter mellan 640px och 800px (stående ipad) visas albumlisningen som ett lager som placeras framför bildlistningen, men för enheter bredare än 800px (liggande ipad) ligger albumlistningen ständigt till vänster om bilderna och gör det lättare att bläddra mellan album.</div>
<div></div>
<div>En demo av applikationen finns att testa <a href="http://silverfisk.nu/demo/galleri/">här</a>. Den är testad på desktop,iphone4,ipad och android Legend. Testa gärna och rapportera eventuella problem som uppstår i er telefon, eller testa i exempelvis Chrome och skala fönster fram och tillbaka för att se magin i @media-queries.</div>
<div></div>
<div>Kommentarer och frågor välkomnas varmt!</div>
]]></content:encoded>
			<wfw:commentRss>http://blogs.creuna.se/2011/03/playing-mobile-gallery-web-app/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Den nya templatesajten</title>
		<link>http://blogs.creuna.se/2010/11/den-nya-templatesajten/</link>
		<comments>http://blogs.creuna.se/2010/11/den-nya-templatesajten/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 14:30:10 +0000</pubDate>
		<dc:creator>Fredrik Gustafsson</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[template]]></category>
		<category><![CDATA[tillgänglighet]]></category>
		<category><![CDATA[webbstandards]]></category>

		<guid isPermaLink="false">http://blogs.creuna.se/?p=424</guid>
		<description><![CDATA[Som en del av er vet och som en del av er kanske märkt så har templatesajten blivit uppdaterad med ett helt nytt ramverk.
Den nya templatemallen är en från grunden omgjord plattform för att ligga som grund många olika typer av projekt. Markup och stilmallar är byggda för att utgöra en generellgrund anpassad för helt [...]]]></description>
			<content:encoded><![CDATA[<p>Som en del av er vet och som en del av er kanske märkt så har templatesajten blivit uppdaterad med ett helt nytt ramverk.</p>
<p>Den nya <a href="http://templatesite.creuna.se/">templatemallen</a> är en från grunden omgjord plattform för att ligga som grund många olika typer av projekt. Markup och stilmallar är byggda för att utgöra en generellgrund anpassad för helt olika typer av design och funktionalitet.<span id="more-424"></span></p>
<h3>Ramverket</h3>
<p>Ramverket är en uppdatering av den äldre templatemallen som följer de senaste trenderna i webbutveckling och levererar en mer generell plattform att bygga stabila webbplatser på. Dess struktur är uppbyggd för att kunna anpassas på väldigt många olika sätt med wrappers som hanterar bredder och den grundläggande layouten, containers som hanterar avstånd och justeringar och content som enbart ska stylas efter dess generella utseende oberoende av container. Med den strukturen är det lätt att styla om innehållet på det vis som behövs för varje specifikt projekt och det gör det lätt att skapa snygga anpassningar för mobil och print. Ett konsekvent ramverk möjliggör även mer avancerade AJAX-funktioner och javascript som förhöjer den avancerade användarens webbupplevelse.</p>
<h3>HTML5</h3>
<p>Templatemallen är baserat på HTML5 med den enkla doctypen &lt;!DOCTYPE html&gt;. Detta gör det möjligt att kunna använda nya tekniker och element som ingår i den nya standarden och anamma det nya tankesättet på ett sätt att de webbplatser som skapas idag även är framtidssäkrade. Eftersom många av de webbläsare som används idag inte har stöd för de nya elementen i HTML5 som &lt;header&gt;, &lt;article&gt;, &lt;footer&gt;, &lt;section&gt; kan dessa ännu inte användas utan stödet för javascript. Dock kan samma typografi användas med tillgängliga element som &lt;div class=”article”&gt;, &lt;div class=”header”&gt;, &lt;div class=”section”&gt; etc. Element som däremot kan ärva sin style eller som inte är lika viktiga att de ser lika dant ut i IE utan javascript kan moderniseras till HTML5 som exempelvis: &lt;time datetime=&#8221;2010-06-14&#8243;&gt;14 juni 2010&lt;/time&gt; eller &lt;figure&gt;&lt;img  src=”bil.png”/&gt;&lt;figcaption&gt;En fin bil&lt;/figcaption&gt;. Några andra HTML5element som går utmärkt att börja använda är formulärelementen i HTML5.</p>
<h3>Formulär</h3>
<p>HTML5 gör det mycket enklare att hantera olika typer av formulärfält genom de nyinförda inputtyperna, &lt;input type=”number”&gt;, &lt;input type=”tel”&gt;, &lt;input type=”date”&gt;, &lt;input type=”search”&gt;, &lt;input type=”email”&gt;, &lt;input type=”url”&gt; etc. Eftersom dessa har grundläggande stöd för validering i moderna webbläsare samt öppnar upp rätt typ av tangentbord, på touch baserade enheter, men på övriga webbläsare faller de tillbaka och hanteras som en &lt;input type=”text”&gt;. Det gör det möjligt att om webbläsaren inte hanterar funktionaliteten själv, applicerar vi ett script söm gör funktionaliteten åtkomlig i övriga webbläsare också.</p>
<p>HTML5 medför även ett natal formulärattribut som gör det lättare för oss som webbutvecklare. Ex. Placeholder, reguired, pattern, step, min, max etc vilket gör att vi kan specificera hur elementet ska hanteras i moderna webbläsare och använda samma attribut för att bygga fallbacklösningen till äldre webbläsare.</p>
<p>Läs mer om formulärhanteringen för alla webbläsare i mitt tidigare blogginlägg <a href="http://blogs.creuna.se/2010/10/framtidens-formular-idag/">Framtidens formulär idag</a></p>
<h3>Struktur</h3>
<p><a href="http://blogs.creuna.se/wp-content/uploads/2010/11/Screen-shot-2010-11-18-at-3.20.07-PM.png"><img class="size-full wp-image-428 alignnone" src="http://blogs.creuna.se/wp-content/uploads/2010/11/Screen-shot-2010-11-18-at-3.20.07-PM.png" alt="" width="429" height="349" /></a></p>
<p><strong>#page</strong></p>
<p>Page är den yttersta wrappern som innehåller allt innehåll. Den sätter grundläggande regler för sidans utforming, bredd och positionering.</p>
<p><strong> #header</strong></p>
<p>Header innehåller statisk information som finns på sajtens alla sidor och har role=”banner”. Innehållet i denna är det som alltid får fokus först på sidan, och bör inte vara för länktung. Exempelvis en kort lista med globala länkar, logotyp och ett sökfält. Blir innehållet längre bör en skiplink läggas i högst upp som ger möjligheten att hopa över headerinnehållet direkt till #conent.</p>
<p><strong> #content-wrapper</strong></p>
<p>Content-wrapper är en wrapper som inte har en annan uppgift än att göra det lättare och mer flexibelt att stila innehållet tillsammans med navigationen.</p>
<p><strong> #content</strong></p>
<p>Yttligare en wrapper för allt sidans innehåll.</p>
<p><strong> #main</strong></p>
<p>Wrapper för huvudytan, allt innehåll som inte placeras i #aside. Denna har attributet role=”main” för att märka upp sidans huvudinnehåll.</p>
<p><strong> #primary</strong></p>
<p>Primäry är den huvudsakliga container som innehåller faktiskt innehåll. Förutom att peka ut hududinnehållets primära innehåll, innebär primary att innehållet fyller ut hela bredden av #main.</p>
<p><strong> .secondary</strong></p>
<p>Secondary är en container för sekundärt innehåll som är relaterat till ämnet, men inte nödvändigt för att uppfatta sidans syfte. Förutom att peka ut att innehållet är sekundärt, innebär .secondary att innehållet enbart fyller ut halva bredden av main. Man kan därför ha två .secondary bredvid varandra med sekundärt innehåll. Det finns även möjligheten att för breda sidor använda .tertiary som då tar upp en tredjedel av bredden.</p>
<p><strong> #aside</strong></p>
<p>Aside är sidans sidebar som anspelar på HTML5 elementet &lt;aside&gt;. Det innebär inte att det nödvändigtvis behöver ligga vid didan av #main, men det har den semantiska betydelsen att ha kompletterande innehåll och har därför även attributet role=”complementary”. Aside är precis som primary och secondary en innehållscontainer som i de flesta fall befolkas med sektioner av olika slag.</p>
<p><strong> #navigations</strong></p>
<p>Navigations är en wrapper för sidans meny(er). Den placeras efter #content, vilket innebär att tangentbordsanvändare inte behöver stega igenom menyn varje gång de vill nå innehållet. Det gör det även enklare att göra mobila anpasningar, där menystrukturen kan placeras i boten så användare inte behöver scrolla förbi listmeter med menyalternativ för att se sidans innehåll. Det finns även en skiplink för att hoppa över innehållet direkt till #navigations som placeras högst upp i #content direkt efter brödsmule-listan.</p>
<p><strong> #main-nav</strong></p>
<p>Main-nav är sidans huvudnavigation som ligger som en toppnavigation absolutpositionerad ovanför #content. Main-nav har attributet role=”navigation” för att göra det lätt för skärmläsare att direkt hoppa till navigationen.</p>
<p><strong> #sub-nav</strong></p>
<p>Sub-nav är en egen lista med undersidorna till det just nu valda menyvalet i #main-nav. Sub nav fyller ut det tomrum som bildats av att #content är högerjusterad med en viss bredd. På så vis kan listan växa längre än content utan att försvinna under sidfoten. Även sub-nav har attributet role=”navigation”</p>
<p><strong> #footer</strong></p>
<p>Footern ligger sist i dokumentet och innehåller statisk information om sajten. Samt har attributet role=”contentinfo”.</p>
<h3>Innehåll</h3>
<p><a href="http://blogs.creuna.se/wp-content/uploads/2010/11/Screen-shot-2010-11-18-at-3.20.23-PM.png"><img class="alignnone size-full wp-image-429" src="http://blogs.creuna.se/wp-content/uploads/2010/11/Screen-shot-2010-11-18-at-3.20.23-PM.png" alt="" width="628" height="160" /></a></p>
<p>Det finns två typer av innehållsmoduler som redaktörerna kan använda för att presentera innehåll. Dessa är article och section, inspirerade av HTML5 elementen med samma namn. Dessa används för allt innehåll i #primary, .secondary och #aside och väljs beroende på det semantiska värdet på innehållet.</p>
<p><strong>.article</strong></p>
<p>Article används för en fristående text som kan sammanfattas i sin helhet. Huvudinnehållet som går direkt under sidans huvudrubrik presenteras alltid i en .article som alltid börjar med en &lt;h*&gt;rubrik. På de flesta innehållssidor används en .article. En article kan innehålla .header och/eller .footer för att placera nära relaterat innehåll, som kommentarer, relaterade länkar etc.</p>
<p>På vissa sidor finns det inte någon viss information som är huvudinnehållet, som på exempelvis startsidor, så behöver det inte finnas någon article alls.</p>
<p>För listningar av texter som inlägg eller nyheter kan article användas inuti en annan article eller sektion för varje egen  artikel.</p>
<p><strong>.section</strong></p>
<p>För allt övrigt innehåll används .section. Sektionen har för enkelhetensskull alltid en .header som innehåller dess rubrik, en .content som innehåller dess innehåll och möjligtvis även en .footer, med sektionens relaterade innehåll eller Läs merlänk. Dessa kan placeras i #primary (efter article(om det finns någon)), i #secondary, i #aside och inuti andra .article eller .sections.</p>
<p>Alla klassiska puffar och portlets bör lämpligtvis sättas som sections. Sections kan variera i utseende genom att sätta yttligare klassnamn som sedan skriver över eller utökar grundsektionens stilmallar.</p>
<p>Användandet av article och section i HTML5 är en av de mest omdiskuterade frågorna bland utvecklare som vill anamma tankesättet i HTML5. Då detta troligtvis kommer att bli klarare eftersom specifikationen bli mer färdigställd, kan användningsområdena för dessa ändras. Därför har varken sektion eller artikel någon speciell grundstil (bredd, sidomarginal eller font-size) som begränsar användningen till en viss implementation.</p>
<h3>CSS</h3>
<p>Stilmallen är en viktig del i ett ramverk som har för avsikt att vara generellt och användbart för många olika designer, olika projekt, olika webbläsare, olika användare och olika enheter. Därför ävänder vi korta sökvägar och generella stilar som lätt ska kunna skrivas över och modifieras utan att ändra för mycket i grundmallen.</p>
<p>Av prestandaskäl vid inläsning av sidan bör det aldrig vara mer än en stilmall som läses in och i denna ska alla de stilar (och bara de stilar) som används i projektet finnas.  Först sätts de generella stilar för generella element som länkar, inputfält, rubriknivåer, listor och knappar som sätter regelverket och basen för hela projektet.</p>
<p>Efter det sätts de generella klasserna för templatens struktur, där #page, #header, #contentwrapper, #content, #main, #aside, #footer etc sätts enligt de mått och layout som ska användas på sidan. Fördelen med de extra wrapperobjekten som #main, #aside och #navigations är att brederna sätt oberoende av dess innehåll och kan sättas i px eller % beroende på vad man vill uppnå och innehållet i dem följer utan att bryta layouten.</p>
<p><strong>Px, em och %</strong></p>
<p>Det finns många olika åsikter om vilka måttenheter som ska användas för layout, fontstorlek, radhöjd. Bredder som sätts i % anpassar sig till dess förälder eller webbläsarfunstret och kan vara ett bra sätt att skapa flexibla lösningar, men det krävs lite jobb för att den inte ska bryta designen och är svår att använda tillsammans med andra enheter som px. Em anpassas efter textstorleken och ärvs från sin förälder. I äldre webbläsare med möjlighet att förstora textstorleken kommer allt annat som är satt i em även att förstoras, även denna är svår att kombinera med px som inte zoomas vid textstorlekförändring. Exempelvis resulterar em-breddeer ofta till att bakgrundsbilder med sprites som sätts med px, inte följder designen vid zoom. Pixlar sätter ett fast mått i förhållande designen och är det mest pålitliga för att hålla en statisk design. Moderna webbläsare använder ofta pixelzoom istället för textstorlekzoom vilket förstorar hela designen skalenligt. Dock är det bra att fortsätta text-size och line-height i em, för att kunna förstoras i äldre webbläsare. I templatemallen sätts alla bredder, border, marginaler och avstånd med px och med fontstorlek enbart på body till 12px (75%), och sätts sedan på de objekt som är undantag från regeln ex. ( h1{font-size:2em;} /* 12px*2= 24px */ ).</p>
<p><strong>@media screen, print och handheld</strong></p>
<p><strong><a href="http://blogs.creuna.se/wp-content/uploads/2010/11/Screen-shot-2010-11-18-at-3.11.22-PM.png"><img class="alignright size-medium wp-image-430" src="http://blogs.creuna.se/wp-content/uploads/2010/11/Screen-shot-2010-11-18-at-3.11.22-PM-153x300.png" alt="" width="153" height="300" /></a><br />
</strong></p>
<p>Alla webbplatser som skapas idag måste vara anpassade för olika media. Media @screen som är det som visas på en datorskärm läggs ofta mycket tid på att styla, men det måste även se bra ut utskrivet med @media print och för mobila webbläsare via @media handheld, eller @media all and (max-device-width:480px) som används för kompetenta webbläsare med en skärm som är max 480px stor. Den senare används ofta av smartphones som iphone och androidmobiler som har möjligheten att visa fulla webbuplevelsen och därför inte snvänder sig av @media handheld som äldre telefoner använder.</p>
<p><strong>ie6, ie7, ie8</strong></p>
<p>Det finns en webbläsare som ofta kräver lite mer arbete än andra för att att fungera och se bra ut. Som tur är finns det knep att skapa specille lösningar enbart för denna webbläsares olika versioner.</p>
<p>&lt;!&#8211;[if ie lte 8]&gt;&lt;link href=”ie8.css” rel=”stylesheet” /&gt;&lt;![endif]&#8211;&gt;</p>
<p>&lt;!&#8211;[if ie lte 7]&gt;&lt;link href=”ie7.css” rel=”stylesheet” /&gt;&lt;![endif]&#8211;&gt;</p>
<p>&lt;!&#8211;[if ie lt 7]&gt;&lt;link href=”iepre7.css” rel=”stylesheet” /&gt;&lt;![endif]&#8211;&gt;</p>
<p>Med kommentaren ovan kommer stilmallen ie7.css enbart att läsas in för användare som använder IE7 eller tidigare version. I den stilmallen kan man sätta de specialmallar som behövs för dessa versioner. Det finns tre IE-specifika stilmallar i templatemallen: iepre7.css används för IE6 och tidigare, ie7.css används för IE7 och tidigare och ie8.css används för IE8 och tidigare versioner. Det är egentligen en ful vana att göra speciallösningar för en viss webbläsare, men det är ibland nödvändigt för dessa versioner.</p>
<p>Det finns även möjlighet att göra mer avancerade stilmallar som normalt inte stöds i dessa versioner med hjälp av ett speciell script. Det tillåter att specifisera i stilmallen det beteende som skriptet ska utföra och hur det ska stylas. Exemplevis scriptet cssLastChild() möjliggör att komma åt pseudo-selektorn :last-child, som kan användas i andra webbläsare, genom att söka upp den angivna selectorn och sätta en klass på den som man sedan kan styla.</p>
<p>ul li:last-child{ <em>style</em> } /*För alla andra*/</p>
<p>ul{ 	/*IE bara, placeras I ie8.css */</p>
<p>last-child : &#8216;last-child&#8217;;</p>
<p>selector :  &#8216;li&#8217;;</p>
<p>}</p>
<p>ul li.last-child{ <em>style</em> }</p>
<p>scriptet måste dock aktiveras på de object där de ska användas.</p>
<p>if ($.browser.msie&amp;&amp;$.browser.version&lt;9){</p>
<p>$(&#8216;ul&#8217;).cssLastChild();</p>
<p>}</p>
<p>Andra av dessa script som kan användas I IE är cssBefore (), cssAfter(), cssMyChild(), cssMySibling(), cssHover(), cssFocus(), cssMaxWidth(), cssMinWidth(), cssMaxHeight(), cssMinHeight(), cssFirstChild().</p>
<p>mer om detta i min tidigare bloggpost <a href="http://blogs.creuna.se/2010/08/css-pseudoklasser-i-ie/">Pseudoklasser i IE</a></p>
<h3>JavaScript</h3>
<p>Javascript i ett projekt blir ofta väldigt snabbt väldigt många och väldigt stora och ingen vet längre vilka som faktiskt används och hur. Skript byggs ofta för specifika ändamål och ändrar både på markup och sätter stilar som blir svåra att underhålla. Därför bör ett repository med generella skriptpaket sättas upp, som kan återanvändas i flera olika projekt.</p>
<p>Tills detta är en verklighet läggs dessa plugins, och funktioner med Templatemallen, så att de är klara att använda out of the box. mer om scripthantering i mitt tidigare blogginlägg <a href="http://blogs.creuna.se/2010/11/atervinn-dina-javascript-plugin/">Återvinn dina javascriptplugin</a></p>
<p>Stockholmshems nya webbplats som lanserades igår är baserad på samma ramverk och kan vara en bra inspiration. <a href="http://www.stockholmshem.se">http://www.stockholmshem.se</a>.</p>
<p>Om ni stöter på problem eller har några frågor eller förslag angående ramverket diskuterar jag väldigt gärna dem med er.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.creuna.se/2010/11/den-nya-templatesajten/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Återvinn dina javascript-plugin</title>
		<link>http://blogs.creuna.se/2010/11/atervinn-dina-javascript-plugin/</link>
		<comments>http://blogs.creuna.se/2010/11/atervinn-dina-javascript-plugin/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 07:59:16 +0000</pubDate>
		<dc:creator>Fredrik Gustafsson</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blogs.creuna.se/?p=418</guid>
		<description><![CDATA[De flesta som bygger funktioner i javascript märker efter ett tag att man väldigt ofta skriver om samma funktioner gång på gång för att tillämpningen skiljer sig lite från förra gången. Då försöker man skapa mer generella plugins där man skapar en lista med egenskaper och variabler som man med olika anrop kan påverka resultatet [...]]]></description>
			<content:encoded><![CDATA[<p>De flesta som bygger funktioner i javascript märker efter ett tag att man väldigt ofta skriver om samma funktioner gång på gång för att tillämpningen skiljer sig lite från förra gången. Då försöker man skapa mer generella plugins där man skapar en lista med egenskaper och variabler som man med olika anrop kan påverka resultatet av pluginet.<br />
Exempelvis</p>
<pre class="brush: jscript;">
jQuery.prototype.myAlert = function(argument){
  var option = jQuery.extend({
    message : &quot;Hello world&quot;,
    click : function(){
      alert(option.message);
      return false;
    }
  }, argument);
  jQuery(this).click(option.click);
};
jQuery('a').myAlert({'message':'A whole new world'});
</pre>
<p>Denna metod är en väldigt generell och kraftfull metod som kan påverkas i sina anrop beroende på vilka argument, man anropar den med. Men problemet med denna lösning är att det är en inkapslad metod som inte kan ärvas och för att anropa olika modifierade instanser av den på samma sajt kräver att man sätter väldigt specifika sökvägar.</p>
<pre class="brush: jscript;">
jQuery('#mybox .special-intance a.alert').myAlert({'message':'normal message'});
jQuery('#content .some-specific-place a.alert').myAlert({'message':'a even cooler message'});
</pre>
<p>Istället skulle man vilja skapa en instans av pluginet för varje objekt och sedan modifiera och utöka parametrar och funktioner för undantagen. Detta går att åstadkomma genom att skapa ett publikt objekt för varje plugin, där parametrarna sätts som funktionsparametrar direkt på objektet.</p>
<pre class="brush: jscript;">
var myAlert = {
    message : 'hello world',
    onclick : function(){
	alert(this.message);
	return false;
    },
    init : function(){
	 //initcode
    }
};
jQuery.fn.myAlertBox = function(args){
    var opt = jQuery.extend({}, myAlert, args);
    function init(){
        $(this).setProperties(opt);
	if(typeof(this.init) == 'function'){
		this.init();
	}
    }
 return this.each(init);
};
jQuery.fn.setProperty = function(mykey, myvalue){
    function init(){
        this[mykey] = myvalue;
    }
    return this.each(init);
};
jQuery.fn.setProperties = function(args){
    function init(){
	for (var key in args) {
		$(this).setProperty(key, args[key]);
	}
    }
    return this.each(init);
};
jQuery(function(){
    jQuery('a').myAlertBox({'message' :'hello all links'});
    jQuery('li a').setProperties({&quot;message&quot;:&quot;inside a list&quot;});
});
</pre>
<p>Objekten kan givetvis utöka jQuery-objektet för att kunna definiera mer avancerade jQuery funktioner och händelser.</p>
<p>Med denna funktionalitet kan vi bygga lättare plugin som utför grundfunktionaliteten i exempelvis ett bildspel eller lightbox, och kan utöka objektet för varje typ av implementation och undvika onödiga buggar och frustration. </p>
<p>Har du åsikter om denna metod eller förslag på bättre lösningar så är jag väldigt intresserad av att diskutera dem.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.creuna.se/2010/11/atervinn-dina-javascript-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Framtidens formulär idag</title>
		<link>http://blogs.creuna.se/2010/10/framtidens-formular-idag/</link>
		<comments>http://blogs.creuna.se/2010/10/framtidens-formular-idag/#comments</comments>
		<pubDate>Wed, 20 Oct 2010 11:19:33 +0000</pubDate>
		<dc:creator>Fredrik Gustafsson</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[webbstandards]]></category>

		<guid isPermaLink="false">http://blogs.creuna.se/?p=385</guid>
		<description><![CDATA[Som alla vet så heter framtiden HTML5 och innehåller massor med vackra och häftiga funktioner som vi som webbutvecklare inte kan vänta på att få använda oss av som klientvalidering, inputtyper för flera olika typer av data, placeholder-text, felmeddelanden, autofocus datepickers, nummerstegning etc. etc.

Många av dessa funktioner är redan implementerade i de moderna bra webbläsarna på marknaden som gör livet lätt för oss utvecklare, för att uppnå samma funktionalitet i äldre webbläsare måste man bygga sina egna skript, men de ska enbart användas på de webbläsare och de versioner som inte redan har inbyggt stöd för HTML5 funktionaliteten.

Jag har utvecklat ett sådant skript som gör det enkelt att använda de moderna formulärfunktioner som erbjuds i HTML5 till dagens webbläsare. Så sätt på er läsglasögonen och ta några minuter och läs igenom vad skriptet gör och hur det fungerar, så kan du börja använda det i dina projekt och förhoppningsvis spara massor med tid.]]></description>
			<content:encoded><![CDATA[<p>Som alla vet så heter framtiden HTML5 och innehåller massor med vackra och häftiga funktioner som vi som webbutvecklare inte kan vänta på att få använda oss av som klientvalidering, inputtyper för flera olika typer av data, placeholder-text, felmeddelanden, autofocus datepickers, nummerstegning etc. etc.</p>
<p>Många av dessa funktioner är redan implementerade i de moderna bra webbläsarna på marknaden som gör livet lätt för oss utvecklare, för att uppnå samma funktionalitet i äldre webbläsare måste man bygga sina egna skript, men de ska enbart användas på de webbläsare och de versioner som inte redan har inbyggt stöd för HTML5 funktionaliteten.</p>
<p>Där kommer Modernizer in. Modernizer är ett litet skriptbibliotek som testar webbläsarens funktionalitet mot funktioner och element i HTML5 och gör det enkelt att applicera sina skript och stilmallar till enbart de webbläsare som behöver den. Detta genom en uppsättning av funktioner som testar en viss feature, eller via sökvägar, då den sätter webbläsarens egenskaper som klassnamn på &lt;html&gt;<br />
Modernizer initierar även HTML5 element vilket gör att de är stilningsbara i Internet Explorer, men för att det ska fungera måste Modernizer inkluderas i .</p>
<p>Man kan kolla om webbläsaren har stör för just den aktuella funktionen, med:</p>
<pre class="brush: jscript;">if (!Modernizr.inputtypes.date) {
//specialscript
}</pre>
<p>Eller peka ut sökvägar utifrån specifika features exempelvis:</p>
<pre class="brush: xml;">.no-borderradius #mybox{//style}&lt;/span&gt;</pre>
<p>Mer om Modernizer hittar ni på <a href="http://http://www.modernizr.com/">http://www.modernizr.com/</a></p>
<p>För att inte alla ska behöva bygga dessa grymma skript själva så har jag byggt ett relativt komplett paket av HTML5 formulärfunktionalitet för alla webbläsare som bara behöver läggas in och anropas med,</p>
<pre class="brush: jscript;">$(document).ready(function(){
$(this).initforms();
})</pre>
<p>Men innan ni får hämta hela paketet, ska jag förklara kort vad skriptet gör och hur de fungerar.</p>
<p><span id="more-385"></span></p>
<h2>Validering</h2>
<p>För att enkelt kunna validera fält för deras inmatningstyp definierar jag enkla funktioner som jämför värdet mot ett reguljärt uttryck och returnerar sant eller falskt.</p>
<pre class="brush: jscript;">var validate = {
	email : function(value){
			return value.match(/^.+@.+\..+$/)?true:false;
	},
	number : function(value){
			return value.match(/^-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?$/i)?true:false;
	},
	tel : function(value){
			return value.match(/^\+?\d+(?:\-\d*)?(?:[+\-\ ]?\d+)*\ ?$/i)?true:false;
	},
	date : function(value){
		return value.match(/^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$/i)?true:false;
	},
	url : function(value){
		return value.match(/^([A-Za-z]+:\/\/)?[A-Za-z0-9-_]+\.[A-Za-z0-9-_%&amp;amp;\?\/.=]+$/)?true:false;
	},
	pattern : function(value, pattern){
		return value.match(pattern)==value?true:false;
	}
};</pre>
<p>De typer av inputfält som valideras är text, email, url, number, tel, date och pattern.<br />
Varje gång ett inputfält ändras, triggar eventet &#8216;validate&#8217; som hanteras olika för varje enskild formulärtyp. Om fältet innehåller mer än 25 tecken valideras inte längre fältet pågrund av prestandaproblem.</p>
<pre class="brush: jscript;">$('input', container).bind('keyup click focus blur change', function () { //Sniffa efter alla förändringar i fältet
        var input = $(this);
	if(this.value.length&amp;lt;25){
		input.removeClass('valid long').trigger('validate');
	} else{
		$(this).addClass('long').removeClass('valid invalid'); //För lång classnamnet &quot;long&quot; hindrar validering
	}
        if (!input.is('[type=radio]') &amp;amp;&amp;amp; !input.is('[type=checkbox]')) {
            if (input.val().length &amp;amp;&amp;amp; !input.is('.placeholder')) {
                input.removeClass('empty');
                if (!input.is('.long') &amp;amp;&amp;amp; !input.is('.invalid-email') &amp;amp;&amp;amp; !input.is('.invalid-number') &amp;amp;&amp;amp; !input.is('.invalid-tel') &amp;amp;&amp;amp; !input.is('.invalid-date') &amp;amp;&amp;amp; !input.is('.invalid-url') &amp;amp;&amp;amp; !input.is('.placeholder') &amp;amp;&amp;amp; !input.is('.invalid-pattern')) {
                    //Om fältet inte är invalid av något slag så är den valid
                    input.removeClass('invalid').addClass('valid').next('.errormsg').remove();
                }
            } else {
                input.addClass('empty');
            }
        }
}).trigger('change'); //Kör kontroller initialt</pre>
<p>Själv kontrollen av fältet gör separat för varje fälttyp exempevis för epost:</p>
<pre class="brush: jscript;">$('input.email:not([pattern])', container).bind('validate', function () { //validera epostfält med class=&quot;email&quot;
	if (!validate.email(this.value)) {
		$(this).addClass('invalid invalid-email');
	} else {
		$(this).removeClass('invalid-email');
	}
});</pre>
<p>Observera att den appliceras på inputfält med klassnamet &#8221;email&#8221; istället för inputtyp, detta för att vissa äldre webbläsare inte ens uppfattar type-värdet. Detta innebär även att HTML5 funktionaliteten är användbar för dokument som inte använder HTML5 doctype eller html5formulär. Vi använder inte heller modernizer för denna kontroll eftersom vi inte kan styra den som vi kan styra vår egen. Dockj är det viktigt att de reguljära valideringuttrycken överensstämmer med specen för den inbyggda valideringen i moderna webbläsare.</p>
<p>Man kan för egna fält även sätta reguljära valideringsmönster för sina fält med attributet pattern=&#8221; &#8221;, vilken då är överordnad till alla andra valideringsformer.<br />
Mer om pattern och andra HTML5formulärattribut kan studeras på <a href="http://www.w3.org/TR/html5/forms.html">http://www.w3.org/TR/html5/forms.html</a></p>
<h3>Felmeddelanden</h3>
<p>Fält som inte validerar korrekt får direkt klassnamnet &#8221;invalid&#8221; vilken kan stylas för att ge direkt feedback till användaren och exempelvis färga fältet rött. När formuläret skickas vill man dock poängtera vilka fel som finns i formuläret innan formuläret skickas. För detta ändamål används felmeddelanden. Felmeddelanden sätts ut på alla obligatoriska formulärfält som inte är valida. För att visa vilka som är obligatoriska används attributet required=&#8221;required&#8221;. Dessa förhindrar att formuläret skickas förrän de är korrekt ifyllda. Det är också möjligt att felmeddelanden visas för ej obligatoriska fält, med klassnamnet &#8221;validate&#8221;, dessa förhindrar dock inte formuläret från att skickas.</p>
<p>Felmeddealndefunktionen anropas när en submit-knapp klickas inuti en &lt;fieldset&gt; och formulärvalideringen görs enbart på alla formulärelement inom samma &lt;fieldset&gt;. För att andra knappar på sidan som inte har för uppgift att skicka formuläret inte ska hindras måste attributet formnovalidate=&#8221;formnovalidate&#8221; sättas på dessa.</p>
<pre class="brush: jscript;">$('fieldset button[type=submit], fieldset input[type=submit]', container).not('[formnovalidate]').click(function() {
		var fieldset = $(this).closest('fieldset');
		if (fieldset.find('[required].invalid, [required].empty, .validate.invalid:not(.empty)').length) {
				fieldset.find('[required].invalid, [required].empty, .validate.invalid:not(.empty)').showErrors();
				return false;
		}
		$('input.placeholder', fieldset).removeClass('placeholder').val('');
});</pre>
<p>Beroende på vilket fel som upptäcks sätts olika felmeddelanden som läggs in i DOM&#8217;en direkt efter det aktuella fältet.<br />
Felmeddelanden har defaulvärden men kan ersättas med egna värden, i detta exempel ersätts de strängar som finns satta i den globala variablen sse.errorMessages.</p>
<pre class="brush: jscript;">$.fn.showErrors = function(args){
	var opt = jQuery.extend(jQuery.extend({
	  text: &quot;Fältet får inte lämnas tomt&quot;,
		email: &quot;Du måste ange en korrekt epostadress&quot;,
		number: &quot;Värdet måste vara ett nummer&quot;,
		date: &quot;Du måste ange ett korrekt datum&quot;,
		url: &quot;Ange en korrekt url&quot;,
		pattern: &quot;Felaktigt format&quot;,
		select: &quot;Du måste ange ett alternativ&quot;,
		custom: &quot;&quot;
	},errorMessages),args);
	$(this).each(function(){
		var input = $(this);
		var errormsg = $(this).next('.errormsg').length ? $(this).next('.errormsg') : $('

');
		if(opt.custom !== &quot;&quot;){
			errormsg.text(opt.custom);
		} else if(input.is('.invalid-email')){
			errormsg.text(opt.email);
		} else if(input.is('.invalid-number')){
			errormsg.text(opt.number);
		} else if(input.is('.invalid-date')){
			errormsg.text(opt.date);
		} else if(input.is('.invalid-url')){
			errormsg.text(opt.url);
		} else if(input.is('.invalid-pattern')){
			errormsg.text(opt.pattern);
		} else if(input.is('[type=text]')){
			errormsg.text(opt.text);
		} else if(input.is('select')){
			errormsg.text(opt.select);
		}
		if(input.is('[type=password].empty')){
			input.prev('.replacement').addClass('invalid').removeClass('empty');
		}
		errormsg.insertAfter(input.removeClass('empty'));
	});
	return this;
};</pre>
<h2>Placeholder</h2>
<p>Det väldigt praktiska HTML5-attributet placeholder är implementerat i många moderna webbläsare och ger en schablontext i fältet när det lämnas tomt och försvinner när fältet får fokus. Även denna funktionalitet är självklart implementerad. Och sättas automatiskt på alla inputfält som har ett placeholder-attribut.<br />
För att lösenordsfält också ska fungera utan att visa schablontexten som stjärnor, skapar ett identiskt fält som byts ut när lösenordsfältet får och förlorar  fokus.</p>
<pre class="brush: jscript;">$.fn.setPlaceholder = function(text){
	function init(){
		var input = $(this);
		if(!text){
			var text = input.attr('placeholder');
		}
		var replacement = $('');
		var type = input.attr('type');
		input.blur(function(){
			if(!input.val()){
				if (type==&quot;password&quot;){
					input.hide();
					replacement.insertBefore(input).show();
				} else {
					input.val(text).addClass('placeholder');
				}
			}
		}).focus(function(){
			if(input.is('.placeholder')){
				input.removeClass('placeholder').val('');
			}
		});
		replacement.focus(function(){
			$(this).hide().next('input').show().focus();
		});
		if(!input.val() || input.val() == text){
			if (type==&quot;password&quot;){
				input.hide();
				replacement.insertBefore(input).show().width(input.width());
			} else {
				input.val(text).addClass('placeholder');
			}
		}
	}
	return this.each(init);
};</pre>
<h2>Special inputformat</h2>
<p>Förutom vanliga textfält av olika slag har HTML5 specifikationer för andra typer av formulärelement som sliders, datepickers, nummerstegare och sökfält.<br />
Dessa är implementerade för olika slag av implementering.</p>
<h3>Sliders</h3>
<p>Sliders kan skapas på två olika sätt, antingen enligt HTML5-specifikationen för  som då visar fältet som en slider. (Appliceras i skriptet utifrån klassnamnet &#8221;range&#8221;). Denna typ bör ha attributen max=&#8221;", min=&#8221;" och step=&#8221;" och data-units=&#8221;kronor&#8221; (som sätter ut det satta värdet med units efteråt, bakom sliderns).</p>
<p>Det andra sättet att generera en slider är utifrån en dropdownlista med fasta gradvisa steg.</p>
<pre class="brush: xml;">
&lt;select class=&quot;slider&quot;&gt;
  &lt;option&gt;Not important&lt;/option&gt;
  &lt;option&gt;Somewhat important&lt;/option&gt;
  &lt;option&gt;Pretty important&lt;/option&gt;
  &lt;option&gt;Must have&lt;/option&gt;
&lt;/select&gt;
</pre>
<p>Denna skapa en slider med lika många steg som options och visar det aktuella valets innehåll efter slidern.</p>
<h3>Datepicker</h3>
<p>Nästan alla projekt använder någon gång en datepicker för att underlätta valet av datum för användaren. Denna är automatiskt aktiverad för alla  Och använder sig av jquery-UI med svenskt tidsformat.<br />
Beakta att eftersom HTML5-funktion denna är implementerad i exempelvis Opera, och använder sig av Modernizer kommer ett fält som inte är av typen date, inte visa någon datepicker alls för klass &#8221;date&#8221;. Denna funktion har heller inte (i dagsläget) stöd för de övriga datumformaten som är specade i HTML5 som ,  etc.</p>
<pre class="brush: jscript;">if (!Modernizr.inputtypes.date) {
		$('input.date', container).datepicker({ onClose: function () {
				$(this).removeClass('placeholder').focus();
		}
		}).bind('validate', function () {
				if (this.value &amp;amp;&amp;amp; !validate.date(this.value)) { $(this).addClass('invalid invalid-date'); } else { $(this).removeClass('invalid-date'); }
		}).keydown(function (e) {
				var input = $(this);
				var currentDay = $('#ui-datepicker-div .ui-datepicker-current-day');
				switch (e.keyCode) {
						case 38: //Up
								if (!currentDay.prev('td').length || currentDay.prev('td.ui-datepicker-unselectable').length) {
										if (currentDay.parent().prev().length &amp;lt; 1) {
												$('#ui-datepicker-div .ui-datepicker-prev').trigger('click');
												$('#ui-datepicker-div table a:last').trigger('click');
										} else {
												currentDay.parent().prev('tr').find('a:last').trigger('click');
										}
								} else {
										currentDay.prev().find('a').trigger('click');
								}
								input.focus();
								break;
						case 40: //Down
								if (!currentDay.next('td').length || currentDay.next('td.ui-datepicker-unselectable').length) {
										if (currentDay.parent().next().length &amp;lt; 1) {
												$('#ui-datepicker-div .ui-datepicker-next').trigger('click');
												$('#ui-datepicker-div table a:first').trigger('click');
										} else {
												currentDay.parent().next('tr').find('a:first').trigger('click');
										}
								} else {
										currentDay.next().find('a').trigger('click');
								}
								input.focus();
								break;
						case 33: //PageUp
								$('#ui-datepicker-div .ui-datepicker-prev').trigger('click');
								$('#ui-datepicker-div table a:last').trigger('click');
								input.focus();
								break;
						case 34: //PageDown
								$('#ui-datepicker-div .ui-datepicker-next').trigger('click');
								$('#ui-datepicker-div table a:first').trigger('click');
								input.focus();
								break;
				}
		});
}</pre>
<p>Datepickern har naturligtvis stöd för tangentbordsnavigation och hoppa hela månader med pageUp/Down.</p>
<h3>Nummerstegare</h3>
<p>HTML5 specifikationen specifierar att  automatiskt applicerar en stegare där man kan klicka med mus eller tangentbord för att öka eller minska värdet gradvis. Denna funktionalitet är också implementerad, men kräver attributet &#8221;step&#8221;, för att man ska kunna validera nummerfält av andra slag, exempelvis kreditkortsinformation etc.</p>
<p>Stegningen kan specifieras med attributen min=&#8221;", max=&#8221;" och step=&#8221;".</p>
<h3>Sökfält</h3>
<p>Sökfält har en egen funktionalitet som är specifierat i HTML5 som skiljer sig mot andra fält på det sättet att när det har innehåll dyker upp ett litet kryss i högerkantetn av formuläret som ger möjligheten att enkelt tömma fältet. Detta är framförallt praktiskt för mobiltelefoner och musanvändare. Denna funktionalitet läggs automatiskt på alla fält av type=search eller klassnamn &#8221;search&#8221;.</p>
<h3>Autofokus</h3>
<p>Det finns även en praktisk specifikation att med attributet autofocus=&#8221;autofocus&#8221; automatiskt sätta fokus på det aktuella fältet. Denna ska bara användas på ett fält per sida, exempelvis sökfält, på söksidan.</p>
<h2>UngroupOptgroup</h2>
<p>Yttligare i formulärskripet finns det en funktion som delar upp en större dropdownlista med s till två kortare dropdowns, där man i första enbart väljer bland optgroup-rubrikerna och sedan väljer värde. Denna används inte automatiskt utan måste anropas när den är önskvärd, med.</p>
<pre class="brush: jscript;">$('select optgroup').parent('select').ungroupOptgroup();</pre>
<h2>Ladda hem HTML5Forms</h2>
<p>Om du har läst ända hit tycker jag att du nu förtjänar att få ladda hem skript och börja leka, använda och vidareutveckla.<br />
Om du saknar någon viss formulärfunktionalitet, upptäcker någon bugg eller vill veta mer om skriptet, så får du gärna höra av dig.<br />
<a title="HTML5Forms" href="http://blogs.creuna.se/wp-content/uploads/2010/10/forms.zip">HTML5Forms (ZIP)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.creuna.se/2010/10/framtidens-formular-idag/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CSS Pseudoklasser i IE</title>
		<link>http://blogs.creuna.se/2010/08/css-pseudoklasser-i-ie/</link>
		<comments>http://blogs.creuna.se/2010/08/css-pseudoklasser-i-ie/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 09:32:39 +0000</pubDate>
		<dc:creator>Fredrik Gustafsson</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Internet Explorer]]></category>

		<guid isPermaLink="false">http://blogs.creuna.se/?p=241</guid>
		<description><![CDATA[Att utveckla för Internet Explorer innebär ofta att man skapar speciallösningar och att man bygger skript som åstadkommer samma stilningsresultat som riktiga webbläsare hanterar med CSS. På så sätt bildas det dubbletter där man får samma resultat på två olika ställen och man definierar sidans design både i CSS och i javascript. När man sedan [...]]]></description>
			<content:encoded><![CDATA[<p>Att utveckla för Internet Explorer innebär ofta att man skapar speciallösningar och att man bygger skript som åstadkommer samma stilningsresultat som riktiga webbläsare hanterar med CSS. På så sätt bildas det dubbletter där man får samma resultat på två olika ställen och man definierar sidans design både i CSS och i javascript. När man sedan vill ändra designen eller vidareutveckla sajten blir det ett väldigt arbete att hitta alla stylesättande skript.</p>
<p>Trots att Internet Explorer saknar mycket funktionalitet i CSS har den en feature som är väldigt praktisk, i IE kan du sätta variabler med CSS.</p>
<p>a.mylink{ store-my-valueplease : 45px; } Trots att webbläsaren inte förstår stilklassen lagras den och är åtkomlig via javascript.</p>
<p>Tack vare denna bug/feature, kan man definiera egna stilklasser specifika för IE som bakomliggande skript kan använda för att uppnå det önskade beteendet, medan alla stilregler sätts enbart i CSS, precis som det ska vara.</p>
<p>Med denna teknik har jag byggt några tillämpningar för vanliga stilmallsklasser och pseudoelement som Internet Explorer saknar.</p>
<p>Kodexempel följer!</p>
<p><span id="more-241"></span></p>
<p><strong>min-width / max-width / min-height / max-height</strong></p>
<p>IE6 saknar möjligheten att tolka min och max klasser i CSS, men med ett litet skript kan samma resultat uppnås.</p>
<pre>$.fn.cssMaxWidth = function(){
	this.each(function(){
		if ($(this).css('max-width') != "none"){ //fix for IE6
			var maxWidth = $(this).css('max-width').match(/^(.+?)px$/)[1];
			if ($(this).width()&gt;maxWidth){
				$(this).width(maxWidth);
			}
		}
	});
	return this;
};
</pre>
<p>Funktionen anropas på de obejkt som ska genomsökas efter stilklassen max-width.</p>
<pre>if ($.browser.msie&amp;&amp;($.browser.version&lt;7)){ //anropas enbart för IE6 och tidigare
$('img).cssMaxWidth();
}</pre>
<p>Beaktka att width (utan overflow:hidden) i IE6 fungerar på samma sätt som min-width gör i andra webbläsare och behöver oftast inte specialscript.</p>
<p><strong>first-child / last-child</strong></p>
<p>I de flesta moderna webbläsare kan du med CSS peka ut första och sista elementet av en viss typ med pseudoselektorn :first-child, :last-child. Denna funktionalitet är dock inte implementerad i någon av versionerna för Internet Explorer och behöver därför uppnås med script eller klassnamn på första och sista elementet. Då klassnamn är att föredra eftersom det fungerar även utan javascript, kan det i vissa fall vara smidigt att styla första och sista elementet lite annorlunda.</p>
<pre>$.fn.cssFirstChild = function () {
    //Fix for IE6, IE7, IE8 (in IE8 this only works if styles is not combined with :first-child)
    // combined with the css-class e.g. 'selector: '.classname'; you can specify what object you wnat the last-child of.
    this.each(function () {
        if ($(this).css('first-child')) {
            var firstChild = $(this).css('first-child').match(/^['"]?(.+?)["']?$/)[1];
            if ($(this).css('selector')) {
                var selector = $(this).css('selector').match(/^['"]?(.+?)["']?$/)[1];
                $(this).find(selector + ':first-child').addClass(firstChild);
            } else {
                $(this).find(':first-child').addClass(firstChild);
            }
        }
    });
    return this;
};
$.fn.cssLastChild = function(){
	//Fix for IE6, IE7, IE8 (in IE8 this only works if styles is not combined with :last-child)
	// combined with the css-class e.g. 'selector: '.classname'; you can specify what object you wnat the last-child of.
	this.each(function(){
		if ($(this).css('last-child')){
			var lastChild = $(this).css('last-child').match(/^['"]?(.+?)["']?$/)[1];
			if ($(this).css('selector')){
				var selector = $(this).css('selector').match(/^['"]?(.+?)["']?$/)[1];
				$(this).find(selector+':last-child').addClass(lastChild);
			} else {
				$(this).find('&gt;:last-child').addClass(lastChild);
			}
		}
	});
	return this;
};
</pre>
<p>Med dessa plugins sätter man in egna klasser på första eller sista elementet, och stilar sedan det objektet med en vanlig klasselektor.<br />
<code> </code></p>
<pre>#main-nav ul li:last-child{<em>style</em>}
#main-nav ul{
last-child : "last-child";
selector : 'li'   /* Selector är valfri, men gör att du kan välja mer specifika objekt ex. li.odd  */
}
#main-nav ul li.last-child{<em>style</em>}
</pre>
<p>Beakta att stilmallarna för li.last-child måste skrivas separat trots att de är identiska med de för li:last-child, men IE hoppar över hela objektet då den läser li:last-child och de kan därför inte kombineras.</p>
<p><strong>mychild / mysibling</strong></p>
<p>I moderna webbläsare kan man med hjälp av selektorerna + och &gt; begränsa sök mängden till direkta syskon eller direkta barn, denna funktionelitet stöds inte i IE6 och IE7 dock, men då finns det ett plugin även för detta.</p>
<pre>$.fn.cssMyChild = function(){
	this.each(function(){
		if ($(this).css('myChild')){ //fix for IE6, IE7
			var myChild = $(this).css('myChild').match(/^['"]?(.*?)["']?$/)[1].split('.');
			$(this).children(myChild[0]).addClass(myChild[1]);
		}
	});
	return this;
}
$.fn.cssMySibling = function(){
	this.each(function(){
		if ($(this).css('mySibling')){ //fix for IE6, IE7
			var mySibling = $(this).css('mySibling').match(/^['"]?(.*?)["']?$/)[1].split('.');
			$(this).parent().children(mySibling[0]).addClass(mySibling[1]);
		}
	});
	return this;
}
</pre>
<p>Dessa kan användas på liknande sätt som last-child,</p>
<pre>#container &gt; div{<em>style</em>}
#container{
myChild : 'div.children';
}
#container div.children{<em>style</em>}

#main + div{<em>style</em>}
#main{
mySibling : 'div.sibling';
}
#main div.sibling{<em>style</em>}
</pre>
<p><strong>after / before</strong><br />
Det är även möjligt att skapa pseudoelement på liknande sätt som kan göras med :after och :before i vettiga webbläsare.</p>
<pre>$.fn.cssAfter = function(){
	//Fix for IE6, IE7 (IE 8 sets dubble if combined with :after)
	return this.each(function(){
		if ($(this).css('after')){
			var after = $(this).css('after').match(/^['"]?(.*?)["']?$/)[1];
			if (after.substr(0,3) == 'url'){
				after=$('<img alt="" />').attr('src', after.substr(5,after.length-7)).addClass('after');
			}
			$(this).append(after);
		}
	});
};
$.fn.cssBefore = function(){
	//Fix for IE6, IE7 (IE 8 sets dubble if combined with :after)
	return this.each(function(){
		if ($(this).css('before')){
			var before = $(this).css('before').match(/^['"]?(.*?)["']?$/)[1];
			if (before.substr(0,3) == 'url'){
				before=$('<img alt="" />').attr('src', before.substr(5,before.length-7)).addClass('before');
			}
			$(this).prepend(before);
		}
	});
};
</pre>
<p>Med dessa stilar man på följande sätt</p>
<pre>a:after{
content : "\A00BB";
}
a{
after : "\A00BB";
}
blockquote:before{
content : url('quote.png');
}
blockquote{
before : url('quote.png');
}
</pre>
<p><strong>hover / focus</strong><br />
PseudoEventSelektorerna :hover och :focus stöds faktiskt i samtliga versioner av Internet Explorer, men enbart på länkar och inputfält. Vill man styla andra objekt vid fokus eller hover, kan man använda detta plugin.</p>
<pre>$.fn.cssHover = function(){
	this.each(function(){
		if ($(this).css('hover')){ //fix for IE6
			var hover = $(this).css('hover').match(/^['"]?(.+?)["']?$/)[1];
			$(this).mouseover(function(){$(this).addClass(hover);}).mouseout(function(){$(this).removeClass(hover);});
		}
	});
	return this;
}
$.fn.cssFocus = function(){
	this.each(function(){
		if ($(this).css('focus')){ //fix for IE6, IE7
			var focus = $(this).css('focus').match(/^['"]?(.+?)["']?$/)[1];
			$(this).focus(function(){$(this).addClass(focus);}).blur(function(){$(this).removeClass(focus);});
		}
	});
	return this;
}
</pre>
<p>Med stilmallen<br />
<code> </code></p>
<pre>#main-nav li:hover ul{
display:block;
}
#main-nav li{
hover : 'overme';
}
#main-nav li.overme ul{
display:block;
}
</pre>
<p>Samma princip går att utnyttja för massor med liknande funktioner för att få IE at fungera lite bättre, men tänk på att enbart använda dessa funktioner för sådant som inte är nödvändigt för att kunna använda sidan, eftersom de inte kommer att fungera för användare som inte har stöd för javascript.</p>
<p>Beakta även att även om dessa klaser går utmärkt att blanda med andra stilar eftersom de ignoreras av alla webbläsare, resulterar de i invalida stilmallar och bör begränsas till IE-specifika mallar. Kom även ihåg att applicera dessa plugins på alla de typer av objekt som de ska användas för och enbart i de webbläsare där de faktiskt behövs.</p>
<pre>if ($.browser.msie&amp;&amp;$.browser.version&lt;7){
		$('#main-nav li').cssHover();
}
if ($.browser.msie&amp;&amp;$.browser.version&lt;8){
	$('a, blockquote').cssAfter();
	$('a, blockquote').cssAfter();
}
if ($.browser.msie&amp;&amp;$.browser.version&lt;9){
		$('#main-nav ul').cssLastChild();
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blogs.creuna.se/2010/08/css-pseudoklasser-i-ie/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Svunna minnen från SWDC</title>
		<link>http://blogs.creuna.se/2010/08/svunna-minnen-fran-swdc/</link>
		<comments>http://blogs.creuna.se/2010/08/svunna-minnen-fran-swdc/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 15:03:15 +0000</pubDate>
		<dc:creator>Fredrik Gustafsson</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[konferens]]></category>
		<category><![CDATA[mobilt]]></category>
		<category><![CDATA[webbstandards]]></category>

		<guid isPermaLink="false">http://blogs.creuna.se/?p=228</guid>
		<description><![CDATA[Två månader har hunnit passera sedan jag var på Scandinavian Web Developer Conference 2010 på Skandiateatern i Stockholm. Det var två fullspäckade heldagar om webbutveckling och mobilutveckling med moderna webbtekniker, av några av världens mest framstående talare på området.
Första dagen talade bland andra Daniel Glazman (@glazou) som är en av de gamla rävarna från W3C [...]]]></description>
			<content:encoded><![CDATA[<p>Två månader har hunnit passera sedan jag var på Scandinavian Web Developer Conference 2010 på Skandiateatern i Stockholm. Det var två fullspäckade heldagar om webbutveckling och mobilutveckling med moderna webbtekniker, av några av världens mest framstående talare på området.</p>
<p>Första dagen talade bland andra <strong>Daniel Glazman (@glazou)</strong> som är en av de gamla rävarna från W3C som har varit med från allra första början när webben vuxit fram till vad det är idag. Han predikade självklart om vikten av webstandarder och att vi måste börja använda de nya teknikerna i HTML5, CSS3 för att gamla avdankade webbläsare som Internet Explorer 7 och 6 måste försvinna. Flash är en bra platform, men den kräver en annan kompetens som kostar mer för samma resultat.</p>
<blockquote><p>&#8221;We dont want to kill  flash, it will be an unexpected side-effect&#8221;</p></blockquote>
<p>Han visade exempel på hur man med Canvas kan spela mariocart på en ipad och styra genom att komma åt ipadens accelerometer, direkt i webbläsaren. <a href="http://www.nihilogic.dk/labs/mariokart/">(http://www.nihilogic.dk/labs/mariokart/</a>).</p>
<p>Allas vår egen <strong>Robert Nyman (@robertnyman)</strong> från Valtech, presenterade HTML5 och vilka möjligheter det medför för utvecklare och användare.</p>
<p><strong>Cristian Heilmann (@codepo8) </strong>från Yahoo, predikade som alltid om Progressive Enhancement, och att alla webbplatser ska gå att använda på en dålig mobiltelefon, med en taskig uppkoppling utan javascript. Men användarna bryr sig inte om de coola effekter och funktioner som vi utvecklare lägger ner dagar på att utveckla och anpassa för att de ska se lika bra ut i IE6 som i Safari.</p>
<p>De flesta användare som sitter med gammal utrustning och dåliga webbläsare har inte något val. Antingen är de rädda för virus och inte vågar ladda hem någonting nytt, eller så sitter de på ett företag där de inte får ha javascript påslaget pågrund av att javascript är en säkerhetsrisk (om den används på fel sätt), eller vet inte skillnaden på webbläsare, sökmotor och epost. Låt informationen vara åtkomlig och gör webbplatser tillgängliga, men låt varje teknik hantera den &#8221;design&#8221; den klarar av. Tvinga inte in runda hörn, transparens, skuggor, lagerpålager, ajax och max-bredder på de plattformar som inte är gjorda för dem, för användarna bryr sig inte om det som vi tycker är ballt.</p>
<p>Han föreslog en underbar slutgiltig lösning på hur vi tillsammans kan hjälpas åt för att få bort IE6 utan att sluta stödja den. Amelie from Montemartmetoden (<a href="http://icant.co.uk/ie6-amelie/">http://icant.co.uk/ie6-amelie/</a>) är ett litet skript som vi kan lägga in på våra webbplatser som utnyttjar en väldigt konstig &#8221;blur&#8221;-effekt som finns stöd för i IE6. Men slumpmässiga mellanrum kommer all text på webbsidan att bli suddig för IE6 användare under ett kort ögonblick. Efter några månade talar man om att det kan bero på mjukvaruutmattning och att om det inte åtgärdats även kan drabba hårdvaran. <img src='http://blogs.creuna.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Ändra IE6 problemet från ett teknikproblem till ett hälsoproblem, så får det en helt annan prioritet.</p>
<p><strong>Rik Arends (@rikarends) </strong>från Ajax.org demate ett väldigt läckert webbaserat IDE (@cloudide<cite></cite>) för kooperativ webbutveckling i molnet. Det ger möjlighet för designer, frontend-utvecklare, backendutvecklare och testare att samarbeta, utveckla och köra lösningar direkt i molnet via webbläsaren. Designer skapar ett GUI genom drag and drop som sedan byggs logik till av utvecklarna. Testfall kan skapas på ursprungliga prototyper som sedan körs och spelas in medan produkten vidareutvecklas. Som ett komplett bättre Visual Studio i molnet med direktkoppling till GitHub.</p>
<p>Andra talare under första dagen pratade om nodeJS, CouchDB, javascriptmoduler för stora webbplatser, google chrome extensions och google för utvecklare.</p>
<p>Dag två inriktade sig helt på mobil utveckling och hur vi med Offline storage, geolocation, canvas, CSS3, PhoneGap etc kan skapa häftiga applikationer för mobiltelefoner och andra enheter som gör upplevelsen riktigt häftig.</p>
<p><a href="http://mini.softwareas.com/my-swdc-talk-html5-gives-you-wings-done"><img class="alignleft" src="http://posterous.com/getfile/files.posterous.com/mahemoff/GCDfmAoEcgwrBxmnlceFFyArCmbibqyCfpxpGaJkwvtfnFpcgqDInFEDqtDC/media_httpfarm5static_kxwFw.jpg.scaled500.jpg" alt="" width="127" height="170" /></a><strong>Michael Mahemoff (@mahemoff)</strong> från Google, skapare av Ajaxian.com och författare till boken &#8221;Ajax  design patterns&#8221; talade också om hur HTML5 ger oss utvecklare vingar och  möjliggör helt nya webbplatser och applikationer i webbläsaren. Han  visade hur man på klienten kan lagra data, offline-manifest och köra  avancerade javascript i bakgrundsprocesser, där olika enheter kan  kommunicera och styra samma process. För mobiltelefoner är det väldigt  viktigt eftersom man kan hantera &#8221;shaky connections&#8221;, klara av avbrott  för samtal och utnyttna webbläsarens fulla processor för skript och gui.</p>
<p><strong>Wolfram Kriesing (@wolframkriesing)</strong> talade om &#8221;Cross platform Mobile Apps&#8221; och lätt det är att skapa kraftfulla mobilapplikationer med hjälp av W3C Widgets och PhoneGap som fungerar för iPhone, Android, Palm, Blackberry, Nokia och Windows mobile, utan att utveckla en applikation för varje enhet.</p>
<p>Det finns upp till 50 olika mobila appstores för olika plattformar och olika utvecklingsspråk, varav 26 är riktigt stora. Webbapplikationer är det enda sättet att skapa applikationer som fungerar i samtliga telefoner.</p>
<p>W3C Widgets är ett paket av html-filer, css-filer, xml-config, ajax-bibliotek och en ikon som är zippade och omdöpt till .wgt, det skapar en widget som kan komunicera med webben som ex. facebook-dashboard-widgets.</p>
<p>PhoneGap är en lösning som ger webbsidor tillgång till telefonens hårdvara med hjälp av javascript och gör det möjligt att skapa riktiga applikationer av HTML, CSS och JS som kan genereras för alla olika plattformar. PhoneGap finns för att fylla gapet som finns mellan webb och OS till det att det stöds av alla telefoner och gör det möjligt att med javascript använda telefonens kamera, adressbok, gps, accelerometer, bildgalleri etc etc.</p>
<p>En annan väldigt intressant föreläsning var <strong>Tom Hughes Croucher (@sh1mmer) </strong>som talade om &#8221;How to avoid the latence trap when using web services&#8221;. Han menade att det största problemet som vi som mobilwebbutvecklare har är latens. Latens uppstår vid alla typer av kommunikation speciellt trådlöst, av störande enheter, eller slöseri på bandbredd då en massa extrauppgifter skickas med varje paket. Det gäller därför att optimera bandbredden för maximal utdelning. Iphon kan t.ex. hantera 6 paralella anrop per domän, det kan därför vara en fördel att dela upp stilmallar, bilder och javascript i olika filer och på olika domäner.</p>
<p>Yahoo YQL är en samling av öppna APIer där din webbapp enbart behöver skicka textsträngar till Yahoos snabba servrar som sedan kommunicerar vi diverse andra servrar och sedan levererar resultatet till telefonen, vilket medför att fler anrop kan skickas snabbare utan att behöva vänta på svarstider från olika apier. <a href="http://speakerrate.com/talks/1986-mobile-data-how-to-avoid-the-latency-trap-when-using-web-services">Slides här</a></p>
<p><strong>Tim Caswell (@creationix)</strong> visade tillslut hur man i Node.js kan bygga webbsajter där mobila enheter kan kopplas samman och interagera i realtid i samma webbapplikation.</p>
<p>Det var mycket intressant att lära sig på dessa två konferensdagar anordnade av Peter Svensson (@psvensson). Ett stort tack och jag ser fram emot nästa år, när dessa revolutionerande webbtekniker har fått ytterligare ett år på sig att mogna.</p>
<p>Nu är det dags för Creuna att börja utveckla mobila webbappar, så jag kan få sätta mina införskaffade &#8221;kunskaper&#8221; i praktiken!</p>
<p><a href="http://swdc-central.com/">http://swdc-central.com/</a></p>
<p><a href="http://www.phonegap.com/">http://www.phonegap.com/</a></p>
<p><a href="http://www.w3.org/TR/widgets/">http://www.w3.org/TR/widgets/</a></p>
<p><a href="http://nodejs.org/">http://nodejs.org/</a></p>
<p><a href="http://couchdb.apache.org/">http://couchdb.apache.org/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.creuna.se/2010/08/svunna-minnen-fran-swdc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

