ugrás a tartalomhoz

CSS lépésről-lépésre: képválasztás listapanel segítségével

PiG · 2004. Okt. 19. (K), 21.00
CSS lépésről-lépésre: képválasztás listapanel segítségével
A mai nap (a múlt hetihez hasonlóan) egy új sorozat indul útjára, CSS lépésről-lépésre címmel. A sorozat keretében minden alkalommal egy-egy CSS alapú megoldással fogunk megismerkedni, melyek mind a CSS rugalmasságát, illetve lehetőségeit fogják bemutatni. Első alkalommal egy olyan listaválasztó kialakításával ismertet meg minket P][G, melynél a szöveges felsorolás mellett képek is megjelennek, s ezáltal - például - kategóriák közül "WYSIWYG" módon választhatunk. Boogie.

Az ötlet

Nemrégiben, saját használatunkra készített portálrendszer adminisztrációs felületének kialakításakor, a hírek rovat kategóriáinak kialakításánál az jutott eszembe, milyen jó is lenne, ha a kategóriákba sorolásnál egy listapanelből választhatnék, és a választáskor mindjárt magában a listapanelban látnám is a kategóriához tartozó képet. A képkiválasztást már jó pár helyen láttam rádiógombokkal vagy felugró ablakok segítségével megvalósítani - de én direkt nem így akartam. Pár perc kísérletezgetés után elértem a kívánt eredményt:

A végeredmény


Csatolmányok

A sasszeműek észrevehetik, hogy a kép bizony nem Internet Explorerben készült, és igazuk is van. A következőkben leírtak csakis Mozillában (illetve a Gecko alapú böngészőkben: Firefox, Galeon, Camino, stb.) voltak hajlandóak működni. Mivel - mint fentebb is írtam - saját, belső használatra készült oldalon használom a bemutatott eljárást, és amúgy is Mozillát használunk, ezért különösebben nem izgatott a dolog.

A megvalósítás

A megvalósítást természetesen szokásos HTML elemekkel és CSS definíciókkal képzeltem el. Lehetséges lenne akár JAVA appletet, Flash megoldást is készíteni, vagy netán többoldalas Javascript kódokat kiagyalni, de valahogy úgy éreztem, ezekhez nem lenne idegzetem. A kezdetekben még csak agyamban létező CSS-es megoldás pedig olyan elegánsnak és pofátlanul egyszerűnek tűnt, hogy nem bírtam ellenálni a kísértésnek és nekiálltam.

A select elem létrehozása

Kiindulásként egy mezei lista szolgál:

<select name="icon" id="icon" size="3">
 <option value="0">Hírek</option>
 <option value="1">Karbantartás</option>
 <option value="2">Fontos</option>
 <option value="3">Mozilla</option>
 <option value="4">Firefox</option>
</select>
Nos, eddig még nem túl izgalmas, de legalább Internet Explorerben is működik! :-))

Lista méreteinek meghatározása

Mivel képeim 48x48-as méretűek, ezért a lista (select) magasságát ehhez alkalmazkodva határoztam meg (size="3" - tehát 3x48px=144px), a szélességet pedig hasraütésszerűen 200px-ben. Ne feledjük a 48px széles képecskének is el kell férnie, valamint a szövegnek is, és az sem árt, ha pár pixel helyet hagyunk a kettő között! Miután a listapanel befoglaló méretei megvannak, nekiláthatunk az egyes <option> elemek megformázásának is. Ismét a kép méretéből kiindulva a magasság 48px magas lesz. Stíluslapunk, illetve listapanelünk tehát a következőképp fest:

<style type="text/css">
select {
  height: 144px;
  width: 200px;
}
option {
  height:48px;
}
</style>
Internet Explorert használó barátaink már most nem azt látják, amit kéne, ugyanis az <option> elem magassági beállításának nincs hatása (az én IE-mben biztos nincs!). De lépjünk tovább!

A képek - végre!

Végre elértünk a képek elhelyezéséhez. CSS szabályainkat tovább finomítva rövidesen széles mosollyal nyugtázhtajuk, hogy a végeredmény olyan, mint mi magunk - azaz tökéletes. :-)

