CSS float problēmas un risinājumi

14.10.2007. 22:03:07 sagatavoja Deniss Fedotovs (deni2s)

Lai cik efektīva un noderīga mēdz būt elementu piesaistīšana pie cita elementa sāna (float), šie elementi mēdz būt diezgan viltīgi. Iespējams, ka esat redzējuši līdzīgu situāciju, kā 1.attēlā, kas ir izveidota tikai ar diviem <div> elementiem, katrs ar attēlu, kas ir piesaistīts pie kreisās malas.


1. attēls. Nav labi!
1. attēls. Nav labi!

Visdrīzāk, ka tas nav īsti tas, ko kodētājs bija iedomājies, taču ar izmantoto CSS kodu, šis ir korekts izklājums. Lūk, kā tas tika izveidots:

div.item {border: 1px solid; padding: 5px;}
div.item img {float: left; margin: 5px;}

Tas ir viss, kas nepieciešams. Rezultātā, tas, kas redzams 1.attēlā, notiek jo, <div> elementi „neizstiepjas”, lai aptvertu pie sāna piesaistītās bildes, kuras tajos ir iekļautas. Ja palūkojas uz situāciju no otras puses, tad tā notiek, jo piesaistītās bildes „lien ārā” no <div> elementu apakšas.

Tā nav kļūda. Tā arī nav CSS nepilnība. Patiesībā, pārsvarā gadījumu kodētāji vēlas tieši šo likumsakarību. Tikai piemērā, kas redzams 1.attēlā, tas nav tas, ko viņi vēlas.

Problēmas izprašana

Tātad, kad visa labā un pareizā vārdā, kodētāji vēlētos, lai pie sāna piesaistītais elements izvirzītos no elementa, kurā tas atrodas? Elementāri: vēsturiski visbiežāk pielietotajā CSS pazīmes (property) float izmantošanā. Pievērsiet uzmanību 2.attēlam un xHTML kodam, kas seko.

2.attēls. Bilde, kas piesaistīta teksta kreisajai pusei.
2.attēls. Bilde, kas piesaistīta teksta kreisajai pusei.

<p>
...teksts...
<img src="jul31-03-sm.jpg" height="200" width=”50” class="picture" alt=”Kalni” />
...teksts...
</p>
<p>
...teksts...
</p>

Šāda attēla ievietošana tekstam pa vidu tiek praktizēta jau kopš ļoti, ļoti seniem laikiem. Tāpēc šī iespēja tikai ieviesta tīmeklī sākot ar Netscape 1.1, un kāpēc CSS padara to iespējamu izmantojot CSS pazīmi float.[1] Taču palūkojieties uzmanīgāk uz 2.attēlu. Bilde lien ārā no elementa (<p>), kurā tā atrodas. Uzskatāmāk to var novērot, attēlojot malas rindkopām, kā parādīts 3.attēlā.

3.attēls. Rindkopu malas ir redzamas.
3.attēls. Rindkopu malas ir redzamas.

Tagad ir redzams, kāpēc ir būtiski, lai pie sāna piesaistītie elementi izvirzītos no elementiem, kuros tie atrodas. Ja tas tā nenotiktu, tad 2.attēlā redzamā situācija attēlotos kā 4.attēlā.

4.attēls. Ja piesaistītie elementi neizvirzītos no elementiem, kuros tie atrodas.
4.attēls. Ja piesaistītie elementi neizvirzītos no elementiem, kuros tie atrodas.

Tas ir tas, ko dizaineri nekad nepieļautu. Tātad, lai sekotu tīmekļa dizaina tradīcijām un tam, ko kodētāji sagaida, CSS ir veidots, lai ļautu piesaistītajiem elementiem izvirzīties no elementu apakšas, kuros tie atrodas. Lai gan tā ir nepieciešamība izmantojot piesaistīšanu pie teksta, šeit rodas liela problēma, kad piesaistītie elementi tiek izmantoti, lai veidotu lapas izklājumu (layout).

Clear risinājums

