ugrás a tartalomhoz

Dinamikus betűméret választó

Bártházi András · 2004. Május. 16. (V), 22.45
Dinamikus betűméret választó
Honlapunk készítésekor - ha szempont, hogy mindenki számára elérhető tartalmat nyújtson -, egyik fontos dolog, hogy gondolnunk kell a gyengénlátókra is. Ebben a cikkben ennek egyik következményét, az oldalon található szövegek betűméretének állítását lehetővé tevő megoldást mutatok be, mellyel lehetővé tehetjük, hogy a felhasználóink kiválaszthassák, mekkora betűkkel szeretnék olvasni szövegeinket. Ezt Javascripttel, sütikkel és egy kis CSS-sel fogjuk megvalósítani, úgy, hogy a böngésző emlékezzen a kiválasztott méretre, csak egyszer kelljen beállítani.

A betű átméretezés lényege, hogy egy kis Javascript kódrészlettel az oldal CSS-ének egy részét felülbíráljuk. Ezekhez alternatív CSS-eket fogunk használni, melyekben a betűnagyságok különböznek csak. Célként két extra dolgot tűzünk ki: egyrészt hogy a kiválasztott méret megjegyzésre kerüljön, másrészt hogy kompatibilis legyen a Firefox (Firebird) alternatív stílusválasztóival.

A megvalósításhoz csak kliens oldali eszközt, vagyis Javascriptet használunk, a tároláshoz pedig sütiket fogunk felhasználni.

Példaoldal

Először is vegyünk egy példaoldalt, amiből kiindulhatunk, és kiegészíthetjük majd a betűátméretezés lehetőségével. Ezt a programot hívjuk egyszerűen index.html-nek:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="hu" lang="hu">
<head>
 <title>Betűátméretezés példaoldal</title>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2" />
 <link rel="stylesheet" type="text/css" href="common.css" />
</head>
<body>
  <h1>Hello Világ!</h1>
  <p>Ez a dokumentum példaként szolgál a betűkészlet átméretezéshez.</p>
  <p>A benne levő betűket átméretezhetővé fogjuk tenni.</p>
</body>
</html>
Ennek a dokumentumnak lesz egy common.css-e is, amelyből ki fogunk tudni indulni:

body {
  background: #eeeeee;
  color: #800000;
  margin: 0;
  padding: 25px;
}
h1 {
  font-family: Helvetica, Arial, sans-serif;
  font-size: 1.4em;
  background: inherit;
  color: #000040;
  padding: 5px 0;
  margin: 5px 0;
  border-bottom: 3px double #000000;
}
p {
  font-family: Helvetica, Arial, sans-serif;
  font-size: 1em;
  background: inherit;
  color: #000000;
  padding: 0;
  margin: 5px 20px;
}
Ez egy teljesen átlagos dokumentumnak tekinthető, az egyetlen fontos dolog benne talán az, hogy a betűméreteket relatívan, az em megadási lehetőséggel adtuk meg.

Extra stíluslapok definiálása

Az oldalon több dolgot kell majd megváltoztatnunk. Első körben definiáljunk három extra stíluslapot, és ezekben a stíluslapokban adjunk meg különböző méreteket az oldal szövegeinek. Ennek kapcsán a Firefox-ban már meg is fog jelenni a kis stílusválasztó ikon.

Íme a kívánt módosítás után az index.html-ünk:

[...]
 <link rel="stylesheet" type="text/css" href="common.css" />
 <link rel="alternate stylesheet" type="text/css" title="small" href="small.css" />
 <link rel="stylesheet" type="text/css" title="normal" href="normal.css" />
 <link rel="alternate stylesheet" type="text/css" title="large" href="large.css" />