Tehát a képecskék elhelyezéséhez vagy a <select> elem <option> elemeit látjuk el id-vel, és a stíluslapban később ezekre hivatkozunk, vagy magukat az <option> elemeket módosítjuk a megfelelő stílusjellemzőkkel. A következőkben az utóbbi megoldást láthatjuk:

<select name="icon" id="icon" size="3">
 <option style="background-image:url(images/news.png);" value="0">Hírek</option>
 <option style="background-image:url(images/cog.png);" value="1">Karbantartás</option>
 <option style="background-image:url(images/important.png);" value="2">Fontos</option>
 <option style="background-image:url(images/mozilla.png);" value="3">Mozilla</option>
 <option style="background-image:url(images/firefox.png);" value="4">Firefox</option>
</select>
Könnyen rájövünk innentől kezdve, hogy nem kellene a háttérképnek ismétlődnie, és a szöveg pedig kezdődhetne beljebb, hogy ne fedje el a képet. Pont ezt tudjuk a background-repeat és a padding tulajdonság segítségével beállítani! Stíluslapunkat ennek megfelelően átalakítva:

<style type="text/css">
select {
  height: 144px;
  width: 200px;
}
option {
  height: 48px;
  padding-left: 60px;
  text-align: left;
  background-repeat: no-repeat;
}
</style>

Utolsó simítások

Bár már azt hinnénk készen vagyunk, utolsó simításként azért próbáljuk meg a listaszöveget a képek közepéhez igazítani függőlegesen. A függőleges igazítás problémás dolog, ha nem táblázatcellán belül vagyunk. Jelen esetben is hiába próbálkoztam a vertical-align: middle beállítással, eredménye nem volt. Így a jó hasraütéses hagyományokat követve a padding-top értékét állítottam át, úgy kábéra. Ez a betűméret függvényében változhat, de ha pontosan pixelre megadunk font-size segítségével egy méretet is, akkor nagy meglepetés nem fog érni minket. Ezzel együtt persze a height értéket csökkenteni kellett, hogy az összesített magasság továbbra is az eredeti 48px maradjon.