Ja piesaistītie elementi tiek izmantoti veidojot beztabulu izklājumus, tad ir nepieciešams atrast veidu, lai elementi, kuros tie atrodas izstieptos ap tiem. Pašlaik tam nepieciešams ir neliels strukturāls triks (hack). Tā kā mēs vēlamies, lai elementa, kurā atrodas piesaistītais elements, apakšējā mala atrastos tīri aiz piesaistītā elementa apakšējās malas, tad CSS parametrs clear ir mūsu risinājums. Mums nepieciešams ievietot block-level elementu tieši pirms saturošā elementa noslēguma, un pievienot tam CSS pazīmi clear. Ievērtējiet:

<div class="item">
<img src="w6144.gif" />
Widget 6144
<br />$39.95
<hr />
</div>
<div class="item">
<img src="w6145.gif" />
Widget 6145
<br />$44.95
<hr />
</div>

Tagad mums jāpielieto sekojošais CSS kods xHTML kodam, un jāiegūst rezultāts, kas attēlots 5.attēlā.

div.item hr 
{
display: block;
clear: left;
margin: -0.66em 0;
visibility: hidden
}

5.attēls. Horizontālās līnijas izmantošana elementa pastiepšanai.
5.attēls. Horizontālās līnijas izmantošana elementa pastiepšanai.

Pārliecinoties, ka <hr> elementi ir block-level, un tiem ir CSS pazīme clear, mēs piespiežam <div> elementus „aptvert” attēlus, kas ir piesaistīti kreisajam sānam.

Negatīvās augšējā un apakšējā maliņas (margins) ir nepieciešamas, lai noslēgtu atstarpi, ko aizņem <hr> elementi. Tomēr šis efekts nav precīzs un nedarbojas identiski uz visiem pārlūkiem. Elementa <hr> mistiskās dabas dēļ ir ļoti grūti iepriekš paredzēt, kā īsti tas attēlosies. Nepieciešamais <hr> elementa augstums varētu būt nulle, vai neliels pozitīvs skaitlis, vai pat negatīvs augstums.

Tāpēc situācijās, kur ir nepieciešama precizitāte, kodētāji var izmantot <div> elementu <hr> elementa vietā, lai panāktu attīrīšanas efektu. Piemēram:


div.clearer {clear: left; line-height: 0; height: 0}

<div class="item">
<img src="w6144.gif" />
Widget 6144
<br />$39.95
<div class="clearer">&nbsp;</div>
</div>

Float izmantošana float labošanai


Ir veids, lai izvairītos no pārliekas strukturālā trika izmantošanas, kurš tika apskatīts iepriekš, lai gan reizēm tomēr arī tas ir nepieciešams. Lielākajā daļā pārlūku, un kā tas ir definēts iekš CSS 2.1, elements ar CSS float parametru paplašināsies, lai aptvertu visus elementus ar CSS parametru float, kurus tas pats satur. Tātad mūsu piemērā mēs varētu izvākt visus <div class="clearer"> elementus un tā vietā pierakstīt šādu CSS kodu:

div.item {float: left; border: 1px solid; padding: 5px; width: 60%}
div.item img {float: left; margin: 5px}

Pievērsiet uzmanību, ka CSS float parametrs tika iedots gan bildēm, gan <div class="item"> elementiem. Norādot <div> elementu platumu lielāku par 50%, mēs nodrošinām, ka tie nekad nevarēs atrasties viens otram blakus, bet tā vietā atradīsies viens virs otra. Rezultāts ir attēlots 6.attēlā.

6.attēls. float parametra izmantošana problēmas risināšanai.
6.attēls. float parametra izmantošana problēmas risināšanai.

Šo acīmredzami ir vieglāk izmantot, gan HTML koda ziņā, gan CSS koda ziņā. Tomēr triks, kas tika apskatīts agrāk vēl aizvien var būt noderīgs. Iedomāsimies, ka ir nepieciešams pievienot nelielu papildus tekstu zem „items”. Lai teksts nesāktos no <div> elementu labās puses, mums jāizmanto iepriekš apskatītais „clear” triks. Kas mūs noved pie sekojoša koda, kura rezultāts ir attēlots 7.attēlā.

<div class="item">
<img src="w6144.gif" />
Widget 6144
<br />$39.95
</div>
<div class="item">
<img src="w6145.gif" />
Widget 6145
<br />$44.95
</div>
<div class="clearer">&nbsp;</div>
<p>Widgets are sold on an "as is" basis without
warranty or guarantee.</p>

