| Kłopotliwe ramki |
|
|
|
| Wpisany przez Administrator | ||||
| Poniedziałek, 10 Listopad 2008 16:14 | ||||
Strona 1 z 2 W założeniach XHTML i CSS miały rozwiązać problemy z wyświetlaniem stron na różnych urządzeniach i przeglądarkach poprzez oddzielenie warstwy prezentacyjnej od ich treści. Ale tak się nie stało. Przeglądarki jeszcze nie do końca prawidłowo interpretują standardy, a już najgorzej radzi sobie z tym Internet Explorer: sporo osób używa jeszcze starszych jego wersji, które CSS interpretują źle albo wcale. Jak wygląda ramka w CSS? W 1996 r. konsorcjum W3C opublikowało specyfikację CSS, w której zaproponowano, aby każdy element na stronie (akapit, lista, nagłówek itp.) zamieszczany był w ramce. W jej skład wchodziła zawartość (content), dopełnienie (padding), krawędź (border) oraz margines (margin). Każdemu z tych elementów można przypisać wartość. Teoretycznie wydaje się to proste. Praktycznie model ramkowy może być kłopotliwy i nie zawsze można polegać na własnych odczuciach i wczesnych implementacjach. Na przykład, aby określić całkowitą szerokość ramki, należy zsumować wszystkie wartości. Jeżeli zawartość ma 300 pikseli, dopełnienie 25 pikseli z każdej strony, a krawędź 2 piksele, to całkowita szerokość wyniesie 354 piksele. Można sobie też zaplanować, że zawartość ma 67 proc. szerokości strony, rozmiar dopełnienia to 5em, a krawędź – 1 piksel. Ile wyniesie wtedy całkowita szerokość ramki? Dużo będzie zależało od szerokości okna przeglądarki i domyślnej wysokości tekstu. Co więcej, górne i dolne marginesy sąsiadujących elementów mogą się nakładać, a wartość szerokości nie ma znaczenia, jeśli ramka jest pusta. Rozwiązanie problemu z IE Niestety, przeglądarki Internet Explorer 6.0 używa na świecie i w Polsce całkiem spora grupa internautów. Kłopot natomiast polega na tym, że zaimplementowano tam inny, a więc błędny model ramkowy. Szerokość ramki jest bowiem ustalana wraz z dopełnieniem. W ten sposób IE w naszym przykładzie wyświetli zawartość w oknie o szerokości 246 pikseli (=300-50-4). Typowy zapis się nie sprawdzi – nawet prosta reguła ustalająca szerokość zawartości na 300 pikseli, krawędź na 20, a dopełnienie na 25 pikseli:
div.zawartosc { border: 20px solid; padding: 25px; width: 300px; }
W większości przeglądarek szerokość zostanie ustalona na 390 pikseli, natomiast w Internet Explorerze będzie ona miała 300 pikseli. Oszukajmy więc przeglądarkę:
div.zawartosc { border: 20px solid; padding: 25px; width: 390px; voice-family: "\"}\""; voice-family: inherit; width: 300px; }
Sztuczka działa w bardzo prosty sposób. IE przestanie przetwarzać regułę na komendzie voice-family, której nie potrafi obsłużyć. Inne przeglądarki otrzymają natomiast prawidłową wartość: 300 px. Jeżeli chcesz, aby użytkownicy starszych wersji Opery też nie mieli problemów, dopisz:
html>body .content { width: 300px; }
Ta reguła zadziała, ponieważ jest bardziej szczegółowa od pierwszej, więc będzie miała pierwszeństwo. Oczywiście nie trzeba takiego rozwiązania stosować, jeśli wartość dopełnienia i krawędzi jest ustalona na 0. Jeżeli bierzesz pod uwagę bardzo stare przeglądarki (IE w wersji 4.0 i starsze), to możesz użyć instrukcji @import, która spowoduje, że ukryjesz przed nimi CSS. Po prostu aplikacje te nie potrafią obsłużyć instrukcji. Nie trzeba więc stosować rozwidlenia kodu czy skryptu wykrywającego rodzaj przeglądarki. Błąd znaków odstępu w IE Teoretycznie te dwa fragmenty kodu powinny być równoważne: Praktycznie jednak nie. Błąd ten jest znany od czasów przeglądarki Netscape Navigator 3.0, a kiedy Microsoft postanowił stworzyć swoją, to skopiowano większość jej zachowań, w tym również błędne. Podobnie jest w Internet Explorerze 6. Jeśli strona jest źle wyświetlana, to należy usunąć znaki odstępu (spacje) i końca linii (enter). Taki kod jest znacznie trudniej modyfikować i czytać, ale nie ma innego wyboru. Ostatecznie można zaoszczędzić też kilka bajtów – często białe znaki usuwa się właśnie tylko w tym celu. Błąd właściwości float w IE 6.0 Właściwość float pozwala umieścić jeden element obok drugiego. Na przykład poniższa reguła umożliwia ustawienie elementu div o identyfikatorze zawartosc na lewo od paska bocznego czy innego elementu:
#zawartosc { float: left; }
Jednak Internet Explorer 6 zawiera błąd, który powoduje, że czasem długie fragmenty tekstu umieszczone w elementach pływających są obcinane i znikają paski przewijania. Aby to naprawić, internauta musi odświeżyć stronę lub dwa razy szybko wcisnąć klawisz F11. Problem ten dotyczy również małej liczby użytkowników. Mimo że został on zgłoszony w 2001 r., kiedy IE 6.0 był w fazie testowej, to i tak usterki nie naprawiono zbyt szybko. Prawdopodobnie Explorer zapamiętuje obliczone wartości na stronie. Dlatego jeśli na następnej pojawi się identyfikator o takiej samej nazwie, ale innej wartości, to może się zdarzyć, że wyświetlona zostanie pierwsza z nich. Odświeżenie strony pomaga więc tylko na chwilę. Tym razem pomocny będzie kod JavaScript przeliczający układ elementów:
if (document.all && window.attachEvent) window.attachEvent("onload, naprawIE); function naprawIE() { if (document.body.scrollHeight < document.all.zawartosc.offsetHeight) document.all.zawartosc.style.display = 'block'; }
gdzie zawartość oznacza identyfikator podwieszonego elementu. Innym sposobem jest unikanie właściwości float, ale to przy skomplikowanych układach strony może być czasem trudne.Znikające marginesy Kwestie wynikające stricte z błędów w interpretacji kodu przez przeglądarki to jedna strona medalu. Drugą jest sama specyfikacja CSS, definiująca zasady, jakimi silniki renderowania mają się kierować przy wyświetlaniu witryn. I nie chodzi tu o to, że programiści nie potrafią jej przełożyć poprawnie na kod przeglądarek, ale o problem z poprawnym ich zrozumieniem przez webmasterów. Prosty przykład: na stronie znajdują się dwa obszary blokowe, np. div (ale mogą być to także obrazki), umieszczone jeden pod drugim:
<body> <div class="gorny"> Tekst gornej ramki </div> <div class="dolny"> Tekst dolnej ramki </div> </body>
Nadana została im żądana kolorystyka, jednopikselowe obramowania i marginesy o szerokości 10 pikseli z każdej strony za pomocą następującego, poprawnego kodu CSS:
.gorny{ background: #E0E976; } .dolny{ background: #8791F2; } .gorny, .dolny { margin: 10px; padding: 3px; width: 200px; border: 1px solid red; }
I teraz prosta zagadka: jaka będzie pionowa odległość między obszarami? Pierwsza, naturalnie nasuwająca się odpowiedź brzmi: 20 pikseli – tyle wynosi bowiem suma marginesów wokół obu obszarów. Tymczasem po otwarciu strony w przeglądarce okazuje się, że jeden margines zniknął – między ramkami jest tylko 10 pikseli przerwy. Przy prostych layoutach różnica ta nie gra zwykle roli i często przechodzi niezauważona, jednak przy bardziej skomplikowanych designach graficznych, gdzie liczy się dopasowanie elementów co do piksela, może spowodować niespodziewane najście na siebie sąsiednich elementów. Rozwiązanie kwestii znikających marginesów jest wbrew pozorom proste, o ile przeanalizuje się specyfikację CSS. Zapadanie się marginesów (margin collapsing) jest typowym zachowaniem obiektów blokowych, umieszczanych na stronie w tzw. trybie normalnym. Przeglądarka, ustalając odległość między sąsiednimi obszarami, bierze pod uwagę po prostu większą z dwóch wartości zdefiniowanych w ich stylach. Czyli, jeśli górnej ramce nadany zostałby 15-pikselowy margines, a dolnej np. 5 px, efektywna odległość między nimi wyniosłaby 15, a nie 20 pikseli. Aby życie było trudniejsze, czasem liczona jest jednak po prostu suma odległości. Tak jest jednak tylko w przypadku, gdy jeden margines ma wartość dodatnią (10 px), a drugi ujemną, np. -5 px. Rezultatem tego będzie 5 pikseli odstępu między obiektami. Tego rodzaju triki wykorzystuje się często, gdy jeden obrazek ma częściowo zachodzić na drugi. W celu dalszego utrudnienia sprawy, przy obu marginesach ujemnych znów brany pod uwagę jest tylko ten o większej wartości bezwzględnej. Aby zmusić przeglądarkę do bezwzględnego respektowania explicite przypisanych wartości, wystarczy wstawić między oba obszary niewidoczny dla użytkownika element div, tzw. spacer, koniecznie ze znakiem niełamliwej spacji wewnątrz:
<div class="gorny"> ... </div> <div class="spacer"> </div> <div class="dolny"> ... </div>
po czym nadać mu taki styl: .spacer { clear: both; height: 0; margin: 0; }
Dzięki temu spacer będzie miał efektywny rozmiar równy zeru, czyli nie będzie widoczny, ale zmieni sposób liczenia odstępów przez przeglądarkę. Odstęp między górnym a dolnym blokiem będzie równy 10 px (obliczone jako margines między pierwszym divem a spacerem) plus 10 px (między spacerem a drugim obszarem), czyli 20 pikseli – poprawnie. Należy też pamiętać, że jeśli pozycjonowanie elementów wykonane zostanie metodą absolutną (atrybut position: absolute), marginesy nigdy nie będą się zapadać, więc żadne sztuczki nie będą potrzebne. Więcej szczegółów zawiera specyfikacja CSS2.1, dostępna pod adresem podanym w stopce. Gdzie mogą pojawić się problemy? Niestety, mimo że W3C ustaliło standard już dawno, to w chwili obecnej nie ma przeglądarki, która w pełni jest do nich dostosowana. Nawet HTML 3.2 nie jest w 100 proc. poprawnie zaimplementowany. Najbliżej ideału są najnowsze wersje Opery, Konquerora oraz Safari. Specyfikacja czasem jest bardzo ogólnikowa, a czasem zmienia się po jej publikacji. Przykładem może być współczynnik wielkości czcionek, który w pierwszej wersji był za duży. Wprawdzie zostało to już poprawione, ale Net- scape 4 używa wczesnej, niezbyt szczęśliwej specyfikacji. Kolejny kłopot dotyczy starych przeglądarek. Dlatego bez skrupułów możesz korzystać z technik, które pozwolą ci ominąć znane problemy. żródło:http://www.nextmag.pl/ |

Porady 