<style type="text/css">
select {
  height: 144px;
  width: 200px;
}
option {
  height: 33px;
  padding-top: 15px;
  padding-left: 60px;
  text-align: left;
  background-repeat:no-repeat;
}
</style>
Ha még ez sem elég, akkor az option:hover pszeudo kiválasztó esetében adjunk meg még egy szabályt: option:hover { background-color: #F0F8FF; }. Így egérrel a listaelemek fölött a listaelemek háttérszíne megváltozik.

A tökéletes végeredményt elérve paskoljuk meg vállunkat, dőljünk hátra és mosolyodjunk el, mert olyant vittünk véghez, amit az internetező társadalom kb. 10% tud majd megcsodálni, értékelni pedig még annyi sem!

A tökéletesnél is tökéletesebb

Rövid pihenő és megfelelő mennyiségű öndicséret után térjünk vissza még egy kicsit a tettek mezejére! Miért is?, kérdezhetitek, hiszen már készen vagyunk. Igaz, de ez a megoldás még nem aknázza ki teljes mértékben a CSS 2 lehetőségeit. Mivel Internet Explorerben a megoldásunk úgyse működik, Mozilla alatt pedig igen, ezért itt szabadon használhatunk olyan dolgokat is, amik tekintetében egyébként vissza kellene fognunk magunkat. Aki kicsit nézegette már a szabvány, az tudja, hogy HTML tulajdonság alapján is megadható szabály. Jelen példánkban az <option> elem attribútuma a value, mely 0 és 4 közti intervallumban vesz fel értékeket. A tulajdonság kiválasztó segítségével igen sokféleképpen behatárolhatjuk azon elemeket, melyekre a szabályt alkalmazzuk. Lássunk ebből néhányat:
[att]
    Akkor illeszkedik, ha az elem rendelkezik bármilyen att attribútummal. Pl.: h1[title]{color:blue} - minden title attribútummal rendelkező h1 elem kék lesz.
[att=val]
    Akkor illeszkedik, ha az elem att attribútuma pontosan val. Pl.: option[value="1"]{color:green} minden option elem, melynek value attribútuma 1, zöld lesz.

Internet Explorert használók már csak a fejüket kapkodják, és sehogy sem akar összejönni nekik. Nem is fog - a hiba a "készülékükben van", sajnos ez a lehetőség az egyik, mely náluk nem működik.

A kezdetekhez visszakanyarodva HTML kódunk ismét legyen a következő:

<select name="icon" size="3">
 <option value="0">Hírek</option>
 <option value="1">Karbantartás</option>
 <option value="2">Fontos</option>
 <option value="3">Mozilla</option>
 <option value="4">Firefox</option>
</select>
Stíluslapunkat a tulajdonság kiválasztók kipróbálására a következőként módosítsuk (helytakarékosság miatt a szabályokat egy sorba tördeltem, de aki idáig követte a cikket azt már nem hiszem, hogy ez megzavarja!):

<style type="text/css">
select { height: 144px; width: 200px; }
option { height: 33px; padding-top: 15px; padding-left: 60px; text-align: left; background-repeat: no-repeat; }
option[value="0"] { color:red; }
option[value="1"] { color:blue; }
option[value="2"] { color:green; }
option[value="3"] { color:navy; }
option[value="4"] { color:fuchsia; }
option:hover { background-color: #F0F8FF; }
</style>

Tehát a különböző value attribútummal rendelkező <option> elemek a value értéke szerint kapták meg színüket. Innen már ismét csak egy kis lépést kell tennünk, hogy a kívánt eredményt kapjuk. Ha netán több lista (<select>) is szerepel oldalunkon, úgy érdemes megkülönböztetni ezeket valahogy, és a kiválasztóban ezzel megtoldva megadni a szabályt (magától adódik, hogy a select elem name tuladjonságát használjuk erre a célra):
[colorer=html]
<style type="text/css">
select { height: 144px; width: 200px; }
option { height: 33px; padding-top: 15px; padding-left: 60px; text-align: left; background-repeat: no-repeat; }
select[name="icon"] option[value="0"] { background-image: url(images/news.png); }
select[name="icon"] option[value="1"] {background-image: url(images/cog.png); }
select[name="icon"] option[value="2"] {background-image: url(images/important.png); }
select[name="icon"] option[value="3"] {background-image: url(images/mozilla.png); }
select[name="icon"] option[value="4"] {background-image: url(images/firefox.png); }
select[name="icon"] option:hover { background-color: #F0F8FF; }
</style>
Most, hogy többféle megoldást is találtunk a kezdeti problémára, nem marad más hátra, mint a további kísérletezés. Lehet az egészet külső stíluslapra helyezni, melyet valamilyen programmal, adatbázisból generálunk, lehet játszani a formázási lehetőségekkel, s lehet gondolkodni még újabb lehetőségeken is. Ehhez sok sikert kívánok!

Külön köszönet Boogie-nak az építő kritikáért :-)

Források

 
1

url és az attr(value)

T.G · 2004. Okt. 19. (K), 23.40
Miközben olvastam a cikket eszembe jutott valami, de nem nagyon találok rá megoldást.

Tegyük fel, hogy nem számok, hanem szövegek az értékek:

<select name="icon" id="icon" size="3">
 <option value="news">Hírek</option>
 <option value="cog">Karbantartás</option>
 <option value="important">Fontos</option>
 <option value="mozilla">Mozilla</option>
 <option value="firefox">Firefox</option>
</select>
Ekkor, milyen jó lenne egy darab sorral megadni a képeket:

<style type="text/css">
select#icon option { background-image: url(images/attr(value).png); }
</style>
Szerintem, ha én egy okos böngésző lennék, akkor ezt megérteném. :) De sajnos nem vagyok okos böngésző, és nem is tudom, hogy ezt hogyan kellene megértetni egy majdnem nagyon okos böngészővel. :)
2

Nem rossz ötlet.