[...]
A hozzáadott stíluslapok két dologban különböznek az eredeti változattól: egyrészt kettő rel tulajdonságának az értéke alternate stylesheet, mely az alternatív stíluslapok jelölésére szolgáló módszer, míg mindhárom esetén egy title tulajdonságot is megadtunk, ami a nevét fogja jelölni a stíluslapnak. Ezek tartalmának csak Firefox (és más, magába a böngészőbe épített választási lehetőséget nyújtó kliens) esetén van jelentősége, megléte viszont annak meghatározására szolgál, hogy mely tartalmak között tudunk kapcsolgatni.

A három CSS a következő lesz (rendre small.css, normal.css, large.css):

body {
  font-size: 14px;
}

body {
  font-size: 16px;
}

body {
  font-size: 24px;
}
Ezekben a CSS-ekben csak a betűméretekre vonatkozó információk kaptak helyet. Mivel a betűméret öröklődik (ezért használtunk relatív betűméretet!), ezért elég volt a body elemre megadni a nagyságot, a többi elem (esetünkben a h1 és p) ettől fog függni, külön a méretük megadása felesleges. Ha ez a CSS-ünk kialakítása miatt nem lenne elég, bátran adjuk meg az összes az oldalon található elem betűméretét külön, felülbírálva ezzel az eredetiket.

Választási lehetőség biztosítása

A választási lehetőséget Javascript segítségével fogjuk megjeleníteni, így csak akkor fog ténylegesen látszani, ha valóban használható is. Ehhez a következő sort kell felvenni a common.css meghívása elé:

 <script type="text/javascript" language="javascript" src="fontsize.js"></script>
A fontsize.js tartalma egyelőre a választási lehetőség megjelenítése lesz:

function fontresizeStart() {
  fontresizeShow();
}

function fontresizeShow() {
  var div = document.createElement("div");
  div.id = "fontresize";
  var aSmall = document.createElement("a");
  var aNormal = document.createElement("a");
  var aLarge = document.createElement("a");
  aSmall.onclick = function() { StyleActivate('small'); return(false); };
  aSmall.href = "#";
  aSmall.className = "small";
  aSmall.appendChild(document.createTextNode('A'));
  aNormal.onclick = function() { StyleActivate('normal'); return(false); };
  aNormal.href = "#";
  aNormal.className = "normal";
  aNormal.appendChild(document.createTextNode('A'));
  aLarge.onclick = function() { StyleActivate('large'); return(false); };
  aLarge.href = "#";
  aLarge.className = "large";
  aLarge.appendChild(document.createTextNode('A'));
  div.appendChild( aSmall );
  div.appendChild( aNormal );
  div.appendChild( aLarge );
  document.body.appendChild( div );
}
A lefutásához az onload eseményhez kell rendelnünk a fontresizeStart() függvény meghívását:

<body onload="fontresizeStart();">
A választó megjelenítéséhez szükséges stílust definiálnunk, így ki kell bővítenünk a common.css-t, illetve a betűméret állító CSS-eket. Az előbbibe az alábbi definíciókat kell felvenni:

#fontresize {
  right: 0;
  top: 0;
  position: absolute;
  background: #000000;
  color: #ffffff;
  width: 90px;
  height: 30px;
}
#fontresize a {
  display: block;
  color: #ffffff;
  text-decoration: none;
  float: left;
  width: 30px;
  line-height: 30px;
  text-align: center;
}
#fontresize a.small {
  font-size: 14px;
}
#fontresize a.normal {
  font-size: 16px;
}
#fontresize a.large {
  font-size: 24px;
}
A három CSS-t pedig az alábbi kódokkal kell kibővíteni (rendre small.css, normal.css, large.css):

#fontresize a.small {
  color: #8080ff;
  font-weight: bold;
}

#fontresize a.normal {
  color: #8080ff;
  font-weight: bold;
}

#fontresize a.large {
  color: #8080ff;
  font-weight: bold;
}
Ennek hatására az aktuális CSS-t jelképező "A" betű mindig vastagon, és kék színnel fog megjelenni.

Választási lehetőség megvalósítása

Ha már ilyen jól előkészítettük, itt az ideje a választás megvalósításának is. Ehhez egy új eljárást veszünk fel a fontsize.js-be:

