Méretezhető CSS doboz készítése: 9-slice CSS Box

A feladat olyan méretezhető CSS Box/Panel készítése, ami:

– scriptmentes
– a kerete rugalmasan paraméterezhető
– a magassága lehet fix méretű vagy tartalomhoz igazodó
– a felhasznált képek mérete legyen minimális
– pixelpontosan legyen tervezhető, felhasználható
– valid CSS/(X)HTML
– táblázatmentes megoldás legyen (tableless)
– böngészőfüggetlenség (ie6, ie7, ff2, ff3, safari3, opera9, chrome)

A végeredményt itt megnézheted, a leírás végén pedig letöltheted az összes szükséges kódot és képet becsomagolva, egy öszetettebb példával együtt.

1. Miért kellene nekünk változtatható méretű panel?

Ha van egy panelgrafikánk, akkor azt a HTML kódban leegyszerűsítve az alábbiak szerint tudjuk felhasználni:

1.1 Az eredeti méretben illesztjük be a weboldal tartalmába, ekkor azonban nagyon korlátozottak a lehetőségeink. Esetleg elkészíthetjük a panelgrafikát több méretben, de ekkor egyrészt megnő a weboldalon felhasznált képek háttértár igénye, másrészt nem tudjuk felhasználni dinamikus szövegek kereteként (dinamikus szöveg alatt olyan szöveget értek, aminek nem tudjuk előre pontosan a hosszát, ami változhat, jó példa erre az adatbázisból vett szöveg), hiszen előre megadott méretekben készítjük el.

1.2 Átméretezzük a kellő nagyságúra, ebben az esetben viszont a panel sarkai, a fejléc magassága, az oldalszegélyek nyúlnak-zsugorodnak, ami nem elfogadható megoldás:

Egy normál panel megnyújtott, torz képe
1. ábra - Egy normál panel megnyújtott, torz képe

1.3 Különválasztjuk a sarkokat és az oldalkeretet, hiszen ha a 4 sarok grafikáját állandó nagyságban a panel 4 sarkába helyezzük, az oldalakat alkotó grafikát nyugodtan megnyújthatjuk, a panel képe nem torzul el. Vagyis annyi a feladat, hogy készítsünk egy olyan “dobozt”, aminek a sarkaiba betesszük a sarokgrafikákat, az oldalaihoz pedig hozzáadjuk az oldalgrafikákat, csak éppen az aktuális méretre nyújtva.

Összefoglalva, ha dinamikus szövegeket akarunk megjeleníteni, vagy nem akarjuk folyamatosan minden méretben elkészíteni a panelgrafikáinkat, akkor a méretezhető CSS Box-ra van szükségünk.

2. A grafika létrehozása

2.1 Rajzoljunk egy panelgrafikát (itt találsz egy ragyogó tutoriált) én ezt készítettem:

CSS Box
2. ábra - CSS Box

2.2 Daraboljuk szét az alábbi módon (jelen esetben nekünk 8 db-ra lesz szükségünk):

CSS Box darabolása
3. ábra - CSS Box darabolása

A 4 sarokban lévő grafika állandó nagyságú lesz (ez természetesen állítható a css-ben különböző nagyságú képek esetén):

– corner_tl.gif (corner-top-left):

– corner_tr.gif (corner-top-right):

– corner_bl.gif (corner-bottom-left):

– corner_br.gif (corner-bottom-right):

A CSS Box oldalainak grafikáit pedig majd “megnyújtjuk” akkorára, amekkora a CSS Box aktuális oldalhosszúsága és oldalszélessége. A “megnyújtjuk” azért került idézőjelbe, mert valójában csak annyiszor rakjuk majd egymás mellé, amíg el nem éri a kívánt hosszt, vagyis nem nyújtjuk, hanem ismételjük:

– border_t.gif (border-top):

– border_r.gif (border-right):

– border_b.gif (border-bottom):

– border_l.gif (border-left):

A grafikával meg is vagyunk, jöhet a kódolás.