Bártházi András · 2004. Okt. 20. (Sze), 07.16
Ilyet biztos nem lehet csinálni, de a generált tartalom talán megoldás lehet. Még lehetne valami ilyesmivel próbálkozni:

<style type="text/css">
select#icon option:before {
  content: attr(value);
}
</style>
De itt meg szövegnek veszi (bár nem próbáltam, hogy ezzel tud-e kezdeni valamit a Mozilla? Vagy esetleg egy ilyen lehetne megoldás:

<style type="text/css">
select#icon option {
  background-url: url("images/" attr(value) ".png");
}
</style>
Szumma: ez jó lehetne, de sajnos a mai CSS értelmezők ilyet nem támogatnak szerintem. (Azért valaki kipróbálhatná, hátha... :)

-boogie-
4

Aha

PiG · 2004. Okt. 20. (Sze), 08.01
Nekem is eszembe jutott, hogy jó lenne vmi hasonlót kiagyalni, hiszen a cikkben ismertetett utolsó példa bár szép, - és zavarbaejtően profi :-) - de sokkal macerásabb - és nem utolsósorban hosszabb (több adat letöltése a kliensre!) -, mintha simán az <option style="...">-ban adnánk meg. Igazán valóban akkor nyerne értelmet, és lenne nagyon elegáns, ha tényleg lehetne css-ben akár függvényeket is használni.
Ahogy a cikk végén is utalás történik rá, a szabályok legenerálására marad vmilyen szerveroldali scriptnyelv, ami valószínű amúgy is rendelkezésre áll, hiszen ha nem lenne, akkor hogyan dolgoznánk fel a <select>-ban kiválasztott opciót...
P][G
15

Esetleg

kgyt · 2004. Okt. 22. (P), 13.15
Esetleg ezt valahogy ki lehetne használni...

http://www.w3.org/TR/CSS21/syndata.html#counter

--
Szeretettel: Károly György Tamás
kgyt&kgyt.hu - http://kgyt.hu
16

IE vs FF

Anonymous · 2006. Jún. 28. (Sze), 07.43
Azon tűnődtem, hogy ezt meg lehetne IE alatt is működőre csinálni egy scrollozható DIV meg unsorted list, egy hidden form field és egy kis JavaScript segítségével. Sajnos időm nincs megcsinálni, csak ötletelek...
3

kozepre igazitas fuggolegesen

Anonymous · 2004. Okt. 20. (Sze), 07.44
Egysoros szovegeket fuggolegesen nagyon egyszeruen lehet kozepre igazitani: ugyanakkorara kell allitani a sor magassagot mint a blokk elem magassaga. Igaz a vertical-align:middle mar kozepre tudja rakni a szoveget.

option {
  height: 48px;
  padding-left: 60px;
  text-align: left;
  background-repeat:no-repeat;

  line-height:48px;
  vertical-align:middle;
}


Jo a cikk egyebkent! Kene egy kep IE-bol, hogy hogyan is nez ki ott. Nem ront el semmit, csak egyszeruen sima selectkent fog megjelenni.

Jano
5

Az ember mindig tanul...

PiG · 2004. Okt. 20. (Sze), 08.08
Na, ezt kipróbálom, mert sokkal kiszámíthatóbbá és egyszerűbbé tenné a formázást.
P][G
6

pelda zipben

Anonymous · 2004. Okt. 20. (Sze), 08.18
Jo lenne ha csatolva lenne kesz pelda zipben. Ikonokkal, miegymassal, hogy lehessen vele egybol jatszani. Ez megoldhato?

Jano
7

Megoldható

Bártházi András · 2004. Okt. 20. (Sze), 09.53
Igen, csak még nem volt rá sajnos időm összeállítani. Ha P][G eljuttat hozzám egy ilyet (most épp nem áll rendelkezésemre az anyag, amit eljuttatott anno hozzám), akkor csatolom a cikkhez.

-boogie-
8

Délután küldöm...

PiG · 2004. Okt. 20. (Sze), 12.04
...előtte még megebédelek, meg ilyesmi :-)
P][G
9

Csatolva

Bártházi András · 2004. Okt. 20. (Sze), 13.56
A cikk elején megtalálható, letölthető.

-boogie-
10

Kiraly

Jano · 2004. Okt. 20. (Sze), 14.25
Koszonet!
11

Szorgalmi

PiG · 2004. Okt. 20. (Sze), 14.30
Az option elemek és stílusuk automatikus generálására írtam egy scriptet. Persze, azért, hogy egyszerű lehessen, na pont ezért lett bonyolult, meg persze minden eddigi megoldásnál hosszabb :-)
<script type="text/javascript">
elemek=new Array(
		new option('news.png','Hírek'),
		new option('cog.png','Karbantartás'),
		new option('important.png','Fontos'),
		new option('mozilla.png','Mozilla'),
		new option('firefox.png','Firefox')
		);
