<?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>RSS 2.0 Článků kategorie "HTML, CSS, JavaScript"</title>
	<atom:link href="https://mike.treba.cz/rss/kategorie/xhtml-css-javascript/" rel="self" type="application/rss+xml" />
	<link>https://mike.treba.cz/</link>
	<description>RSS 2.0 Článků kategorie "HTML, CSS, JavaScript"</description>
	<lastBuildDate>Mon, 30 Dec 2024 22:21:10 +1100</lastBuildDate>
	<language>cs</language>
	<generator>Abstract CMS</generator>
	<sy:updatePeriod>daily</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>

		
		<item>
			<title>Webová typografie: odstavce a odsazování</title>
			<link>https://mike.treba.cz/webova-typografie-odstavce-a-odsazovani/</link>
			<pubDate>Mon, 30 Dec 2024 22:21:10 +1100</pubDate> 
			<comments>https://mike.treba.cz/webova-typografie-odstavce-a-odsazovani/#comments</comments>
			<dc:creator></dc:creator>
			<description><![CDATA[<p><span>Rychlovka z&nbsp;oboru #4. V praxi se často setkáváme s odsazováním pomocí prázdných odstavců. Byť je to řešení naprosto nejsnazší, není úplně správné. Možnosti jsou víceméně dvě. V dnešním článku vám popíšu jednu z nich.&nbsp;</span></p>]]></description>   
			<guid isPermaLink="false">https://mike.treba.cz/webova-typografie-odstavce-a-odsazovani/</guid>
			<content:encoded><![CDATA[<p><span>Rychlovka z&nbsp;oboru #4. V praxi se často setkáváme s odsazováním pomocí prázdných odstavců. Byť je to řešení naprosto nejsnazší, není úplně správné. Možnosti jsou víceméně dvě. V dnešním článku vám popíšu jednu z nich.&nbsp;</span></p> <p>Když chystáme web "na slepo" a grafik nám nepřipraví dostatečně obsáhlou textovou stranu, daný problém zpravidla neřešíme. Pokud ovšem vytváříme novou grafiku již existujícího webu, který má dostatek obsahu pro kontrolu, můžeme formátování textů nachystat mnohem lépe.&nbsp;</p>
<p>První věc, kterou musíme rozhodnout, je odsazování pomocí marginů či paddingů. Setkal jsem se s obojím, ale sám budu vždy preferovat spodní padding oproti hornímu a spodnímu marginu. Marginy mají tu výhodu, že se slijí dohromady, nicméně je to pořád neintuitivní chování, které se musíme v hlavě představit kdykoli, když skládáme libovolné elementy za sebe.&nbsp;</p>
<p>Proto je za mě lepší vždy a jenom spodní odsazení. Pro * &gt; :last-child pak stačí resetovat na nulu a máme hotovo.&nbsp;</p>
<p>Jakmile si nastavníme nějaké globální odsazení základních typografických elementů, můžeme se zamyslet nad celkovou strukturou očekávaných článků. Používá klient 2 nadpisy za sebou? Používá klient nadpisy jen jako grafické zdůraznění nebo se jedná o logické celky, které je potřeba oddělit víc? Má klient rád vzdušné stránky, kde není vše namačkáno na sebe?&nbsp;</p>
<p>Pokud je odpověď na většinu z těchto otázek kladná, stačí nám přidat opravdu jen pár definic, aby se výše uvedené věci začaly dít samy. Tady na blogu to dělám úplně stejně.</p>
<h2>Globální definice</h2>
<p>Začneme jednoduchou ukázkou kódu. Z ní je na první pohled jasné, že všechny seznamy a nadpisy, které budou natvrdo v šabloně musíme redefinovat. Ale ono se stačí zamyslet nad poměrem: Omezený počet elementů v šablonách vs. libovolný počet html textu, který nám do šablony dodá systém? Nutnost ručně přidávat všechny definice pokaždé, když přidám novou typovou šablonu? Ne, děkuji. Raději si těch pár prvků mimo obsahovou oblast zresetuji sám.&nbsp;</p>
<pre><code class="css">h1 {padding-bottom:4rem;}

p,
h2,
h3 {padding-bottom:2rem;}

ul, 
ol, 
table {margin-bottom:2rem;}

h4,
h5 {padding-bottom:1rem;}
</code></pre>
<p>Mějme základní definice odsazení. 40 pixelů pro nadpis první úrovně, 20 pixelů pro zbytek. Následující kód vyřeší groupování jednotlivých sekcí tak, abychom v administraci nemuseli řešit vůbec nic navíc. <em>(Komponenty, x různých html bloků pod sebou, oddělovače...)</em>&nbsp;</p>
<h2>Logický blok začíná nadpisem</h2>
<p>Každý nadpis bude odsazen o dalších 20 <span class="small-text">(10, 5)</span> pixelů, pokud před ním není jiný nadpis stejné nebo vyšší úrovně.&nbsp;</p>
<pre><code class="css">.article-detail {

	*:not(h2) &plus; h2 {padding-top:2rem;} 
	*:not(h2):not(h3) &plus; h3 {padding-top:1rem;} 
	*:not(h2):not(h3):not(h4) &plus; h4 {padding-top:0.5rem;} 

}</code></pre>
<p>Je to takhle jednoduché.&nbsp;</p>
<h2>Dvojité odsazení</h2>
<p>Použití padding-bottom namísto dvojitého marginu má ještě další výhodu, kterou je automatické zvedání hodnot u prvků typu &lt;table&gt;. Tabulka musí být vždy odsazena marginem. Pokud chceme pro náš příklad zvednout její odsazení na dvojnásob, nemusíme se bát spojení marginu s předchozím prvkem.&nbsp;</p>
<p>Chceme-li zdůraznit tabulku, která je přesně mezi dvěma odstavci, stačí jednoduše:</p>
<pre><code class="css">p &plus; table {margin-top:2rem;}
p &plus; table &plus; p {padding-top:2rem;}</code></pre>
<p>Spolu s výchozím odsazením, které prvky zdědily z prvního bloku kódu, máme krásných 40 pixelů z obou stran.&nbsp;</p>]]></content:encoded>
			<image>
    				<url>https://mike.treba.cz/img/2023/renewed/design-art.jpg</url>
			</image>
		</item>
		
		
		<item>
			<title>Stylování formulářů snadno a rychle</title>
			<link>https://mike.treba.cz/stylovani-formularu/</link>
			<pubDate>Tue, 15 Dec 2020 19:09:51 +1100</pubDate> 
			<comments>https://mike.treba.cz/stylovani-formularu/#comments</comments>
			<dc:creator></dc:creator>
			<description><![CDATA[<p>Než si dáme další článek z dílny seriálového kritika, proložím své recenze jedním z oboru. Takový už jsem nepsal ani nepamatuji, ale snad si vzpomenu, jak se to dělá. A protože mé návody byly vždy cílené na kodéry začínající a mírně pokročilé, vezmu si pod lupu stylování formulářů. Úplné základy. </p>]]></description>   
			<guid isPermaLink="false">https://mike.treba.cz/stylovani-formularu/</guid>
			<content:encoded><![CDATA[<p>Než si dáme další článek z dílny seriálového kritika, proložím své recenze jedním z oboru. Takový už jsem nepsal ani nepamatuji, ale snad si vzpomenu, jak se to dělá. A protože mé návody byly vždy cílené na kodéry začínající a mírně pokročilé, vezmu si pod lupu stylování formulářů. Úplné základy. </p> <p>Je to nutné zlo, které člověk musí trpět poměrně často. Ale technologie pokročily, takže se s tím dá poprat velice snadno i bez použití složitých frameworků. Ty buď máte zvládnuté a neřešíte nic, nebo vám činnost spíš zkomplikují. U formulářů to platí dvojnásob.</p>
<h2>Základní resety</h2>
<p>Relativní jednotky zatím řešit nebudeme. Hezky všechno v pixelech, ať v tom nedělám ještě větší zmatky. </p>
<pre><code class="css">* {
	border:0;
	margin:0;
	padding:0;
	-webkit-box-sizing:border-box;
	box-sizing:border-box;
}
:focus {outline:none;}

button,
input,
textarea,
select {
	-webkit-appearance:none;
	-moz-appearance:none;
	appearance:none;
	border-radius:0;
}</code></pre>
<p>Appearance je nejdůležitější vlastnost, které je třeba se zbavit, ať nám to neblbne na telefonech a iOS zařízeních. A pak můžeme úplně v klidu nastavit globální styl pro základní formulářové prvky. Dřív platilo, že hvězdičkový reset na formulářové prvky ne. To už naštěští nějakou dobu nemusíme řešit, takže ušetříme spoustu zbytečností ve stylech.</p>
<p><strong>Nesmíme zapomenout</strong> nastavit kompletní vlastnosti fontu. Tohle bohužel mnohé prohlížeče neumí zdědit z body. Stejně tak <strong>box-sizing</strong>: nemáme-li ho v resetu, je potřeba nastavit pro uvedené elementy. Pro textareu zvedneme výšku a omezíme <strong>resize</strong> na směr i hodnoty.</p>
<pre><code class="css">body, 
input, 
textarea, 
select, 
button {
	font:400 16px/1.5 Arial,Helvetica,sans-serif;
}

input:not([type="radio"]):not([type="checkbox"]),
select,
textarea {
	display:block;
	color:#000;
	padding:10px 15px;
	height:50px;
	width:100%;
	border:1px solid #e1e1e1;
	/*
	-webkit-box-sizing:border-box;
	box-sizing:border-box;
	*/
}

textarea {
	height:200px;
	min-height:100px;
	max-height:1000px;
	resize:vertical;
}</code></pre>
<p>A to je k základním prvkům vše. Všimněte si, že základní pole nemám jako výčet hodnot, ale jako výjimku ze všech. HTML5 nám nabízí mnohem vyšší škálu typů, než jenom [text] a [password]. </p>
<p>Tlačítko si pak můžeme upravit jakkoli uznáme za vhodné, já ho vykreslím jen jako šedý obdélník. Pod tag &lt;form&gt; ho mám vnořené cíleně, protože grafik nám často naplánuje různě vypadají buttony pro formulář a mimo něj. </p>
<pre><code class="css">form button, 
form input[type="submit"] {
	cursor:pointer;
	background:#e1e1e1;
	transition:.25s;
	min-width:100px;
	border:0;
	height:50px;
}
form button:hover, 
form input[type="submit"]:hover {
	background:#888;
	color:white;
}</code></pre>
<h2>Placeholder</h2>
<p>Než nám moderní technologie povolily atribut placeholder, museli jsme výchozí hodnoty složitě měnit JavaScriptem. Nyní je ale vše mnohem jednoduší, snad s výjimkou stylování. Tam malý zádrhel je. Vlastnosti musí být zapsané tak, jak je mám na následující ukázce. Pokud totiž vše zapíšeme za sebe s čárkou, IE Edge nás s tím pošle do háje. Takže <strong>pro každý prefix jedna ukončená definice</strong>. </p>
<pre><code class="css">textarea::placeholder,
input::placeholder {color:#e1e1e1;} 

textarea:-ms-input-placeholder,
input:-ms-input-placeholder {color:#e1e1e1;}

input:not([readonly]):not([disabled]):focus,
textarea:not([readonly]):not([disabled]):focus {border-color:#a1a1a1;}</code></pre>
<h2>Grafický selecbox</h2>
<p>Další problematický prvek je selectbox. V minulosti bylo potřeba na jeho složitější vykreslení povolat JavaScriptovou knihovnu, nyní se však obejdeme bez ní. Pokud ale potřebujeme komplexnější prvky uvnitř drop-down nabídky, čistým stylováním to bohužel nezvládneme. JS knihoven jsem vyzkoušel větší množství, ale nakonec jsem vždy došel k závěru, že je lepší, když si to prostě napíšu sám. Žádná není na 100 % dokonalá. U každé narazíme na nějaké bugy, či události, které neumí. Nejnovější knihovnička mi zabrala asi 3 hodiny, což zhruba odpovídá času, který bych strávil studiem a debugováním nějakého hotového řešení... Často je lepší, když si to člověk napíše sám.</p>
<p>Ale zpět ke stylování klasického selectu. Jediné omezení, které musíme překousnout, je nemožnost upravit samotný drop-down. Jediné, k čemu nás prohlížeče pustí, je velikost písma a barvy. </p>
<p>Hlavní select se dá ovšem nastylovat se vším všudy, bez jakýchkoli problémů. Pokud stále řešíme IE 11, definici backgroundu je nutné rozepsat, protože IE 11 ji nepochopí, když obsahuje funkci calc(). A já raději použiju calc, než abych naschvál ukládal png obrázek s bílým místem, kvůli marginu.</p>
<pre><code class="css">form select {
	padding-right:50px;
	cursor:pointer;
	background:url(select.png) no-repeat;
	background-position:calc(100% - 15px) 50%;
	background-size:20px auto;
}
form select option {
	font-size:110%;
	color:#013be0;
}
form select option:hover {
	background:#013be0;
	color:white;
}
form select::-ms-expand {
	display:none;
}
form select:focus {
	border-color:#a1a1a1;
	color:black;
	text-shadow:0 0 0 #000;
	font-weight:400;
}</code></pre>
<h2>Grafický checkbox a radio</h2>
<p>Ani zde není potřeba volat JavaScript a stylovat prvky pomocí nastrčených spanů. Valná většina moderních prohlížečů umí vykreslit základní styly pro checkbox i radio správně, výjimkou budiž jen Internet Explorer 11. Ale ani on není extra pozadu; "škaredě" vykreslí pouze puntík, respektive fajfku při stavu :checked. </p>
<pre><code class="css">form input[type="radio"],
form input[type="checkbox"] {
	margin:0 15px 0 0;
	font-size:24px;
	width:1em;
	height:1em;
	border:2px solid #e1e1e1;
	border-radius:0;
	display:inline-block;
}
form input[type="checkbox"]:checked {
	border-color:#013be0;
	background:url(checkbox.png) no-repeat 50% 50%/80% auto;
}

form input[type="radio"] {
	border-radius:50%;
	background:url(radio.png) no-repeat -100px 50%/50% auto;
}
form input[type="radio"]:checked {
	border-color:#013be0;
	background-position:50% 50%;
}
form label.radio,
form label.checkbox {
	display:flex;
	align-items:center;
}</code></pre>
<p>Není to vůbec nic složitého: nějaké barvy a obrázky, zarovnání a odsazení, a máme hotovo. Pokud chceme stejně hezké prvky i pro zmiňovaný IE 11, je potřeba přidat pomocné spany, ale i tady se úspěšně vyhneme JS obsluze. Stačí přidat pár CSS definic pro posloupné prvky. To už si ale prohlédněte na přiložené ukázce. </p>
<h2>Závěrem: přístupnost na prvním místě</h2>
<p>Na závěr bych ještě rád zmínil jednu věc, kterou vídám v poslední době stále častěji. Mám na mysli různé "cool" efekty, které mají formuláře takříkajíc zkrášlit. Máme label, který je vepsaný přímo přes textové pole a supluje funkci placeholderu. Na focus popisek vyjede nahoru přes definovanou transition. Určitě už jste to někdy viděli. Funkce je to sice pěkná, ale zoufale nepraktická... Problém nastává ve chvíli, kdy nám prohlížeč automaticky jednotlivá pole vyplní. JavaScript totiž neumí univerzálně detekovat tuto událost, a tak se nám může stát, že label je překrytý přes hodnotu v poli. To sice lze vyřešit několika způsoby, ale my bychom si spíš měli položit otázku: proč bych měl tohle vůbec ladit?</p>
<p>Jako uživatel chci formulář přehledný a jednoduchý, jako kodér chci formulář... můžete hádat, jaký. Není formulář v příloze sympatičtější, než nějaká pekelná monstra, co vám třikrát obletí svět, než vás pustí k vyplnění? </p>
<p class="download-links">Ukázka: <a href="doc/2020/form/" target="_blank">form.html</a></p>]]></content:encoded>
			<image>
    				<url>https://mike.treba.cz/img/2020/web/pexels-photo-code-2.jpeg</url>
			</image>
		</item>
		
		
		<item>
			<title>Ajaxové stránkování: základy</title>
			<link>https://mike.treba.cz/ajaxove-strankovani-zaklady/</link>
			<pubDate>Wed, 29 Apr 2020 21:59:33 +1100</pubDate> 
			<comments>https://mike.treba.cz/ajaxove-strankovani-zaklady/#comments</comments>
			<dc:creator></dc:creator>
			<description><![CDATA[<p>Úpravy vlastního webu mi daly podklady pro nový článek, který se bude věnovat Ajaxovému stránkování. Tedy přesněji, jak nalepit Ajax na existující výstup. Budu předpokládat, že nějaký výpis článků z databáze už máte hotový a podívám se detailněji na úpravy, kterými musí systém projít. Složité úpravy to určitě nebudou. Článek bude směrovaný k začínajícím kodérům. </p>]]></description>   
			<guid isPermaLink="false">https://mike.treba.cz/ajaxove-strankovani-zaklady/</guid>
			<content:encoded><![CDATA[<p>Úpravy vlastního webu mi daly podklady pro nový článek, který se bude věnovat Ajaxovému stránkování. Tedy přesněji, jak nalepit Ajax na existující výstup. Budu předpokládat, že nějaký výpis článků z databáze už máte hotový a podívám se detailněji na úpravy, kterými musí systém projít. Složité úpravy to určitě nebudou. Článek bude směrovaný k začínajícím kodérům. </p> <p>Pošlu request, dostanu výstup, vepíšu výstup: nejkratší možná cesta, nic víc. Až v závěru článku nastíním, jak by se daná funkcionalita mohla <em>(měla)</em> řešit lépe. Ale věřím, že pro začátek to takhle stačí. </p>
<h2>Co musí být hotové</h2>
<p>Abych nemusel rozebírat úplné a naprosté základy, naopak zase předpokládám, že to hlavní už je hotové. Musíme mít výpis článků z databáze. K tomu stránkování. Jak bude vypadat a jak se bude chovat, na tom nezáleží: musí prostě jen fungovat. Také bychom měli mít aspoň minimálně oddělený kontroler od šablony, abychom mohli využít podmíněné tahání jednotlivých bloků stránky. </p>
<h2>Co musíme upravit</h2>
<p>V prvé řadě <strong>šablonu</strong> tak, abychom měli jasně ohraničený cíl, kam se bude vpisovat obsah. Dále <strong>kontrolery</strong>. Pokud posílám Ajax request na výpis článků, nechci přece zbytečně načítat celé menu nebo novinky někde v pravém sloupci. <strong>Přidáme funkci</strong> na detekci Ajax requestu, abychom to nemuseli podmiňovat GET proměnnou. <em>(Kterou sice stále využijeme, ale k jinému účelu.)</em> Dále loadovací kolečko: můžeme přidat, nemusíme. Tedy úprava <strong>stylů</strong>. No a na závěr samozřejmě celá <strong>JavaScriptová obsluha</strong>. </p>
<p>Úprava kontrolerů je přímo úměrná složitosti systému, ale tož nemusíme to osekat úplně všechno. Někdy je lepší provést pár operací navíc, než abych podmiňoval každou akci v každém layeru systému, aby pak vznikl nějaký <br /><a href="https://mike.treba.cz/img/2017/www/nth/wtf_per_minute.png" rel="lightbox" target="_blank">takovýto kód</a>...</p>
<h3>Detekce Ajax requestu</h3>
<pre><code class="php">function isAjax() {
	return isset($_SERVER['HTTP_X_REQUESTED_WITH']) &amp;&amp; (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
}</code></pre>
<h3>Příklad načtení obsahu</h3>
<p>Jak vyřešit architekturu systému a routování Ajaxových a běžných requestů, o tom dnešní článek také není. Buď vyřešeno máte, nebo se s tím nebudete trápit. Právě takové řešení uvedu v následujícím příkladu. Jednoduchou podmínkou oddělíme volání funkcí respektive metod, které mají být vykonané. Třeba nějak takhle. Pokud bychom tuto úpravu neprovedli, samotný Ajax pak ztratí tak trochu smysl. </p>
<pre><code class="php">function loadStuff(){
	
	$ajax = Server::isAjax();
	
	loadArticles();
	loadTagsForArticles();
	
	createPaging();
	getPageTitle();
	
	if(empty($ajax)){
		loadCategoryMenu();
		loadArchiveMenu();
		loadTagCloud();
		
		// ...
	}

	include_once('template.phtml');

}</code></pre>
<h2>Šablona</h2>
<p>V šabloně potřebujeme vyřešit reálné zobrazení. Určitě je jednodušší dostat celý kód a někam ho fláknout, než parsovat bůhvíjaké pole a někam ho pochybně generovat. Pořád se bavíme o webu náročnosti toho mého, nikoli o komplexní JavaScriptové aplikaci. Takže z šablony vyjmeme části, které se měnit nebudou. Včetně containeru, kam se vloží výsledek requestu. </p>
<pre><code class="php">&lt;?php
	$ajax = isAjax();
?&gt;
&lt;?php if(empty($ajax)){ ?&gt;
	
	&lt;?php include_once('_header.phtml'); ?&gt;
	
	&lt;div class="article-list"&gt;
		&lt;div class="js-ajax-main-container"&gt;

&lt;?php } ?&gt;
		
		&lt;?php // foreach co vypise clanky ?&gt;
		
		&lt;?php // strankovani ?&gt;
	
&lt;?php if(empty($ajax)){ ?&gt;	
		
		&lt;/div&gt;
		&lt;div class="ajax-loader js-ajax-loader hidden"&gt;&lt;div class="circle"&gt;&lt;/div&gt;&lt;/div&gt;
	&lt;/div&gt;

	&lt;?php include_once('_footer.phtml'); ?&gt;
	
&lt;?php } ?&gt;</code></pre>
<h3>Styly</h3>
<p>Než se podíváme na nejdůležitější část kódu, JavaScript, sfoukneme ještě styly. Přidáme si loadovací kolečko tak, aby bylo vždy vycentrované ve viditelné oblasti a zároveň překrývalo celý container. Samozřejmě je potřeba, aby náš "<em>js-ajax-main-container</em>" byl obalen ještě jediným divem s relativní pozicí, aby se absolutní chytila správně. Pozici kolečka pak zařídí výška relativně k viewportu a <strong>position: sticky.</strong>  <em>(Fixní alternativa je fallback pro IE11.)</em> </p>
<pre><code class="css">.hidden {display:none !important;}

.article-list {position:relative;}

.ajax-loader {
	position:absolute;
	top:0;
	left:0;
	width:100%;
	height:100%;
	z-index:20000;
}

.ajax-loader .circle {
	position:fixed;
	position:sticky;
	top:0;
	left:0;
	width:100%;
	height:100%;
	max-height:100vh;
	background:rgba(255,255,255,0.75) url(loading.gif) no-repeat 50% 50%/150px auto;
}</code></pre>
<h2>JavaScriptová obsluha</h2>
<p>A to nejdůležitější na závěr. Kontroler máme upravený, načítá jen nutná data. Šablona zobrazí přesně to, co potřebujeme. Takže teď se jenom napojíme na stránkování a namísto přechodu na cílovou URL provedeme request. Ještě připomenu, že stránkování je také potřeba přepsat po requestu, protože pokud ho například vypisujeme nějak takto: </p>
<pre style="text-align: center;"> 1 ... 7 | <strong>8</strong> | 9 ... 12</pre>
<p>samotné přehození<strong> active class</strong> nestačí. A opět je jednodušší vepsat celý HTML kód, než tuhle hrůzu generovat přes JS. Když už ji umíme vypsat přes PHP. Což také znamená, že po requestu musíme znovu namapovat akce na odkazy. </p>
<pre><code class="js">var hookActions = function(){
	$('.paging').find('a').on('click touch', function(){
		var url = $(this).attr('href');
		contentRequest(url, false);
		return false;
	});
	
	// plus vse ostatni, co se nejak napojuje na elementy ve vypisu clanku
};

hookActions();</code></pre>
<p>Samotná funkce <strong>contentRequest </strong>je mega easy. Pošle request, dostane html výstup, přepíše innerHTML a konec. Ale abychom si to udělali víc cool a sexy, provedeme i změnu URL bez jejího znovunačtení. K tomu slouží metoda <strong class="color-blue">history.pushState</strong>. Takže pokud kliknu např. na stránku 2, stisknu F5, už na ní zůstanu. A nemusím to ohýbat přes kotvy a podmíněné volání funkce. Server prostě vrátí normální output. </p>
<pre><code class="js">var loader = $('.js-ajax-loader');
var target = $('.js-ajax-main-container');
var currentUrl = window.location.href.split('#')[0];

var contentRequest = function(url, historyMove){
	loader.removeClass('hidden');
	
	var requestUrl = url &plus; (url.indexOf('?')&plus;1 ? '&amp;' : '?') &plus; 'ajax=1';
	
	$.ajax({
		url: requestUrl
		success: function(data){
			target.html(data);
			
			if(!historyMove){
				$('html,body').stop(true,true).animate({ scrollTop: 0 }, 0);
				history.pushState(null, null, url);
			}
			
			currentUrl = url;
			
			hookActions();
			loader.addClass('hidden');
		},
		error: function(){
			window.location.href = url;
		}
	});
};</code></pre>
<p>Jenže když už jednou šáhnu na <strong>history.pushState</strong>, měl bych vyřešit i nativní funkce prohlížeče <strong>zpět</strong> a <strong>vpřed</strong>. Pokud uživatel přijde například z Googlu na druhou, třetí stránku výpisu, párkrát si dole klikne na paging, tlačítko zpět by ho vrátilo zase na Google. Protože reálně se po stránce nepohyboval. Ale to lze vyřešit přidáním jediné události: </p>
<pre><code class="js">$(window).bind('popstate', function(e){
	var nextUrl = window.location.href.split('#')[0];
	
	if(nextUrl != currentUrl){
		contentRequest(window.location.href, true, true);	
	}
	
	currentUrl = nextUrl;
});</code></pre>
<p>Tady jsem měl trochu problém s odpálením popstate při změně <strong>window.location.hash</strong>. Přes hash totiž zaměřuji jednotlivé komentáře, a on se na to <strong>popstate</strong> také chytá. Proto parsování url a jedna malá podmínka: otestuji, jestli se změnila celá adresa nebo jenom kotva. </p>
<p>V tuto chvíli je vám také určitě jasné, k čemu slouží druhý parametr u funkce <strong>contentRequest</strong>: jakmile se hýbu v historii, nebudu znovu vyvolávat její změnu, nebo bych se z toho zacyklil. </p>
<p>A co se vlastně stane při vypnutém JavaScriptu? No přece to samé, co před nasazením Ajaxu. Stránka se načte přes normální request. Na závěr ještě přiložím link na jednotlivé části kódu v samostatných souborech, pokud byste měli zájem si je uložit. </p>
<h2>Lepší řešení</h2>
<p>JSON, samozřejmě. Pořád budu vracet celý HTML kód, ale díky poli dostanu možnost měnit třeba titulek. Nebo si do patičky zapsat čas trvání reqeustu. Pro účely vývoje. Ale to už bych nemohl článek oštítkovat jako "Základy", navíc by šlo o příliš individuální úpravy, které těžko zobecním jedním tutoriálem.  </p>
<p>Také bychom mohli přidat rozdílné chování pro telefon: stránkování se nahradí jenom za odkaz "<em>Následující</em>" a funkce obsah přidá, nepřepíše. Ale to už by pro změnu bylo na nový článek. A protože druhý díl už mám nachystaný a chci v něm ukázat funkční miniaplikaci, o mobilním stránkování třeba zase jindy.  </p>
<p class="download-links"><a href="https://mike.treba.cz/doc/2020/ajaxarticles/index.php?f=func" target="_blank">func.php</a><br /><a href="https://mike.treba.cz/doc/2020/ajaxarticles/index.php?f=load" target="_blank">loadstuff.php</a><br /><a href="https://mike.treba.cz/doc/2020/ajaxarticles/index.php?f=temp" target="_blank">template.php</a><br /><a href="https://mike.treba.cz/doc/2020/ajaxarticles/style.css" target="_blank">style.css</a><br /><a href="https://mike.treba.cz/doc/2020/ajaxarticles/main.js" target="_blank">main.js</a></p>
<p class="download-links"><a href="https://mike.treba.cz/doc/2020/ajaxarticles/ajaxarticles.zip" target="_blank">ZIP archív ke stažení</a></p>]]></content:encoded>
			<image>
    				<url>https://mike.treba.cz/img/2023/renewed/keybord.jpg</url>
			</image>
		</item>
		
		
		<item>
			<title>CSS pseudo-třídy: nth-child, nth-of-type, nth-last-of-type</title>
			<link>https://mike.treba.cz/css-pseudo-tridy-nth-child-nth-of-type-nth-last-of-type/</link>
			<pubDate>Thu, 23 Mar 2017 20:05:27 +1100</pubDate> 
			<comments>https://mike.treba.cz/css-pseudo-tridy-nth-child-nth-of-type-nth-last-of-type/#comments</comments>
			<dc:creator></dc:creator>
			<description><![CDATA[<p>Článek z oboru slibuji už dlouho. A čím lepším pokračovat, než pořádným seznamem tipů a triků, jak snáz stylovat web. Dnes se podíváme některé pseudo-třídy kaskádových stylů, které vám usnadní stylování dlouhých seznamů. Ale i krátkých. Také se pokusím vysvětlit, proč tyto selektory nefungují vždy tak, jak bychom si představovali.</p>]]></description>   
			<guid isPermaLink="false">https://mike.treba.cz/css-pseudo-tridy-nth-child-nth-of-type-nth-last-of-type/</guid>
			<content:encoded><![CDATA[<p>Článek z oboru slibuji už dlouho. A čím lepším pokračovat, než pořádným seznamem tipů a triků, jak snáz stylovat web. Dnes se podíváme některé pseudo-třídy kaskádových stylů, které vám usnadní stylování dlouhých seznamů. Ale i krátkých. Také se pokusím vysvětlit, proč tyto selektory nefungují vždy tak, jak bychom si představovali.</p> <h2>HTML kód</h2>
<p>Mějme následující HTML kód. Ten může reprezentovat například výpis produktů na e-shopu, výpis novinek nebo čehokoli jiného. Container obsahuje prvky .item zakončené vyčištěním floatů.</p>
<pre><code class="html">&lt;div class="itemlist"&gt;
	&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;
	&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;
	&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;
	&lt;div class="cleaner"&gt;&lt;/div&gt;
&lt;/div&gt;</code></pre>
<h2>Nth-child: základ</h2>
<p>Pro ty z nás, kteří si v životě nezapamatují, jestli <em>odd </em>nebo <em>even </em>je <em>lichá </em>nebo <em>sudá</em>, existuje velice jednoduchý vzorec. Každý druhý prvek je samozřejmě sudý, při odečtení jedničky od sudého čísla vyjde číslo liché.</p>
<pre><code class="css">.itemlist .item:nth-child(2n) {background:red;}  
.itemlist .item:nth-child(2n-1) {background:blue;}</code></pre>
<p><img src="http://www.mike.treba.cz/img/2017/www/nth/nth-2n.jpg" alt="" /></p>
<h3>Rozsah: od začátku po N-tý</h3>
<p>Často potřebujeme pár prvních elementů odlišit od těch ostatních. Takto zvýrazníme první 3.</p>
<pre><code class="css">.itemlist .item:nth-child(-n&plus;3) {background:blue;}</code></pre>
<p><img src="img/2017/www/nth/nth-range-2.jpg" alt="" /></p>
<h3>Rozsah: od N-tého dál</h3>
<p>Pokud potřebujeme opak výše uvedeného, učiníme tak následovně.</p>
<pre><code class="css">.itemlist .item:nth-child(n&plus;4) {background:blue;}</code></pre>
<p><img src="img/2017/www/nth/nth-range-1.jpg" alt="" /></p>
<h3>Rozsah: průnik definic</h3>
<pre>.itemlist .item:nth-child(-n&plus;6):nth-child(n&plus;4) {background:blue;}</pre>
<p><img src="img/2017/www/nth/nth-range-double.jpg" alt="" /></p>
<h2>Nth-child: kdy to nefunguje</h2>
<p>Při použití n-tého potomka je důležité myslet na jednu věc: pseudo-selektor se <strong>nevztahuje </strong>k CSS třídě, u které je napsán. Takže pokud někam mezi divy vložíme například nějaké &lt;br&gt;, celý princip pořadí prvků se rozbije.</p>
<p><strong>Následující zápisy jsou ekvivalentní:</strong></p>
<pre><code class="css"><strong>.itemlist .item:nth-child(2n) {background:blue;}  
.itemlist :nth-child(2n) {background:blue;}</strong></code></pre>
<p>Proč se tedy mnohem častěji setkáme s podobou zápisu na prvním řádku než na druhém? Odpověď je jednoduchá: přece aby bylo jasné, co tím autor myslel. K čemu přesně je definice myšlena. Druhý řádek proto považuji za monstrózní prasárnu.</p>
<h2>Nth-of-type</h2>
<p>Nth-of-type částečně supluje chování, kterého většinou chceme u podobných výpisů dosáhnout. Na rozdíl od nth-child, která referuje na N-tý prvek DOMu nezávisle na tom, o jaký prvek se jedná, nth-of-type se vztahuje na <strong>tagName</strong>. Takže když si rozšíříme první příklad o nějaké další prázdné prvky, fungovat to bude.</p>
<pre><code class="html">&lt;div class="itemlist"&gt;
	&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;span&gt;&lt;/span&gt;
	&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;span&gt;&lt;/span&gt;
	&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;span&gt;&lt;/span&gt;
	&lt;span class="cleaner"&gt;&lt;/span&gt;
&lt;/div&gt;</code></pre>
<p>Pokud selektor napojíme na .<strong>item</strong>, zacílí právě divy. Ostatní tagy stejného rodiče ignoruje. Samozřejmě v takovém případě nechceme čistící prvek jako div, nýbrž jako span.</p>
<pre><code class="css">.itemlist .item:nth-of-type(2n) {background:blue;}</code></pre>
<p><img src="https://mike.treba.cz/img/2017/www/nth/nth-of-type.jpg" alt="Nth Of Type" /></p>
<h2>Nth-last-of-type</h2>
<p>Má stejný princip jako u předchozího selektoru, akorát prvky bereme odzadu. Tady je opravdu nutné dbát na jména tagů, protože zobrazení se pak může různě přeskakovat či neaplikovat vůbec. Jako příklad uvedu HTML kód se spoustou parazitních tagů, kterým zobrazení definovat nechceme.</p>
<pre><code class="html">&lt;div class="itemlist itemlist_6"&gt;
	&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;br&gt;
	&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;br&gt;
	&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;br&gt;	
	&lt;span class="cleaner"&gt;&lt;/span&gt;
&lt;/div&gt;</code></pre>
<pre><code class="css">.itemlist .item:nth-of-type(3n&plus;1) {background:blue;}
.itemlist .item:nth-last-of-type(1) {background:red;}
.itemlist .item:nth-last-of-type(2n) {background:green;}</code></pre>
<p>První, čtvrtý a sedmý prvek bude modrý. Poslední bude červený. A každý sudý odzadu zase zelený, což samozřejmě přebije modré pozadí prvku čtvrtého :-)</p>
<p><img src="https://mike.treba.cz/img/2017/www/nth/nth-multi.jpg" alt="Nth Multi" /></p>
<h2>N-tý prvek v závislosti na rozlišení</h2>
<p>Na závěr si dáme trochu responzivity. Produktové výpisy s různým počtem prvků podle rozlišení dnes najdeme na každém druhém webu. Možností nastylování je spousta a já bych na závěr představil jednu z nich, samozřejmě za využití nth-of-type. Abychom nemuseli vše 10x redefinovat, omezíme definice rozlišením.</p>
<p>Nejdřív budou na stránce 4 prvky vedle sebe, pak 3 a na závěr 2. A jako malý bonus obarvíme každý druhý řádek jinou barvou. (<em>Tedy skupinu záznamů na daném řádku.</em>) HTML kód bude opět stejný, jako v první ukázce, akorát tam toho bude trochu víc.</p>
<pre><code class="html">&lt;div class="itemlist"&gt;
	&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;
	&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;
	&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;&lt;div class="item"&gt;&lt;/div&gt;
	&lt;span class="cleaner"&gt;&lt;/span&gt;
&lt;/div&gt;</code></pre>
<p>Každý 4. element bude mít zresetovaný pravý margin, každý 4&plus;1. zresetuje float. Každý 5., 6., 7. a 8. prvek bude zvýrazněný. Skrz omezení na plus a mínus bohužel komplexnější funkci nenapíšeme, a tak je potřeba to takhle vylistovat za sebou.</p>
<pre><code class="css">.itemlist {max-width:900px;margin:0 auto;}
.itemlist .cleaner {clear:both;}
.itemlist .item {width:24.25%;margin:0 1% 10px 0;float:left;height:50px;background:grey;}

@media all and (min-width: 1201px){
	.itemlist .item:nth-of-type(4n) {margin-right:0%;}
	.itemlist .item:nth-of-type(4n&plus;1) {clear:both;}
	
	.itemlist .item:nth-of-type(8n),
	.itemlist .item:nth-of-type(8n-1),
	.itemlist .item:nth-of-type(8n-2),
	.itemlist .item:nth-of-type(8n-3) {
		background:blue;
	}
}

@media all and (min-width: 601px) and (max-width: 1200px){
	.itemlist .item {width:32.666%;}
	.itemlist .item:nth-of-type(3n) {margin-right:0%;}
	.itemlist .item:nth-of-type(3n&plus;1) {clear:both;}
	
	.itemlist .item:nth-of-type(6n),
	.itemlist .item:nth-of-type(6n-1),
	.itemlist .item:nth-of-type(6n-2) {
		background:blue;
	}
}

@media all and (max-width: 600px){
	.itemlist .item {width:49.5%;}
	.itemlist .item:nth-of-type(2n) {margin-right:0%;}
	.itemlist .item:nth-of-type(2n&plus;1) {clear:both;}
	
	.itemlist .item:nth-of-type(4n),
	.itemlist .item:nth-of-type(4n-1) {
		background:blue;
	}
}</code></pre>
<p><img src="https://mike.treba.cz/img/2017/www/nth/nth_list.jpg" alt="Nth List" /></p>
<p>Pokud jsme nuceni jednotlivé prvky cílit nějakým šíleným kaskádovým zápisem, lze stejnou definici zapsat i negací bez nutnosti opakovat 4x pod sebou ".itemlist .item". Ale to už trochu zavání výstižným "WTF" (<em>kde počet WTF za minutu je neoficiální ukazatel kvality kódu</em>).</p>
<p><em>Odkazy na ukázky najdete na konci článku.</em></p>
<pre><code class="css">html.project-237 body.default-article.has-productlist <br /> .container.dark-bg .central-area .itemlist <br /> .item:not(:nth-of-type(8n&plus;1)):not(:nth-of-type(8n&plus;2)):not(:nth-of-type(8n&plus;3)):not(:nth-of-type(8n&plus;4)){
	background:blue;
}</code></pre>
<p><img style="display: block; margin-left: auto; margin-right: auto;" src="https://mike.treba.cz/img/2017/www/nth/wtf_per_minute.png" alt="Wtf Per Minute" /></p>
<h2>Ukázky uvedených řešení</h2>
<p>Vše, co jsme v dnešním článku vyzkoušeli, si můžete prohlédnout na následujících odkazech. Druhý příklad pak reaguje na resize okna prohlížeče.</p>
<p class="download-links"><a href="doc/2017/nth/nth.html" target="_blank">:nth-child, :nth-of-type 1. - 6. příklad</a><br /><a href="doc/2017/nth/nth_2.html" target="_blank">:nth-of-type responzivní ukázka</a></p>]]></content:encoded>
			<image>
    				<url>https://mike.treba.cz/img/2017/www/pen-writing-css-code-feature_1290x688_ms.jpg</url>
			</image>
		</item>
		
		
		<item>
			<title>CSS transition a vytvoření jednoduchého JS carouselu</title>
			<link>https://mike.treba.cz/css-transition-javascript-carousel/</link>
			<pubDate>Wed, 25 Nov 2015 15:15:42 +1100</pubDate> 
			<comments>https://mike.treba.cz/css-transition-javascript-carousel/#comments</comments>
			<dc:creator></dc:creator>
			<description><![CDATA[<p>V minulém článku jsem sliboval, že bude další, ve kterém najdete návod na jednoduchý carousel vytvořený za pomoci JavaScriptu a CSS transition. Tak tady je. Pokud si na stránce zascrollujete trochu níž a vyhledáte v pravém sloupci "Mikroblog" a "Nejnovější články", tak přesně to bude výsledek. </p>]]></description>   
			<guid isPermaLink="false">https://mike.treba.cz/css-transition-javascript-carousel/</guid>
			<content:encoded><![CDATA[<p>V minulém článku jsem sliboval, že bude další, ve kterém najdete návod na jednoduchý carousel vytvořený za pomoci JavaScriptu a CSS transition. Tak tady je. Pokud si na stránce zascrollujete trochu níž a vyhledáte v pravém sloupci "Mikroblog" a "Nejnovější články", tak přesně to bude výsledek. </p> <p>Pokud se vám metoda fade in/fade out nelíbí, v druhé části článku se můžete podívat, jak slider upravit na posuv ze strany na stranu. Jak potom dostat obě metody do jediné funkce, to si můžete zkusit sami; funkce to budou opravdu jednoduché a jejich úprava nebude nijak složitá. JavaScript zde bude ještě jednodušší než styly; takže asi taková bude náročnost. Ale i tak si všechno krok po kroku projedeme. Se vším nám pomůže<strong> knihovna jQuery</strong>.</p>
<h2>První slider</h2>
<h3>1. HTML</h3>
<p>Začneme jak jinak, než od HTML kódu. Jak vidíte, opravdu ho není hodně. První důležitá věc je resizovací obrázek: díky němu bude celý objekt pěkně responzivní, díky němu můžeme použít všude absolutní pozice. Je to jenom průhledné png v rozměrech 300x200 pixelů, takže celé to bude vždy v poměru 3:2. Šipky jsou pak samozřejmě ovládací prvky. Prvnímu elementu rovnou nastavíme třídu active, která bude mít důležitou úlohu nejen ve stylech, ale také v samotné obsluze. Toť vše. Jednotlivých prvků "<em>.item</em>" tam může být, kolik jen budeme potřebovat.</p>
<pre><code class="html">&lt;div class="slider"&gt;
	&lt;img src="<strong>slider_resizer.png</strong>" class="resizer" alt="" /&gt;
	&lt;a class="shipka shipka-left" href="javascript:;"&gt;&lt;/a&gt;
	&lt;a class="shipka shipka-right" href="javascript:;"&gt;&lt;/a&gt;
	&lt;div class="inner"&gt;
		&lt;div class="item <strong>active</strong>" style="background-image:url(obrazek_1.jpg);"&gt;
			&lt;h3&gt;&lt;a href="" title=""&gt;&lt;span&gt;Nadpis 1&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;						
		&lt;/div&gt;
		&lt;div class="item" style="background-image:url(obrazek_2.jpg);"&gt;
			&lt;h3&gt;&lt;a href="" title=""&gt;&lt;span&gt;Nadpis 2&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;						
		&lt;/div&gt;
		&lt;div class="item" style="background-image:url(obrazek_3.jpg);"&gt;
			&lt;h3&gt;&lt;a href="" title=""&gt;&lt;span&gt;Nadpis 3&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;						
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/div&gt;</code></pre>
<h3>2. CSS</h3>
<p>Styly zde samozřejmě nebudu uvádět úplně všechny, ale jenom ty nejdůležitější, sloužící ke správnému zobrazení a funkcionalitě. A přijde řeč i na transition. Právě tato vlastnost nám bude celou mašinu pohánět, navíc se postará i o pěkný hover efekt.</p>
<pre><code class="html">.slider {position:relative;}
.slider .resizer {display:block;margin:0;width:100%;}

.slider .inner {position:absolute;width:100%;height:100%;top:0;left:0;overflow:hidden;}
.slider .inner .item {
	position:absolute;top:0;left:0;padding:0;margin:0;width:100%;height:100%;
	z-index:0;opacity:0;transition:300ms; -webkit-transition:300ms;
	background-position:50% 66.6%;background-size:100% auto;
}
.slider .inner .item.active {z-index:10;opacity:1;}
.slider .inner .item:hover {background-size:105% auto;}</code></pre>
<p>Zde už by od pohledu mělo být jasné, jak to celé dopadne. Hlavnímu divu dáme relativní pozici, čímž můžeme vše uvnitř roztáhnout na 100% šířky i výšky, takže každý jeden slide bude přizpůsobený našemu resizovacímu obrázku. Když se podíváte na definice prvku "<em>.item:hover</em>", uvidíte, že background-size, tedy velikost pozadí se také bude měnit. A právě díky <strong>transition </strong>to bude plynule. Přidáním třídy "<em>.active</em>" se pak změní průhlednost z 0 na 1 a z-index, což bude změna viditelného slidu. Další vlastnosti zde popisovat už nebudu, jedná se o totiž pouze o doplňkové designové prvky, o kterých tento článek není.</p>
<h3>3. JavaScript</h3>
<p>Ani JavaScriptu nebude mnoho. K čemu zbytečně stahovat megové knihovny na carousely, které si stejně nedokážeme přizpůsobit, protože k tomu chybí dokumentace? K čemu používat monstrózní řešení, když tohle je otázkou 15 minut?</p>
<p><strong>Máme:</strong></p>
<ul>
<li>2 parametry</li>
<li>1 kontrolu</li>
<li>2 funkce na posun doleva a doprava</li>
<li>2 napojení těchto funkcí</li>
<li>1 automatické spuštění</li>
</ul>
<pre><code class="html">function MiniSlider(slider_element,auto_time){
	var autoInt = null;
	
	if(!slider_element.find('.inner').size()){
		return false;  
	}
	
	var parent = slider_element.find('.inner');
	parent.find('.item:first-child').addClass('active');
			
	var moveItRight=function(){
		var nxt = parent.find('.item.active').next();
		if(!nxt.size()){
			nxt = parent.find('.item:first-child');
		}
		parent.find('.item.active').removeClass('active');
		nxt.addClass('active');
	};
	
	var moveItLeft=function(){
		var prv = parent.find('.item.active').prev();
		if(!prv.size()){
			prv = parent.find('.item:last-child');
		}
		parent.find('.item.active').removeClass('active');
		prv.addClass('active');
	};
	
	slider_element.find('.shipka.shipka-right').click(function(){
		clearInterval(autoInt);
		moveItRight();
		return false;
	});
	
	slider_element.find('.shipka.shipka-left').click(function(){
		clearInterval(autoInt);
		moveItLeft();
		return false;
	});
	
	autoInt = setInterval(function(){
		moveItRight();
	},auto_time);
}
	
new MiniSlider($('.slider'), 5000);
</code></pre>
<h4>Jak to tedy celé funguje?</h4>
<p>Úplně snadno. Funkce najde prvek s třídou active a hledá prvek následující (<em>respektive předcházející</em>). Pokud ho nenajde, vezme první (respektive poslední) element. Jednu třídu active odstraní, druhou přidá. Tím se změní průhlednost a transition nám z toho udělá plynulý efekt. Toť vše. Zde se můžete podívat na výsledek:</p>
<blockquote>
<p>Ukázka: <a href="https://mike.treba.cz/doc/2015/slider/slider_sample.html" target="_blank">slider_sample.html</a><br />ZIP ke stažení: <a href="extras/download/?file=doc/2015/slider/slider.zip" target="_blank">slider.zip</a></p>
</blockquote>
<h2>Druhý Slider</h2>
<p>V druhé ukázce si slider trochu upravíme tak, aby objekty posouvaly ze strany na stranu. Na to mám sice hotové už poměrně komplexní řešení, to zde ale prezentovat nemohu. Navíc je to dost šílený výtvor a já raději píšu o věcech jednoduchých.</p>
<p><em>Můžeme nastavit vnitřnímu divu šířku podle počtu divů a posouvat jenom left či right vždy o jednu obrazovku. Na začátek a konec bychom pak museli zkopírovat poslední a první slide a navíc počítat, kdy je slider na konci a přehodit ho zase na začátek. Toto řešení je dobré v tom, že budeme mít slider nachystaný na větší počet různých chování, ale tím to bude pak složitější. </em></p>
<p>Jenže my to uděláme jinak, jednodušeji. Vždy jenom zaměříme další prvek co je na řadě, tento a aktuální položíme vedle sebe a pak oba posuneme. Po ukázce kódu to bude asi trochu jasnější. Toto řešení ale přinese jistá drobná úskalí, ale to si popíšeme až pod ukázkou JS kódu.</p>
<h3>1. CSS</h3>
<p>HTML kód zůstane, podíváme se tedy, co se změnilo ve stylech. Tam bude jiná definice prvku "<em>.item</em>". Transition omezíme pouze na pozadí, zbytek už bude probíhat na úrovni JavaScriptu. Prvkům nastavíme výchozí pozici o jednu obrazovku doleva, prvnímu pak left:0. Tím jsme ve stylech hotovi.</p>
<pre><code class="html">.slider .inner .item {
	position:absolute;top:0;left:-100%;padding:0;margin:0;width:100%;height:100%;
	z-index:0;transition:background 300ms; -webkit-transition:background 300ms;
	background-position:50% 66.6%;background-size:100% auto;
}
.slider .inner .item.active {}
.slider .inner .item:first-child {left:0;}
.slider .inner .item:hover {background-size:105% auto;}</code></pre>
<h3>2. JavaScript</h3>
<p>Třídě přidáme další parametr, kterým bude délka animace. Už totiž není nastavená ve stylech. Dále už jenom rozšíříme funkce "<em>moveLeft</em>" a "<em>moveRight</em>". Zde už transition nebude ovládat posuv, zde využijeme klasické metody jQuery.animate(). Zjednodušeně to bude fungovat asi takto: před spuštěním posuvu seřadíme aktuální a následující vedle sebe a potom oba posuneme. Od směru se samozřejmě odvíjí souřadnice "<em>left</em>". Takto to zní jednoduše (<em>a ono také je</em>), ale jsou tu dvě věci, na které je potřeba myslet. Dřív, než budu cokoli přehazovat a posouvat, musím vše poctivě zresetovat. Nastavím správné pozice, z-indexy, stopnu animace. Tím ošetřím potenciální zběsilé klikání na šipku.</p>
<p>Další záludnost je pak samotný průběh dvou animací ve stejný okamžik: často se totiž stane, že se jedna z nich o pár milisekund zpozdí - výsledkem je pak takové bílé probliknutí mezi obrázky. Na řešení půjdeme od lesa: stačí prostě odjíždějící slide opozdit. Člověk to ani nepostřehne a my se zbavíme se nežádoucího efektu.</p>
<pre><code class="html">function MiniSlider(slider_element,auto_time,anim_time){
	
	var moveItRight=function(){
		var act = parent.find('.item.active');
		var nxt = parent.find('.item.active').next();
		if(!nxt.size()){
			nxt = parent.find('.item:first-child');
		}
		
		parent.find('.item').css({zIndex:0,left:'100%'}).stop(true,true);
		
		act.stop(true,true).css({zIndex:10,left:0});
		nxt.stop(true,true).css({zIndex:10});
		
		act.animate({left:'-100%'},anim_time&plus;10).removeClass('active');
		nxt.animate({left:0},anim_time).addClass('active');
	};

	var moveItLeft=function(){
		var act = parent.find('.item.active');
		var prv = parent.find('.item.active').prev();
		if(!prv.size()){
			prv = parent.find('.item:last-child');
		}
		
		parent.find('.item').css({zIndex:0,left:'-100%'}).stop(true,true);
		
		act.stop(true,true).css({zIndex:10,left:0});
		prv.stop(true,true).css({zIndex:10});
		
		act.animate({left:'100%'},anim_time&plus;10).removeClass('active');
		prv.animate({left:0},anim_time).addClass('active');
	};

}
	
new MiniSlider($('.slider'), 5000, 500);</code></pre>
<p>A máme hotovo. Celá funkce je na pár desítek řádků, snadno pochopitelná, snadno rozšířitelná. Netřeba stahovat gigantické knihovny. Na závěr bychom ještě mohli obě třídy sloučit tak, aby další parametr určoval, jaký typ efektu bude uplatněn. To už ale nechám na vás, ať se také něco naučíte sami :-)</p>
<blockquote>
<p>Ukázka: <a href="https://mike.treba.cz/doc/2015/slider_mover/slider_sample.html" target="_blank">slider_sample.html</a><br />ZIP ke stažení: <a href="extras/download/?file=doc/2015/slider_mover/slider_mover.zip" target="_blank">slider_mover.zip</a></p>
</blockquote>]]></content:encoded>
			<image>
    				<url>https://mike.treba.cz/img/2023/renewed/code-funny.jpg</url>
			</image>
		</item>
		
		
		<item>
			<title>CSS transition: animace přes změnu třídy - základy</title>
			<link>https://mike.treba.cz/css-transition-animace/</link>
			<pubDate>Mon, 9 Nov 2015 20:22:48 +1100</pubDate> 
			<comments>https://mike.treba.cz/css-transition-animace/#comments</comments>
			<dc:creator></dc:creator>
			<description><![CDATA[<p><strong>CSS</strong> vlastnost <strong>transition </strong>je taková kouzelná formule, kterou můžeme využít nesčetnými způsoby. Zjednodušeně řečeno je to animace. Provede to, co bychom za jiných okolností poslali do <strong>jQuery </strong>metodě <strong>animate</strong>. Použití je velice jednoduché, vše si lze pohodlně testovat ve Firebugu. </p>]]></description>   
			<guid isPermaLink="false">https://mike.treba.cz/css-transition-animace/</guid>
			<content:encoded><![CDATA[<p><strong>CSS</strong> vlastnost <strong>transition </strong>je taková kouzelná formule, kterou můžeme využít nesčetnými způsoby. Zjednodušeně řečeno je to animace. Provede to, co bychom za jiných okolností poslali do <strong>jQuery </strong>metodě <strong>animate</strong>. Použití je velice jednoduché, vše si lze pohodlně testovat ve Firebugu. </p> <p>Dnešní článek bude takový úvod, abyste se s vlastností mohli seznámit, pokud ji ještě neznáte. V druhém článku bych pak ukázal využití v praxi: napíšeme si jednoduchý slider (<em>carousel</em>), který rozhýbe pouze změna třídy. Transition má 4 různé vlastnosti, které lze zapsat pod její definici. Povinný je ale pouze čas.</p>
<pre><code class="css">transition: animovaná vlastnost, délka, efekt, zpoždění</code></pre>
<p>Tento zápis je ale zbytečně krkolomný a špatně zapamatovatelný. Navíc animovanou vlastnost většinou ani uvádět nechci, protože pak by se mi animovala pouze jedna vlastnost - nikoli všechny, které redefinuji.</p>
<p>Podívejme se na následující ukázku. Pouhou změnou třídy docílíme plynulé změny barvy, velikosti pozadí či šířky elementu. Jediný JavaScript na ukázkové stránce je změna třídy s timeoutem jedné vteřiny:</p>
<blockquote>
<p><a href="doc/2015/animtest/" target="_blank">Test animace</a></p>
</blockquote>
<pre><code class="css">.color-animate {background-color:red;color:white;transition:500ms; -webkit-transition:500ms;}
.color-animate:hover {background-color:green;color:black;}</code></pre>
<h2>Podpora</h2>
<p>Na tabulku podpory se můžete podívat na <a href="http://caniuse.com/#feat=css-transitions" target="_blank">této stránce</a>. Pokud ji náhodou nějaká verze prohlížeče podporovat nebude, trápit nás to nemusí... Efekt jen proběhne okamžitě. Definici s -webkit- prefixem využijeme pouze pro Safari. Chrome už je naštěstí rozumný prohlížeč a hackovat ho není třeba. Stejně tak žádné -moz- prefixy uvádět nemusíme.</p>
<h2>Kdy transition a kdy JavaScript</h2>
<p>Transition je vlastnost stylů, tedy je potřeba ji podle toho i používat. Všude tam, kde definuji nějaký vzhled: hovery tlačítek, boxíků, jednorázové změna vzhledu a tak dále, a tak dále. V žádném případě bych transition nepoužíval na složité operace, kde se mění několik vlastností dohromady včetně rozměrů a pozic dohromady. To už je uživatelský zásah do stránky, který by měl dle logiky věci obsloužit JavaScript. A také prohlížeč by vás neměl rád...</p>
<p>Už ten slider, který v pokračování článku představím je tak trochu na hraně, ale měním jenom jediný atribut. Navíc i pár řádků JS ušetřím.<strong>Takže ve zkratce? Dělejte s tím jednoduché věci. </strong>Například na tomto webu mám 100ms na hlavní navigaci (<em>změna pozadí</em>), když se podíváte doprava na výpis mikročlánků, tak hover šipeček i jejich samotné zobrazení také řeším animací. Takže tak.</p>]]></content:encoded>
			<image>
    				<url>https://mike.treba.cz/img/2023/renewed/coding-table.jpg</url>
			</image>
		</item>
		
		
		<item>
			<title>Jak na responzivní web: CSS Grid Layout, stylování Widgetů</title>
			<link>https://mike.treba.cz/jak-na-responzivni-web-css-grid-layout/</link>
			<pubDate>Tue, 13 Jan 2015 22:25:55 +1100</pubDate> 
			<comments>https://mike.treba.cz/jak-na-responzivni-web-css-grid-layout/#comments</comments>
			<dc:creator></dc:creator>
			<description><![CDATA[<p>Je čas zase na nějaký článek na téma, kterému byl tento blog původně věnován. V dnešním tutoriálu ukážu krátký návod, jak vytvořit takzvané Widgety závislé na aktuální šířce okna; naučíme něco o <strong>responzivním webu</strong>. </p>]]></description>   
			<guid isPermaLink="false">https://mike.treba.cz/jak-na-responzivni-web-css-grid-layout/</guid>
			<content:encoded><![CDATA[<p>Je čas zase na nějaký článek na téma, kterému byl tento blog původně věnován. V dnešním tutoriálu ukážu krátký návod, jak vytvořit takzvané Widgety závislé na aktuální šířce okna; naučíme něco o <strong>responzivním webu</strong>. </p> <p>Samotnému layoutu o dynamické šířce se věnovat nebudu; dnes budu předpokládat, že toto už umíte. Widgety v různé podobě jsou nyní vcelku populární záležitost, jenže jak se to má člověk naučit, když článků je pomálu.</p>
<p>Úvodní stránky s boxíky různých velikostí, které se přizpůsobují šířce prohlížeče či dokonce i zařízení jsou stále populárnější. Za tím účelem vznikla i spousta <strong>frameworků</strong>, které problematiku vyřeší za nás. Hotová řešení přináší kromě výhod i řadu nevýhod.</p>
<ul>
<li>Nemáme přehled, co se děje na pozadí.</li>
<li>Opravy možných chyb se mohou natáhnout do hodin práce.</li>
<li>Bývá těžké modifikovat výstup, pokud chcem zobrazení odlišné od autorova záměru.</li>
</ul>
<p>Sám jsem strávil mnoho času zběžným studiem a testováním různých existujících frameworků, které jsem našel, ale právě 3 zmíněné body mě stejně přiměly napsat si to sám. K čemu složité sofistikované řešení, když můžeme použít vlastní, jednoduché, kde máme 100% kontrolu nad každám řádkem kódu. Jedno takové řešení dnes představím.</p>
<h2>Ukázka</h2>
<p><img style="display: block; margin-left: auto; margin-right: auto;" src="https://mike.treba.cz/img/2015/boxes-preview.jpg" alt="Boxes Preview" /></p>
<p>Takto nějak mohou být rozvržené widgety na úvodní stránce prezentace.</p>
<ul>
<li>Mezera mezi boxy bude v pixelech a musí být snadno nastavitelná.</li>
<li>Každý box se při změně šířky okna přizpůsobí tak, aby byly zachovány poměry.</li>
</ul>
<p>Výše uvedené bohužel žádný mnou testovaný framework neuměl, a tak mi nezbylo nic jiného, než se pustit do kódování.</p>
<p><strong>Nyní se podívejte na následující odkaz</strong>: <a href="doc/2015/boxes/boxes_ukazka1.html" target="_blank">boxes_ukazka1.html</a></p>
<p>Na ukázce vidíme už připravenou mřížku, která se chová přesně tak, jak potřebujeme.</p>
<h2>Jak toho docílit?</h2>
<p>Využijeme jedné z chytrých vlastností obrázku, a to, že při změně jednoho rozměru se dopočítá druhý (<em>pokud není definován</em>). Takže ano, koukáme na čtvercové a obdélníkové obrázky, ale ne, nejsou to <em>jenom</em> obrázky. Každý z boxů má šířku 20% rodiče, tedy dynamickou. V něm je vložený jeden průhledný png obrázek, který se stará o resize. Div pro vlastní obsah se absolutně napozicovaný s šířkou i výškou 100%, takže vyplní celý prostor.</p>
<blockquote>
<p>Abychom ale mohli naspat height:100%; width:100%; padding:10px;, musíme využít CSS vlasnosti <strong>box-sizing: border-box;</strong>. Ta říká, že rámeček i padding nebudou přičteny k šířce, ale budou počítány tzv. dovnitř. </p>
</blockquote>
<h3>HTML</h3>
<pre><code class="html">&lt;div class="box size2x2"&gt;
	&lt;img class="resizer" src="box-2-2.png" alt="" /&gt;
	&lt;div class="inbox"&gt;
		&lt;div class="data"&gt;
		
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/div&gt;</code></pre>
<h3>CSS</h3>
<pre><code class="css">.box {float:left;position:relative;overflow:hidden;}
.box.size1x1 {width:20%;}
.box.size2x1,
.box.size2x2 {width:40%;}
.box .resizer {width:100%;height:auto;margin:0;display:block;}
.box .inbox {width:100%;height:100%;box-sizing:border-box;padding:10px;position:absolute;top:0;left:0;overflow:hidden;}
.box .inbox .data {position:relative;width:100%;height:100%;background:green;}</code></pre>
<p>První div určuje vnější obal boxu. Průhledný obrázek zajistí správné chování na resize. První vnořený div je container pro odsazení mezi boxy: padding 10 pixelů ze všech stran nám vytvoří 20px mřížku. A nakonec poslední vnořený div je samotný obsah - to, co vidíte zeleně vybarvené.</p>
<h2>Responzivita</h2>
<p>Responzivita nedefinuje pouze dynamickou šiřku sloupců, ale také změnu zobrazení na předem určených zlomových bodech. Takže při menším rozlišení zobrazíme pouze 4 boxy vedle sebe (<em>namísto pěti</em>) a pro rozlišení nejnižší třeba jenom 2.</p>
<p><strong>Prohlédněte si druhou ukázku a zkuste zužovat okno prohlížeče</strong>: <a href="doc/2015/boxes/boxes_ukazka2.html" target="_blank">boxes_ukazka2.html</a></p>
<p>K tomu využijeme CSS media query, které upraví vlastnosti pro všechna rozlišení nižší než definovaná hodnota.</p>
<pre><code class="html">@media all and (max-width: 840px){
	.box.size1x1 {width:25%;}
	.box.size2x1,
	.box.size2x2 {width:50%;}
}

@media all and (max-width: 640px){
	.box.size1x1 {width:50%;}
	.box.size2x1,
	.box.size2x2 {width:50%;}
	.box .inbox {padding:5px;}
}</code></pre>
<p>Při rozlišení 840 pixelů nebo menším bude malý box čtvrtina a velký box polovina obsahu. Při rozlišení 640 pixelů nebo měnším už budou vždy maximálně 2 vedle sebe, větší box bude roztažený na celou šířku. Zde také můžeme zmenšit rozestupy na 10 pixelů.</p>
<h2>Vlastní obsah boxů</h2>
<p><strong>Na závěr se podívejte na třetí ukázku</strong>: <a href="https://mike.treba.cz/doc/2015/boxes/boxes_ukazka3.html" target="_blank">boxes_ukazka3.html</a></p>
<p>Zelenou jsem vyměnil za trochu příjemnější barvu, přidal základní styly na formátování textu a hurá, už to začíná vypadat jako web.</p>
<p><img style="display: block; margin-left: auto; margin-right: auto;" src="https://mike.treba.cz/img/2015/boxes-preview-2.jpg" alt="Boxes Preview 2" /></p>
<h2>Zobrazení na mobilních zařízeních: meta name=viewport</h2>
<p>Abychom docílili správného zobrazení na mobilních telefonech a tabletech, je potřeba přidat do hlavičky ještě následující meta tag:</p>
<pre><code class="html">&lt;meta name="viewport" content="width=device-width, user-scalable=yes" /&gt;</code></pre>
<p>Co přesně dělá, jaké jsou způsoby jeho využití zde ale uvádět nebudu, protože to by bylo na další celý článek. Ve zkratce: díky němu to bude fungovat tak, jak má :-) Pokud si chcete o využítí meta tagu viewport přečíst něco více v češtině, mohu doporučit například <a href="http://jecas.cz/meta-viewport" target="_blank">tento článek</a> na ječas.cz.</p>]]></content:encoded>
			<image>
    				<url>https://mike.treba.cz/img/2023/renewed/coding-table.jpg</url>
			</image>
		</item>
		
		
		<item>
			<title>Tipy na moderní web: Font Awesome, šipky pomocí CSS</title>
			<link>https://mike.treba.cz/moderni-web-font-awesome-sipky-tvary-css/</link>
			<pubDate>Wed, 17 Dec 2014 17:22:12 +1100</pubDate> 
			<comments>https://mike.treba.cz/moderni-web-font-awesome-sipky-tvary-css/#comments</comments>
			<dc:creator></dc:creator>
			<description><![CDATA[<p>Webdesign je oblast, která se pořád vyvijí a pokud chce člověk držet krok, je potřeba stále studovat nové technologie a využívat vše, co nám nynější prohlížeče dovolí. V dnešním článku si ukážeme jednu kodérskou vychytávku, a to, jak vytvořit jednoduché šipky pouze pomocí css. V druhé části představím piktogramové písmo <strong>Font Awesome</strong> spolu se stručnou ukázkou použití.</p>]]></description>   
			<guid isPermaLink="false">https://mike.treba.cz/moderni-web-font-awesome-sipky-tvary-css/</guid>
			<content:encoded><![CDATA[<p>Webdesign je oblast, která se pořád vyvijí a pokud chce člověk držet krok, je potřeba stále studovat nové technologie a využívat vše, co nám nynější prohlížeče dovolí. V dnešním článku si ukážeme jednu kodérskou vychytávku, a to, jak vytvořit jednoduché šipky pouze pomocí css. V druhé části představím piktogramové písmo <strong>Font Awesome</strong> spolu se stručnou ukázkou použití.</p> <h2>Šipky pomocí kaskádových stylů</h2>
<p>Šipky různých barev a velikostí najdeme dnes téměř na každém webu. Zvyšují přehlednost a obecně se těší oblibě grafiků. Jako nejsnazší řešení ve smyslu "<em>hlavně ať už to mám hotové</em>" se nabízí jednoduše uložit šipku do obrázku a nastavit na background-image odkazu. Jenže takový postup se nám dříve nebo později vymstí. Pamatuji si projekt, kde bylo navrženo asi pět různých barevných modifikací šipky, každá ve dvou velikostech. Nebyl čas ani prostor na experimentování, a tak jsem si vše uložil do png. Web byl hotový a začlo ladění pro mobilní zařízení. A můj domeček z šipek se rozbil. Mít tehdy trochu více času, vyřešil bych zvýraznění odkazů jako nyní, pouze přes styly.</p>
<blockquote>
<p>Nejdříve se podíváme na ukázku: <a href="doc/2014/sipky.html" target="_blank">sipky.html</a></p>
</blockquote>
<p>Na první pohled se může zdát, že je tam toho kódu trochu hodně, jenže tady se díváme na řešení, které je nachystané pro copy&plus;paste na další projekt.</p>
<p>Při stylování využijeme pseudo-třídu <strong>*:before</strong> a <strong>*:after</strong>, díky které nebudeme muset zanořovat žádné další spany či podobný nepořádek; HTML kód bude čistý. Samotnou šipku pak vytvoříme rámečkem, a to kombinací <strong>border-color</strong> a <strong>border-width</strong>. Při správné definici barvy respektive šírky pro rámeček horní / pravý / spodní / levý pak vznikne trojúhelník.</p>
<h3>Jednoduchá šipka</h3>
<pre><code class="css">a.shipka-next {display:inline-block;color:#007bff;}
a.shipka-next:after {width:0;height:0;content:' ';display:inline-block;margin-left:5px;
	border-style:solid;
	border-width:5px 0 5px 5px;
	border-color:transparent transparent transparent #007bff;
}</code></pre>
<h3>Úplná šipka</h3>
<p>Pro celou šipku využijeme oba pseudo-elementy, z nichž jeden bude trojúhelník přes rámečky a druhý pouze vybarvený obdélník.</p>
<pre><code class="css">a.shipka-next-adv {display:inline-block;position:relative;color:#ff0022;margin-right:18px;}
a.shipka-next-adv:before {content:' ';position:absolute;top:50%;right:-12px;margin:-2px 0 0 0;height:4px;width:7px;background:#ff0022;}
a.shipka-next-adv:after {content:' ';position:absolute;top:50%;right:-16px;margin:-5px 0 0 0;width:0;height:0;
	border-style:solid;
	border-width:5px 0 5px 5px;
	border-color:transparent transparent transparent #ff0022;
}</code></pre>
<h3>Hover</h3>
<p>Změna barvy na hover je pak velice jednoduchá. Jenom změníme color, border-color a background-color. U border-color pak samozřejmě pouze ten směr, který je nadefinovaný pro danou šipku. <em>(Pořadí je horní - pravý - spodní - levý, stejně jako u marginu či paddingu)</em>.</p>
<pre><code class="css">a.shipka-next:hover {color:#0000b3;}
a.shipka-next:hover:after {border-left-color:#0000b3;}

a.shipka-next-adv:hover {color:black;}
a.shipka-next-adv:hover:before {background:black;}
a.shipka-next-adv:hover:after {border-left-color:black;}
</code></pre>
<h2>Generátor CSS tvarů</h2>
<p>Na chvíli se ještě vrátím k šipkám. Pamatovat si, jak přesně nastavit border-color a border-width abychom docílili patřičného tvaru není úplně v lidských silách, ale naštěstí existuje chytrý generátor, který styly vytvoří za nás. Stačí zazáložkovat a ušetříme si spoustu času při kódování grafiky.</p>
<blockquote>
<p><a href="http://apps.eky.hk/css-triangle-generator/" target="_blank">CSS triangle generator</a></p>
</blockquote>
<p>Pokud by nám trojúhelníky nestačily, můžeme použít některý z příkladů na stránkách "<em>The Shapes of CSS</em>". Space Invader sice není něco, co bychom chtěli mít na firemním webu, ale vědět, že i takového zobrazení lze docílit se někdy může hodit :-)</p>
<blockquote>
<p><a href="http://css-tricks.com/examples/ShapesOfCSS/" target="_blank">The Shapes of CSS</a></p>
</blockquote>
<h2>Font Awesome</h2>
<p>Font Awesome je písmo vektorových ikon, díky kterému můžeme mít stránky zase o něco lepší. Opět nám ušetří hromady obrázků, kde za použití CSS a knihovny piktogramů dostaneme přístup k rozumnému množství ikonek. Takové ty jako email <em>(obálka vedle odkazu)</em>, telefon <em>(ikonka vedle telefonu)</em>, uživatel <em>(človíček vedle odkazu na profil)</em> a spoustu dalších.</p>
<p>Na této url si můžeme stáhnout celý balík včetně předdefinovaných tříd pro CSS a samotného fontu: <a href="http://fortawesome.github.io/Font-Awesome/" target="_blank">fortawesome.github.io/Font-Awesome/</a>. Výchozí použití je poměrně jednoduché, podíváme se na seznam dostupných ikonek a danému elementu nastavíme tu správnou třídu: <a href="http://astronautweb.co/snippet/font-awesome/" target="_blank">astronautweb.co/snippet/font-awesome/</a>.</p>
<blockquote>
<p><a href="http://fortawesome.github.io/Font-Awesome/" target="_blank">Font Awesome @ GitHub</a><br /> <a href="http://astronautweb.co/snippet/font-awesome/" target="_blank">Font Awesome icon list</a></p>
</blockquote>
<h2>Doporučené použití</h2>
<p>Na výše uvedených odkazech najdeme vše, co je potřeba pro nasazení <strong>Font Awesome</strong>. Balík také obsahuje i poměrné velké CSS se všemi třídami a zde začínají problémy. Sám nerad používám hotová řešení, kde nemám jistotu, že se mi někde něco nerozbije... Přeci jen pokud se nejedná o jQuery, na kterou se lze spolehnout, nikdy nemáme jistotu, že se nějaké definice nezačnou hádat. Proto doporučuji zjednodušenou implementaci.</p>
<p>Nejdříve nadefinujeme font:</p>
<pre><code class="css">@font-face{
	font-family:'FontAwesome';
	src:url(fonts/fontawesome-webfont.eot);
	src:url(fonts/fontawesome-webfont.eot?#iefix) format('eot'),
		url(fonts/fontawesome-webfont.woff) format('woff'),
		url(fonts/fontawesome-webfont.ttf) format('truetype'),
		url(fonts/fontawesome-webfont.svg#fontawesome-webfont) format('svg');
	font-weight:normal;
	font-style:normal;
}
</code></pre>
<p>A následně si nastavíme pouze ty třídy, které reálně využijeme:</p>
<pre><code class="css">.awesome-ico:before {display:inline-block;font:15px/15px FontAwesome;padding-right:10px;color:#000;vertical-align:middle;}
.awesome-ico.email:before {content:'\f0e0';}
.awesome-ico.phone:before {content:'\f098';}
.awesome-ico.user:before {content:'\f007';}</code></pre>]]></content:encoded>
			<image>
    				<url>https://mike.treba.cz/img/2023/renewed/code.jpg</url>
			</image>
		</item>
		
		
		<item>
			<title>Jak jsem opravoval optický klam</title>
			<link>https://mike.treba.cz/jak-jsem-opravoval-opticky-klam/</link>
			<pubDate>Sun, 22 Jun 2014 16:57:21 +1100</pubDate> 
			<comments>https://mike.treba.cz/jak-jsem-opravoval-opticky-klam/#comments</comments>
			<dc:creator></dc:creator>
			<description><![CDATA[<p>Aneb stále se učím. Tedy abych byl přesný, nejednalo se o optický klam, ale o <strong>bug </strong>v zobrazení modelu <strong>RGB</strong>. Měl jsem stránku, kde byly v patičce ikonky sociálních sítí. A došel mi bug report, že druhá z ikon, YouTube, je trochu uskočená. </p>]]></description>   
			<guid isPermaLink="false">https://mike.treba.cz/jak-jsem-opravoval-opticky-klam/</guid>
			<content:encoded><![CDATA[<p>Aneb stále se učím. Tedy abych byl přesný, nejednalo se o optický klam, ale o <strong>bug </strong>v zobrazení modelu <strong>RGB</strong>. Měl jsem stránku, kde byly v patičce ikonky sociálních sítí. A došel mi bug report, že druhá z ikon, YouTube, je trochu uskočená. </p> <p>Jelikož obrázky byly stylama zmenšené a navíc měly jednopixelovou mezeru přímo v sobě, první, co mě napadlo, bylo samozřejmě vše přeuložit. Zkusil jsem mezeru v obrázku, mezeru mimo obrázek, dvoupixelovou mezeru vně i uvnitř obrázku, no prostě všechno... Nic.</p>
<p>Když se podíváte na náhled, tak opravdu ten YouTube posunutý je. Když si stránku pořádně zazoomujete, tak není.</p>
<p><img src="https://mike.treba.cz/img/2014/social-icons-big.png" alt="Social Icons Big" /></p>
<p>Po vyloučení stylové chyby mi začalo být jasné, že tady něco nehraje. Prohodit pořadí ikonek mě samozřejmě napadlo také, ale stále žádná změna. Nakonec jsem vše prokonzultoval s chytrým kolegou a hned jsem měl jasno. Opravdu tomu vadí červená vedle modré. Když jsem totiž zkoušel změnit pořadí, dal jsem akorát Google na druhou pozici, takže stále byla červená vedle modré. Ať už to byl <strong>Facebook </strong>nebo <strong>Google</strong>.</p>
<p>A řešení? Jedině dát ikonku až úplně nakonec. Následující screenshot už je v pořádku.</p>
<p><img src="https://mike.treba.cz/img/2014/social-icons-big-2.png" alt="Social Icons Big 2" /></p>]]></content:encoded>
			<image>
    				<url>https://mike.treba.cz/img/2014/opt-illusion.jpg</url>
			</image>
		</item>
		
		
		<item>
			<title>Když klient reportuje už opravené chyby</title>
			<link>https://mike.treba.cz/kdyz-klient-reportuje-uz-opravene-chyby/</link>
			<pubDate>Sun, 22 Jun 2014 13:15:40 +1100</pubDate> 
			<comments>https://mike.treba.cz/kdyz-klient-reportuje-uz-opravene-chyby/#comments</comments>
			<dc:creator></dc:creator>
			<description><![CDATA[<p>Provádění stylových, grafických či JavaScriptových úprav na webové prezentaci a jejich následné posílání na validaci klientovi by vydalo na samostatný blog, já vám ale dnes ukážu jednoduchý tip, jak těmto situacím co nejvíce předejít. Znáte to: upravíte styl, napíšete, že je hotovo a klient vám obratem odpoví, že není. </p>]]></description>   
			<guid isPermaLink="false">https://mike.treba.cz/kdyz-klient-reportuje-uz-opravene-chyby/</guid>
			<content:encoded><![CDATA[<p>Provádění stylových, grafických či JavaScriptových úprav na webové prezentaci a jejich následné posílání na validaci klientovi by vydalo na samostatný blog, já vám ale dnes ukážu jednoduchý tip, jak těmto situacím co nejvíce předejít. Znáte to: upravíte styl, napíšete, že je hotovo a klient vám obratem odpoví, že není. </p> <p>Tak musíte znovu otevřít email, napsat mu, aby zmáčknul <strong>ctrl&plus;F5</strong> nebo <strong>ctrl&plus;R</strong> a pak bude to v pořádku. Jenže po jisté době to samozřejmě začne být otravné... Jak tedy donutit prohlížeč aby smazal původní soubor v cache a nahradil ho novým?</p>
<p>Řešení je velice jednoduché. Využijeme GET parametrů tam, kde zdánlivě nic nedělají. Proměnná za otazníkem zpravidla slouží pro skriptovací jazyky a podmíněné zobrazení čehokoli, co v danou chvíli potřebujeme. Co se ale stane, když uvedeme parametr u obrázku či stylu? Prohlížeč takovýto zápis pochopí jako nový soubor, takže nezobrazí jeho starší verzi z cache ale načte ho pěkně znovu.</p>
<pre><code class="html">&lt;link rel="stylesheet" href="css/style.css<span class="red">?v=2</span>" type="text/css" media="screen" /&gt;</code></pre>
<p>Styly samozřejmě GET proměnné neumí, takže na pozadí se nic nestane. Stane jenom to, co potřebujeme. Klient uvidí aktualizovanou verzi stylů. Stejnou fintu můžeme použít i u obrázků na pozadí: s nimi bývají největší problémy. Musíme samozřejmě zvýšit verzi i u linku na styly, v nichž pak obrázek na pozadí zapíšeme úplně stejně:</p>
<pre><code class="css">body {background:url(../img/body-bg.png<span class="red">?v=2</span>) repeat-y 50% 0;}</code></pre>
<p>JavaScript jako jediný umí teoreticky zpracovat GET proměnné se kterými je volán, takže pokud už něco takového používáme, prostě přidáme parametr druhý.</p>
<pre><code class="html">&lt;script type="text/javascript" src="js/utils.js?load=forms<span class="red">&amp;v=2</span>"&gt;&lt;/script&gt;</code></pre>]]></content:encoded>
			<image>
    				<url>https://mike.treba.cz/img/2023/renewed/code-funny.jpg</url>
			</image>
		</item>
		
	
</channel>
</rss>