Ideální šířka stránky: nechte vybrat čtenáře

Pachollini, 17. června 2004, 07:46

Ideální šířka stránky?

Na weblozích i různých odborných periodicích (viz odkazy) již vyšly desítky kilobytů textů o tom, zda je lepší pevná či plovoucí šířka stránky a pokud pevná, jak má být stránka optimálně široká. Nebudu tady rozebírat argumenty pro tu či onu variantu, protože bych nutně opakoval mnohokrát vyřčené a pokusím se nabídnout řešení, které sice nelze použít vždy, ale z hlediska uživatele je asi nejideálnější: šířku stránky si nastaví uživatel.

Jak by takové ideální řešení mělo vypadat? IMHO asi takto: po načtění stránky se těm uživatelům, jejichž prohlížeč to umožňuje, zobrazí nějaký ovládací prvek, který bude umožňovat změnu šířky stránky. Vybranou šířku si samozřejmě musí zapamatovat. Řešení bude používat platné standardy (v našem případě JavaScript, DOM a CSS) a zárověň bude fungovat i v prohlížečích, které standardy nepodporují, ale jsou bohužel velmi rozšířené. JavaScriptový kód by měl být objektový. Pokud prohlížeč nepodporuje potřebné technologie, nemělo by se uživateli nic zobrazit, aby nebyl zbytěčně uváděn ve zmatek.

Jak to dopadlo, když jsem se toto ideální řešení pokusil uvést do prakse, můžete vidět na tomto serveru. Pokud nevidíte, zkuste zapnout JavaScript nebo mi napište, že to nefunguje. (Ale psal mi kamarád, co má Safari, že se mu tohle řešení líbí a v MSIE, Mozille i Opeře jsem je testoval, takže by mělo fungovat ve všech dalších slušných prohlížečích.)

Popis řešení

Celé řešení se dá rozdělit na tři části.
  1. Celkový design stránky

    Musíme počítat s tím, že uživatel bude se šířkou stránky manipulovat (a samozřejmě zvětšovat a zmenšovat písmo) a tomu přizpůsobit pozadí prvků a hlavně jejich vzájemné proporce.

    Dále si musíme rozmyslet, který prvek budeme zvětšovat. Já jsem použil řešení, které zvětšuje celkovou šířku obsahu stránky a definoval sloupcům s textem a menu šířku v procentech. Je však např. možné měnit jen šířku hlavního textového obsahu (sloupce) a menu nechat stále stejné.

    A konečně je třeba rozmyslet si, jak budeme šířku nastavovat – můžeme použít pixely, em nebo procenta. Pokud chceme, aby se velikost obsahu měnila, když uživatel změní velikost okna, použijeme procenta. Pokud chceme, aby se měnila při změně velikosti písma, budou se hodit em. Chceme-li, aby se neměnila vůbec (samozřejmě kromě případu, kdy ji změní uživatel), použijeme px. Já osobně fandím em, protože zachovává počet znaků na řádek.

  2. Ovládací prvek na změnu šířky stránky

    Tady se nabízí mnoho možností, např. formulář, kam uživatel vepíše požadovanou šířku, tlačítka pro změnu o definovanou velikost nebo táhlo, které umožní plynulou změnu tažením myší. Vzhledem k tomu, že číselné zadání se mi nezdá být příliš uživatelsky přívětivé (a o to zde přece jde) a tažení myší vyžaduje spoustu JavaScriptu, zvolil jsem kompromisní tlačítka. U nich je důležité umístění: pokud je obsah stránky umístěn na střed, měla by být rovněž veprostřed, aby při změně neucukávala pod myší a nejlépe ještě nahoře, ale tam mne příliš rušila, takže jsem se nakonec rozhodl pro spodek stránky.

    Ovládací prvek vložíme do stránky JavaScriptem pomocí DOMu, do HTML kódu stránky umístíme pouze kontejner, např. prvek <div>, do něhož se ovladač vloží.

  3. JavaScript, který ovládá nastavení šířky stránky

    JavaScriptový kód bude mít dvě základní funkce:
    Inicalizace stránky
    Do stránky se přidají ovládací prvky a přiřadí se jim akce a zároveň se zkontroluje, zda si již uživatel dříve nenastavil svou šířku stránky a pokud ano, použije se.
    Samotné ovládání velikosti
    Skript by měl umět zvětšit a zmenšit šířku stránky a zároveň ji držet v určitých mezích, aby nemohlo dojít k přílišnému zúžení či rozšíření.