function StyleActivate( value ) {
  if (value == '') { return; }
  var i, lnk;
  for( i = 0; (lnk = document.getElementsByTagName("link")[i]); i++ ) {
    if ( lnk.getAttribute('rel').indexOf('style') != -1 && lnk.getAttribute('title') ) {
      lnk.disabled = true;
      if ( lnk.getAttribute('title') == value ) {
          lnk.disabled = false;
        }
    }
  }
}
Ez az eljárás a dokumentum összes link elemén végigmegy, és ha title tulajdonsággal rendelkező stíluslapról van szó, akkor letiltja, kivéve ha a neve megyezik a paraméterben kapott értékkel.

Ennek hatására a választási lehetőség élni fog, már csak két feladat maradt, az egyik a kiválasztott érték mentése, a másik pedig értelemszerűen a visszatöltése.

Mentés és visszaállítás

A mentést sütik segítségével oldjuk meg. Az oldalról történő távozáskor, az onunload esemény hatására az aktuális állapotot elmentjük egy sütibe. Ennek a megoldásnak az az előnye, hogy az alternatív stílusválasztókat (Firefox) is támogatja (ellenkező esetben a változtatáskor is menthetnénk az új értéket).

A sütik írásáért a következő script részlet a felelős, melyet a fontsize.js fájlhoz adhatunk hozzá:

function CookieSet(name,value) {
  document.cookie=name + "=" + escape(value) +
    ";expires=Thu Feb 10 2028 12:00:00 GMT+0100;path=/;domain=" + document.domain;
}
A süti domainje az aktuális domain lesz, lejárni nem mostanában: 2028. februárjában fog. A feladat még az aktuális állapot kiolvasása, ezt is a fontsize.js-hez fűzzük hozzá:

function StyleActual( prefix ) {
  var i, lnk;
  for( i = 0; (lnk = document.getElementsByTagName("link")[i]); i++ ) {
    if ( lnk.getAttribute('rel').indexOf('style') != -1 &&
         lnk.getAttribute('title') &&
        !lnk.disabled ) {
        return lnk.getAttribute('title');
    }
  }
  return null;
}
Végül az onunload esemény végrehajtásakor kell a kiolvasást, és a mentést elvégeznünk, ezért a body elemünk a következőre módosul:

<body onload="fontresizeStart();" onunload="fontresizeEnd();">
És persze a fontresize.js-t is módosítani kell:

function fontresizeEnd() {
  CookieSet( 'preferences_fontsize', StyleActual() );
}
Persze nem elég csak a mentést megvalósítani, a visszaállítás is fontos. Ehhez a fontresizeStart()-ot kell módosítani a fontsize.js-ben:

function fontresizeStart() {
  fontresizeShow();
  StyleActivate( CookieGet('preferences_fontsize') );
}
Illetve még mindig itt, fel kell venni a CookieGet() eljárást is:

function CookieGet( name ) {
  var name = name + "=";
  var cs = document.cookie.split(';');
  for (var i=0; i<cs.length; i++) {
    var c = cs[i];
    while (c.charAt(0)==' ') c = c.substring(1,c.length);
    if (c.indexOf(name) == 0) return c.substring(name.length,c.length);
  }
  return null;
}

Egy másik megoldás a visszaállításra

Lehetőségünk van egy másik megoldásra is a visszaállításhoz, ennek kivitelezése házi feladat lesz, de íme a lényege: az onload esemény helyett már a fejlécben, script elemek között a süti értékétől függően úgy írjuk ki az alternatív stíluslapokat, hogy azok értéke megfelelő legyen.

Összefoglalás

A programot befejeztük, a fentiek megvalósításával működni is fog az oldalunkon a betűméret választó. Sok irányba lehet a scriptet továbbfejleszteni, és persze sokkal szebb megjelenítést is lehet hozzá választani, de itt most a lényeg az volt, hogy egy olyan megoldást mutassak be, mely egyszerűségével érthető lesz az olvasó számára. A program működés közben megtekinthető itt: http://barthazi.hu/betumeret/. Egy zip fájlban is elérhető itt: http://barthazi.hu/betumeret/betumeret.zip
 