3. A CSS létrehozása

3.1 A tartalmat (content) vegyük körbe a fent látható képelemekkel értelemszerűen úgy, hogy a 4 sarok a sarkokba kerüljön fix méretben, az oldalsó elemeket pedig “nyújtsuk” meg akkorára, amekkora a CSS Box oldalhosszúsága.

A képeket 1-1 < div> elem háttérképeként tudjuk majd megjeleníteni. Egy dobozban (div tartományban) egyszerre csak 1 háttérképet tudunk megadni, amit többféle módon pozícionálhatunk (a doboz jobb vagy bal oldalára kerüljön, alulra vagy felülre, fix méretben ismétlés nélkül, vagy többszörözzük meg x-tengely, esetleg y-tengely irányában). A képeket tartalmazó < div> elemek elhelyezésére megannyi lehetőségünk adódik, én nagyrészt az ie6 box-model kezelése miatt az alábbi struktúrát választottam:

A CSS Box felépítése egymás feletti rétegekben megjelenítve
4. ábra - A CSS Box felépítése

Így pixelpontos megjelenítésre van lehetőségünk a fent említett böngészők mindegyikében.

Jöhet a kódolás.

3.2 CSS Box-hoz a példában Eric Meyer reset CSS-ét használom (background: transparent; kikommentezésével ie6 miatt) a böngészők alapbeállításainak felülírására, ezt a mellékletben megtalálod, erre nem térek ki külön. A másik css állományunkban hozzuk létre az osztálydefinícióinkat a fenti ábra szellemében:

1
2
3
4
.menu_container {
  width: 	300px; /* A CSS Box szélessége, tetszőlegesen állítható */
  background:	url(img/border_l.gif) repeat-y left; /* Bal oldali keret képe */
}

Megadjuk a .menu_container osztály szélességét, majd hozzárendeljük a CSS Box keretének bal oldali grafikáját (border_l.gif), amit “megnyújtunk” függőleges irányba (y-tengely mentén).

A többi oldallal hasonlóképpen járunk el:

1
2
3
4
5
6
7
8
9
10
11
12
13
.border_right {
  background:	url(img/border_r.gif) repeat-y right; /* Jobb oldali keret képe */
}
 
.border_top {
  height:	55px;
  background:	url(img/border_t.gif) repeat-x top; /* Felső keret képe */
}
 
.border_bottom {
  height:	25px;
  background:	url(img/border_b.gif) repeat-x bottom; /* Alsó keret képe */
}

Ezután a CSS Box sarkaiban elhelyezkedő képek osztályai jönnek jobbra illetve balra úsztatva (float: left, float: right).

A 4. ábra szemlélteti, hogy a .corner_top_left és a .corner_top_right osztályok majd a .border_top osztályba lesznek beágyazva, az alsó két sarok hasonlóképpen a .border_bottom-ban foglal majd helyet.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
.corner_top_left { /* Jobb felső sarok képe  */
  float: 	left;
  width: 	21px;
  height: 	55px;
  background:	url(img/corner_tl.gif) no-repeat left top;
}
 
.corner_top_right { /* Bal felső sarok képe */
  float: 	right;
  width: 	21px;
  height: 	55px;
  background:	url(img/corner_tr.gif) no-repeat right top;
}
 
.corner_bottom_left { /* Bal alsó  sarok képe  */
  float: 	left;
  width: 	21px;
  height: 	25px;
  background:	url(img/corner_bl.gif) no-repeat left bottom;
}
 
.corner_bottom_right { /* Jobb alsó  sarok képe  */
  float: 	right;
  width: 	21px;
  height: 	25px;
  background:	url(img/corner_br.gif) no-repeat right bottom;
}

Már csak a fejléc és a tartalom szövegének formázása van hátra:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.header_text {
  padding: 	9px 21px 0px 21px; /* A szöveg igazításánál figyelembe vesszük a corner_top_left és corner_top_right szélességét */
  color: 	#fff;
  font-family:	Arial, Times, serif;
  font-size:	1.2em;
  text-align:	center;
}
 