Provedení

  1. Celkový design stránky

    V mém případě se mění šířka prvku, který v sobě pojímá všechen další obsah a má id „main“, ten dále obsahuje sloupec s textovým obsahem (id „content“), sloupec s menu (id „menu“) a div s id „kontrolz“, který bude obsahovat ovládací prvky. Ostatní prvky (patičku, záhlaví atd.) pro zjednodušení vypouštím. Relevantní CSS kód vypadá takto:

    #main
    	{
    	width: 58em;
    	max-width: 93%;	
    	margin: 0.5em auto;
    	padding: 0.5em 1em;
    	}
    
    #content
    	{
    	width: 69%;
    	float:left;
    	}
    
    #menu
    	{
    	width: 31%;
    	float: right;
    	}

    Pro uživatele MSIE bychom ještě mohli přidat kód, který nahradí chybějící vlastnost max-width, viz např. návod Svenda Tofteho, ale na druhé straně to zrovna v tomto případě není nutné, protože šířku si konec konců nastavuje uživatel.

    HTML kód, který potřebujeme pro změnu šířky, stránky má následující strukturu:

    <body>
    	<div id="main">
    		<div id="kontrolz">&nbsp;</div>
    		<div id="content">
    			[obsah]
    		</div>
    		<div id="menu">
    			[menu]
    		</div>
    	</div>
    	<script type="text/javascript">
    		$kontrolz=new c_kontrolz();
    		if($kontrolz)$kontrolz.add_page_width();
    	 </script>
    </body>
  2. Ovládací prvek

    Vzhledem k tomu, že se celý prvek bude vytvářet JavaScriptem, tvoří jej v HTML jen „zapouzdřující“ div s id „kontrolz“. CSS kód, který je použit na tomto webu, není důležitý pro funkčnost řešení, nýbrž jen pro vzhled ovládacích prvků, proto ho vynechám a přejdu rovnou k JavaScriptu. Pokud by někoho přesto zajímal, najde ho v CSS Seků, relevantní jsou všechny selektory začínající #kontrolz.

  3. JavaScriptový kód

    JavaScript je samozřejmě nejlepší připojit v externím souboru a zavolat z HTML hned za prvkem „kontrolz“. (Volání v události „onload“ u <body>, které se v podobných případech občas používá, by vedlo ke zbytečné prodlevě zobrazení, protože by se skript provedl až po načtení všech obrázků do stránky, což není nutné, stačí, když už ve stránce bude prvek „kontrolz“.)

    Následuje výpis kódu s komentáři uvozujícími jednotlivé funkce a objekty. Link na soubor s JavaScriptem bez těchto komentářů najdete na konci článku.

    Funkce gid pouze vrátí prvek s daným id a zde ji používám hlavně proto, abych zkrátil zápis.

    function gid($co)
    	{
    	return document.getElementById($co);
    	}

    Prototyp objektu c_kontrolz slouží k vytvoření „ovládacího panelu“, do něhož se metodou add_page_width přidají tlačítka na změnu šířky stránky (a výhledově i další funkce).

    function c_kontrolz()
    	{	
    	this.heading="Nastavení:"; 
    		// nadpis ovládacích prvků
    	this.node_id="kontrolz"; 
    		// id prvku, do něhož umísťujeme „ovládací panel“
    
    	this.page_width=false;
    	var $tnode,$hnode;
    	if(gid("kontrolz").firstChild) 
    		/* jednoduchý test, zda browser podporuje DOM; 
    		vyžaduje, aby v prvku s id „kontrolz“ 
    		byl ještě nějaký další prvek! 
    		(v našem případě pevná mezera) */
    		{
    		this.add_page_width=add_page_width;
    		this.node=gid("kontrolz");
    		this.node.removeChild(this.node.firstChild);
    			// odebere onu pevnou mezeru
    		$hnode=document.createElement("h3");
    		$tnode=document.createTextNode(this.heading);
    		$hnode.appendChild($tnode);
    		this.node.appendChild($hnode);
    		this.node.style.visibility="visible";
    			// předchozích 5 řádek 
    			vytvoří popisek („Nastavení“)
    		}
    	else return null;
    	}
    
    	function add_page_width()
    		{
    		this.page_width=new c_page_width();
    		}

    Prototyp c_page_width zařizuje samotné změny šířky stránky. Při jeho vytvoření se zavolá metoda create_width_kontrolz, která přidá do stránky ovládací tlačítka a přiřadí jim události, které zvětšují a zmenšují šířku. (Pozor, tady se předpokládá, že hlavní ovládací objekt typu c_kontrolz se jmenuje $kontrolz.) Objekt dále disponuje metodami plus a minus, volajícími metodu set_width, která obstará nastavení požadované hodnoty a uložení do cookie. Metoda set_width je rovněž volána při vytvoření objektu, kdy se z cookie zjistí dřívější nastavení uživatele a to se použije.

    function c_page_width()
    	{
    	this.main_div="main"; 
    		// id prvku, jehož velikost budeme nastavovat
    	this.units="em"; 
    		// jednotky pro zvětšování a zmenšování stránky
    	this.step=3; 
    		// krok zvětšování – o kolik ze zvětší / zmenší šířka 
    		po kliku na tlačítko
    	this.max_width=99; 
    		// maximální šířka, na větší se stránka neroztáhne
    	this.min_width=40; 
    		// minimální šířka
    	this.default_width=58; 
    		// přednastavená šířka
    	this.description="šířka stránky: ";
    	this.plus_title="zvětšit šířku stránky";
    	this.minus_title="zmenšit šířku stránky";
    
    	this.plus=plus;
    	this.minus=minus;
    	this.create_width_kontrolz=create_width_kontrolz;
    	this.set_width=set_width;
    
    	if (document.cookie.indexOf("page_width=")>-1) 
    		this.page_width=Number(document.cookie.substr
    		(document.cookie.indexOf("page_width=")+11,2));
    		// pokud byla dřívě nastavena šířka stránky 
    		(uložena v cookie page_width), použije se
    	if(isNaN(this.page_width))this.page_width=this.default_width;
    		// pokud se ji nepodařilo zjistit, 
    		použije se defaultní
    	this.create_width_kontrolz();
    		// vytvoření ovládacích tlačítek
    	this.set_width(this.page_width);
    		// nastavení šířky stránky
    	}
    
    	function minus()
    		{
    		this.set_width(this.page_width-this.step);
    		}
    
    	function plus()
    		{
    		this.set_width(this.page_width+this.step);
    		}
    
    	function set_width($jak)
    		{
    		if($jak>this.max_width) $jak=this.max_width;
    		if($jak<this.min_width) $jak=this.min_width;
    		this.page_width=$jak;
    		gid(this.main_div).style.width=
    			this.page_width+this.units;
    		document.cookie="page_width="+this.page_width
    		+";path=/;expires=Wed, 30 Apr 2014 12:00:00 GMT";
    		this.pwvalue.firstChild.nodeValue=" "
    			+this.page_width+this.units+" ";
    		}
    
    	function create_width_kontrolz()
    		{
    		var $tnode,$imgnode;
    		this.node=document.createElement("div");
    		$tnode=document.createTextNode(this.description);
    		this.node.appendChild($tnode);
    			// vytvoří div a vloží popisek
    			
    		$imgnode=document.createElement("img");
    		$imgnode.src="/img/arrows/wminus.gif";
    		$imgnode.title=this.minus_title;
    		$imgnode.alt=$imgnode.title;
    		$imgnode.onclick=function()
    			{$kontrolz.page_width.minus();}
    		this.node.appendChild($imgnode);
    			// vytvoří tlačítko (obrázek) 
    			zmenšující šířku
    
    		this.pwvalue=document.createElement("span");
    		this.pwvalue.id="pwvalue";
    		this.pwvalue.appendChild(document.createTextNode(""));
    		this.node.appendChild(this.pwvalue);
    			// vytvoří prvek, v němž zobrazuje 
    			nastavená šířka
    			
    		$imgnode=document.createElement("img");
    		$imgnode.src="/img/arrows/wplus.gif";
    		$imgnode.title=this.plus_title;
    		$imgnode.alt=$imgnode.title;
    		$imgnode.onclick=function()
    		{$kontrolz.page_width.plus();}
    		this.node.appendChild($imgnode);
    			// vytvoří tlačítko (obrázek) 
    			zvětšující šířku
    			
    		$kontrolz.node.appendChild(this.node);
    			// přidá vše do stránky
    		}

Shrnutí postupu

Jak postupovat, pokud chete implementovat toto řešení do svých stránek?

  1. Rozmyslete si, jak vytvořit či přizpůsobit strukturu stránek a zejména u kterého prvku budete chtít měnit šířku.
  2. Připojte ke stránce externí JavaScript, v němž upravíte jednotky, krok, popisky atd. dle své libosti.
  3. Vložte do stránky prvek „kontrolz“ a za něj JS kód, který přidá ovládací prvky.
Pro lepší pochopení jsem vytvořil ukázkovou stránku s minimem přebytečného kódu a balíček se vším potřebným.

Odkazy

Několik odkazů na příspěvky o šířce stránky:

Zájemcům o použití rozhraní DOM v JavaScriptu doporučuji vynikající referenční příručku Gecko DOM Reference, jejíž PDF verzi používám dnes a denně.

Co vy na to?

zobrazit všechny komentáře

Aktuální Seky

.