7.attēls. Kombinējot risinājumus var iegūt vēlamo rezultātu.
7.attēls. Kombinējot risinājumus var iegūt vēlamo rezultātu.

<div class="clearer"> elements automātiski piespiež tam sekojošus elementus sākties no jaunas rindas, tātad zem <div class="item"> elementiem.

Iespējamā problēma, izmantojot piesaistītus sāniem elementus citos piesaistītos elementos, ir tas, ka jūs balstāties uz pārlūku korektu darbību. Šī situācija kļūst daudz trauslāka, ja šie piesaistītie elementi ir daļa no daudz sarežģītāka izklājuma, kurā iespējams arī tiek izmantota piesaistīšana pie sāniem, tabulas vai pozicionēšana. Neteiksim, ka šādus izklājumus nav iespējams veidot. Taču šādu izklājumu veidošana var veidot milzīgu mēģinājumu un kļūdu apjomu, lai izvairītos no nekorektas piesaistīšanas pie sāniem un citām izklājuma kļūdām, kas var rasties pārlūku CSS attēlošanas kļūdu dēļ.

Apkopojums

Izprotot, kā piesaistītie pie sāniem elementi un nepiesaistītie mijiedarbojas viens ar otru, un izprotot kā CSS parametrs clear var tikt izmantots, kodētāji var uzskatīt CSS parametru float par ļoti spēcīgu izklājumu veidošanas rīku. Tā kā šie elementi ar CSS parametru float sākotnēji nebija paredzēti izklājumu veidošanai, daži triki var būt nepieciešami, lai tie izkārtotos tā, kā tas ir ieplānots. Var iesaistīt pie sāniem piesaistītus elementus, kuri satur citus piesaistītus elementus, „attīrošos” elementus ar CSS parametru clear, vai izmantot abu šo triku kombināciju.

Skatoties nākotnē, ir ierosināti vairāki CSS uzlabojumi, kas ļautu kodētājiem norādīt, ka elementam vajadzētu izstiepties, lai saturētu sevī pilnībā visus sāniem piesaistītos elementus. Šīs noteikti būtu iekš CSS gaidītas iespējas, taču pašlaik izskatās, ka līdz šādu iespēju atbalstīšanai būs jāgaida ļoti ilgi.

[1] Termins „float” attiecināms uz veidu kādā elements tiek piesaistīts cita elementa sānam (vai apakšai), kā tas ir aprakstīts oriģinālajā „Addition to HTML 2.0” dokumentā, kas nāca līdzi Netscape 1.1 izlaidumam.

Raksta autors ir Eric A.Meyer, vispāratzīts CSS guru.
Raksts pārtulkots no complexspiral.com, kur tas tika publicēts 2003.gada 25.augustā.

3 komentāri Komentēšana pieejama visiem.
Jānis komentēja 15.10.2007. 00:27:14 (ip:77.93.26.68)
Komentāra reitings: 0

Šis tiešām ir noderīgi. Paldies.

Kārlis (kardinals@pelekais.lv) komentēja 15.10.2007. 10:27:34 (ip:89.248.83.209)
Komentāra reitings: 0.985

vienu lietu gan gribētos piebilst un palabot par meijera rakstā - div.clear nepalīdzēt ne line-height, ne height :0 uz IE. IE ir mūdzis, kas skatās font-size, līdz ar to klāt vēl vajag font-size: 1px;

`rolandinsh` (rolands@e-art.lv) komentēja 02.02.2008. 01:18:21 (ip:83.99.190.55)
Komentāra reitings: 0

Jā.. savulaik arī bija galvassāpes ar šo float problēmu... tagad (jau dažus gadus) ir iegājies automātiski rakstīt float:left, float:right un float:both.
Un domāju raksts noderīgs. Latviski, kā ne kā...

Komentāra pievienošana

Ar * atzīmētie lauciņi ir jāaizpilda obligāti.





[ uz rakstu sarakstu ]

Reklāma
Par web.hc.lv

web.hc.lv ir vortāls, kurā tiek aplūkoti mājaslapu veidošanas un mārketinga aspekti, no idejas līdz gandarījumam.

[Valid RSS] Valid XHTML 1.0! Valid CSS!

RSS 2.0 ziņu barotne (news feed)  Twitter

reģistrēties