.content {
  position: 	relative;
  margin: 	0px 21px 0px 21px; /* A szöveg igazításánál figyelembe vesszük a menu_container jobb és bal oldali keretének szélességét */
  padding: 	10px;
  color: 	#555;
  font-family:	Arial, Times, serif;
  line-height:	1.3em;
}

4. Az XHTML kód

Felépítjük 4. ábrán látott struktúrát, magyarázatok a kommentekben:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 
<!--
*******************************************************
*	CSS Box tutorial
*	Made by: ViziUbi
*	Date: 2008.12.09
*	Tutorial: http://www.tutorial.hu/meretezheto-css-doboz-keszitese/
*	Email: viziubi@gmail.com
*	GNU GENERAL PUBLIC LICENSE
*******************************************************
-->
 
<head>
	<title>CSS Box tutorial</title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<link rel="stylesheet" type="text/css" href="reset.css" media="all" /> <!-- Stíluslapok elérésének deklarálása -->
	<link rel="stylesheet" type="text/css" href="box_style.css" media="all" />
</head>
 
<body>
	<div class="menu_container">
		<div class="border_right">
			<!-- A CSS Box border_top doboza a felső sarkak képeivel -->
			<div class="border_top">
				<div class="corner_top_left"></div><div class="corner_top_right"></div> <!-- A CSS Box felső két sarkának grafikája -->
				<div class="header_text"> <!-- A CSS Box címsora -->
					Header
				</div>  
			</div>
			<!-- A CSS Box középső (content) doboza -->
			<div class="content"> <!-- A CSS Box tartalma -->
				<p>Vitae nostro appetere ne mea, id ferri augue sea, clita appareat eu vix. In est choro nusquam eligendi, sea ut malorum bonorum sensibus. Has ne atomorum facilisis prodesset, vim in ponderum perfecto, cu dicit vocent torquatos sea. Ea mel iusto dolorum admodum, ei omnes tantas persecuti cum. Ei tation iriure sapientem has, ea regione posidonium vim, quas reque labores in mei. Odio adipisci scripserit qui no, nobis legere liberavisse mel ex. Ei qui solum explicari concludaturque, consul dolorem argumentum sea ea, ex per minim viris omittam.</p>
			</div>
			<!-- A CSS Box border_bottom doboza az alsó sarkak képeivel -->
			<div class="border_bottom">
				<div class="corner_bottom_left"></div><div class="corner_bottom_right"></div> <!-- A CSS Box alsó két sarkának grafikája -->
			</div>
 
		</div>	
	</div> <!-- end menu _container -->
</body>
</html>

5. Letölthető állományok

5.1 CSS Box letöltése (XHTML, CSS, képek ~ 8.2 kb)

5.2 CSS Box letöltése öszetettebb példával (XHTML, CSS, képek ~ 27.4 kb)

5.3 Csak a képek letöltése (~ 5.3 kb)

Bónusz: A CSS Box ie5.01 és ie5.5 alatt is működik.

Jó szórakozást!