function option(icon,szoveg){
	this.icon=icon;
	this.szoveg=szoveg;
}
function createOptions(select, tomb){	
	selectElement=document.getElementById(select);
	for (var i=0;i<tomb.length;i++){
		option=document.createElement("OPTION");
		option.value=tomb[i];
		option.text=tomb[i].szoveg;
		option.style.backgroundImage="url(images/"+tomb[i].icon+");";
		selectElement.appendChild(option);
	}
}
</script>
...
head meg title meg a szokásos cucc
...
<body onload="createOptions('icon',elemek);">
<select name="icon" id="icon" size="3">
</select>
</body>
Mozillában néztem csak, nekem ment.
P][G
12

js minek

Jano · 2004. Okt. 20. (Sze), 14.35
Ez oktatasi cellal kivalo, de nem hizsem, hogy gyakorlatban ezt kene hasznalni a HTML+CSS megoldas helyett!

Viszont ezt mar nem nehez kiegesziteni, hogy IE-nek meg genaraljon linkeket egy DIV mezobe, ami linkekre kattintva egy eltuntetett selectben kivalsztjak a megfelelo erteket :)
13

Jobb ötlet

Bártházi András · 2004. Okt. 20. (Sze), 14.39
Egy jobb ötlet: olyan JS-t írni, ami végigmegy az oldal meglevő options elemein (mondjuk amelyeknél a select class tulajdonsága "imageselect"), s azokat bestílusozza (a name tulajdonság szerint rendel hozzá háttérképeket, s akár beállítja a stílust is nekik).

-boogie-
14

Közben ilyesmit agyaltam ki

PiG · 2004. Okt. 20. (Sze), 15.01
A style-ból kijöttek az option[value=akarmi] szabályok ,ezeket script generálja.
Egyébként naná, hogy oktatási céllal.
insertRule csak Mozillaban van IE-ban addRule kéne, de mivel az egész cuccos amúgy sem működik, ezért azzal külön nem szöszmötöltem

<!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">
<head>
<style type="text/css">
select {
	height: 144px;
	width: 200px;
}
option{
	height: 33px;
	padding-top: 15px;
	padding-left: 60px;
	text-align: left;
	background-repeat:no-repeat;
}
option:hover{
	background-color: #F0F8FF;
}
</style>
<script type="text/javascript">
ikonok=new Array("news.png","cog.png","important.png","mozilla.png","firefox.png");
var stiluslap = document.styleSheets[0];
for (var i=0;i<ikonok.length;i++){
	stiluslap.insertRule('OPTION[value="'+i+'"] {background-image:url(images/'+ikonok[i]+');}',stiluslap.cssRules.length);
}
</script>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2" />
<title>i</title>
</head>
<body>
<select name="icon" id="icon" size="3">
  <option value="0">Hírek</option>
  <option value="1">Karbantartás</option>
  <option value="2">Fontos</option>
  <option value="3">Mozilla</option>
  <option value="4">Firefox</option>
</select>
</body>
</html>
Ma délután aztán ráérek, mi?!
:-)
P][G
17

"don’t know what that means"

Anonymous · 2006. Júl. 31. (H), 19.25
http://www.maratz.com/links/

"Képválasztás listapanel segítségével - don’t know what that means, but it’s about styling select and option elements. The code is in english."

:)