Bártházi András arcképe
Bártházi András
Az Emarsys-nál dolgozik vezető fejlesztőként, és az API-ért, integrációkért felelős termékmenedzserként. Szeret profi csapatban profit alkotni.
1

Szia! Csak egy aprosag, az

Hodicska Gergely · 2004. Május. 17. (H), 06.59
Szia!

Csak egy aprosag, az innerHTML ha jol tudom nem szabvanyos, ezert celszerubb helyette a createTextNode hasznalata:
div.appendChild(document.createTextNode('szoveg'));

Felho
2

Jogos

Bártházi András · 2004. Május. 17. (H), 08.01
Szia!

Jogos, javítottam!

-boogie-
3

ezt meglehetne valahogy csin

Anonymous · 2004. Május. 23. (V), 15.45
ezt meglehetne valahogy csinálni php-nuke-ba?
4

Meg lehet.

Bártházi András · 2004. Május. 23. (V), 17.41
Persze, miért ne lehetne megoldani?

-boogie-
5

kicsit bővebben? :) valahog

Anonymous · 2004. Május. 24. (H), 19.11
kicsit bővebben? :)
valahogy úgy kellene, hogy a /includes-be a javascriptet
és valami block féleségbe a lehetőségeket?
6

Fogalmam sincs

Bártházi András · 2004. Május. 24. (H), 22.49
Az az igazság, hogy nem tudom: nem foglalkoztam a PHP-Nuke és társai felépítésével. De egyszerűen kirakod az oldal elejére ezeket, ahol generálódik. És kell két-három alternatív CSS-t készíteni neki, illetve ahova kedved tartja, beszúrni a kezelőfelületet hozzá.

-boogie-
7

Példa

kgyt · 2004. Jún. 23. (Sze), 12.23
Már láttad Internet Explorerben a példát?
Error hegyek...

--
Szeretettel: Károly György Tamás
kgyt##kukac##kgyt.hu - http://kgyt.hu
8

Még nem...

Bártházi András · 2004. Jún. 23. (Sze), 12.32
Még nem láttam, itt a munkahelyemen nincs is pl. ;)

Amúgy a cél inkább a lehetőség és a hogyan bemutatása volt, nem a konkrét megvalósítás. Ha lesz egy kis időm, megnézem, de ha valaki kijavítgatná, megköszönném. Bár elvileg mennie kellene.

-boogie-
9

IE alatt

Bártházi András · 2004. Dec. 16. (Cs), 10.13
A történeti hűség kedvéért: a dolog tökéletesen megy Internet Explorer (hatos verziója) alatt. Azt hiszem a példaoldalra volt kitéve rossz verzió, amit akkor gyorsan javítottam is.

-boogie-
10

----

kmm · 2007. Okt. 3. (Sze), 11.23
És már példaoldal sincs :-)
11

Off: hozzászólás témája

janoszen · 2007. Okt. 3. (Sze), 12.08
Üdv,

időről időre fölmerül, most megint, hogy a hozzászólások témája nem önös érdekből van, hanem az kerül be az RSS-be például. Ennek megfelelően nem tudtam most sem én sem más RSS használó nem tudta hova tenni a hozzászólást. Légyszi figyeljünk erre.

J
12

nincs , de!

Sediqwe · 2009. Május. 11. (H), 09.22
Egy apróbb hiba van a kódban, amit én mint hozzá nem értő, csak nagy küzdelem árán találtam meg :\
"function StyleActivate( value ) { if (value == '') { return; ) var i, lnk; "
a return mögött egy sima zárójel van, pedig kapcsos kéne, emiatt nem müködött a kód!
a hiba meglelve! Köszönet a kiváló leírásért!
13

Köszi, hogy szóltál,

Török Gábor · 2009. Május. 11. (H), 10.33
Köszi, hogy szóltál, javítottam a cikkben az elgépelést.