10 HOZZÁSZÓLÁS

  1. Szép megoldás! Esetleg a header_text div helyett lehet a doboz funkciójától függően címsor elemet használni (h1, h2, stb.), illetve a content részben a szöveget p elembe rakni és akkor még szemantikus is a kód. :-) Ja és egy per jel lemaradt a Content-Type meta végéről a validsághoz.

  2. Köszönöm az észrevételeket, a címsort az olvasóra bízom, a másik kettőt javítottam a forrásállományokban.

  3. Ragyogó tutorial, bár maximálisan akkor lennék elégedett, ha gif-ek helyett png-t használnál, bár ez csak mentés kérdése…

  4. Még egy apróság, ami hasznos lehet: jelen esetben, ha a tartalomban van “float”-olt kép (balra, vagy jobbra rendezett) és az magasabb, mint a mellette elhelyezkedő szövegtörzs, akkor szétcsúszik a box. Ezt az alábbi kód css-be való beszúrásával meg lehet oldani (kivéve IE6, mert az sajnos nem ismeri a pszeudo elemeket):

    7
    8
    9
    10
    11
    12
    13
    
    .content:after {
    clear:both;
    content:".";
    display:block;
    height:0;
    visibility:hidden;
    }
  5. Köszönöm Fotel neked is az észrevételeket. A GIF kontra PNG kérdésen természetesen én is gondolkodtam, s az alábbiak miatt maradtam a gif melett:

    1. Az ie6 nem minden esetben kezeli megfelelően a PNG kiterjesztésű képeket (nem csak abban az esetben, ha van átlátszó része), és ugyan használható hozzá a

    filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=”image.png”)

    szűrő, amit * html hack-el meg lehet adni ie6 számára (ahogy azt a következő tutoriálomban be is mutatom), de jelen esetben a lehető leginkább hack-mentes és ie6 alatt mindenképp működő kialakítás volt az elsőrendű szempont.

    2. Az elkészült GIF és PNG képeket (már csak a kíváncsiság miatt is) pixelről pixelre összehasonlítottam, és jelen esetben pixelenként tökéletesen ugyanazt tárolták el, csak a PNG fájl valamivel nagyobb volt.

    Nos ezek után maradt a GIF. Te mit választanál?

    A második felvetéseddel kapcsolatban pedig fontos az alábbiakat megjegyeznem:
    A cél egy végtelenségig lecsupaszított, bug mentes, böngészőfüggetlen, (stb. lásd fenn) váz volt, ami stabil kiindulási alapot adhat a bemutatott panelek felépítéséhez. Természetesen az általad említett igény többféleképp megoldható még pszeudo elemek felhasználása nélkül böngészőfüggetlen módon is (pl úgy, hogy nem “float”-olod a képet, hanem background-nak adod a content-ben, tetszés szerint jobbra vagy balra igazítva s a mellé kerülő szöveget akár teheted külön div-be is a megfelelő margin és padding beállításokkal, de akár tetszés szerninti div-ekre is feloszthatod a content részt, használhatod ezt a megoldást is az egyenlő oszlopmagasságokra: http://www.alistapart.com/articles/holygrail ). Vagyis a speciális igényekhez természetesen testre kell szabni, de ha minden felmerülő kérdésre megpróbáltam volna “felturbózni” a kódot, akkor azt Te is tudod, hogy sokkalta hosszabb és bonyolultabb szerkezetet eredményezett volna, és a tutoriál pont a lényegét vesztette volna el.

    Mindenesetre köszönöm a többiek nevében is a tesztelést és bemutatott lehetséges megoldást.

    ViziUbi

  6. Hi. Megcsináltam a tutorialt lépésről lépésre és az az egy problémám van, h a szövegdoboz átlátszó. Html be ágyazva használom és van hátterem, így a szöveg nem látszik rendesen. biztosan lehet neki színt adni valahogyan, de nem találtam a kódban.

  7. Foxy, ahogy az előző válaszomban is írtam, ez csak egy csupasz váz, mindazonáltal ha letöltöd az 5.2-es állományt és megnézed annak css-ét (box_examlpe_style.css) akkor abban megtalálod a megoldást a problémádra. Az “összetettebb példában” (box_tutorial_example.html) a content és content2 doboz háttérszíne a .bg_kek és a .bg_piros osztályokkal van megoldva, így nem lesz átlátszó a szövegdoboz háttere és tetszőleges háttérszínt adhatsz neki, ha elakadnál írj nyugodtan.

  8. wolf: van még pár feltöltve, de vmiért még nem kerültek ki az oldalra.
    Ha van konkrét 5leted, h mit látnál szívesen, akkor azt is megoszthatod velünk. Én is időhiányban szenvedek, ezért nem tudtam elkészíteni és feltölteni újabbat.

HOZZÁSZÓLOK A CIKKHEZ

Kérjük, írja be véleményét!
írja be ide nevét