Perfection or Vanity

Project: Terminated

Blog nie jest już dalej prowadzony ani aktualizowany. Mimo tego, wpisy i komentarze są dalej dostępne. Możesz przeczytać pożegnalny wpis albo przejść do archiwum.

Często stosowanym układem layoutu jest menu o stałej szerokości dostawione z jednej strony układu, tak aby druga kolumna dopasowywała się płynnie do pozostałej szerokości.

Ilustracja layoutu opisanego w poście

Standardowe rozwiązanie jest proste - umieścić w HTML menu (#sidebar) nad treścią (#content), ustawić szerokość oraz float - a temu drugiemu margines równy szerokości menu.

HTML:

  1. <div id="sidebar">
  2. </div>
  3. <div id="content">
  4. </div>

CSS:

  1. #sidebar {
  2. width: 200px;
  3. float: left;
  4. }
  5. #content {
  6. margin-left: 200px;
  7. }

Jednak ten sposób sprawia problemy. Jako, że umieszczamy kod menu nad zawartością:

  • zmuszamy gości do zobaczenia ładującego się menu przed resztą
  • musimy dodać link przeskoczenia nawigacji, inaczej się zaklika (klawiatury) albo ogłuchnie (czytniki)
  • spada wartość naszej strony dla wyszukiwarek

I tak dalej. Więc wrócmy do początku i zamieńmy kolejność. Dodatkowo na potrzeby nowego CSS-a należy dodać kolejny div do zawartości oraz otoczyć obydwa wrapperem (co zwykle i tak się czyni w prawie każdym układzie).

  1. <div id="wrapper">
  2. <div id="content">
  3. <div>…</div>
  4. </div>
  5. <div id="sidebar">
  6. </div>
  7. </div>

Wszystko teraz opiera się na sztuczce z marginesami.

  1. Najpierw floatujemy #content w prawo oraz ustawiamy mu szerokość równą 100%.

  2. Następnie odciągamy go w prawo za pomocą ujemnego marginesu równemu szerokości menu.

  3. A nowo wstawionemu divowi do #content dajemy taki sam margines, ale już dodatni.

  4. Na koniec wrapperem przycinamy całość za pomocą overflow: hidden.

  1. #sidebar {
  2. width: 200px;
  3. }
  4. #content {
  5. float: right;
  6. width: 100%;
  7. margin-right: -200px;
  8. }
  9. #content div {
  10. margin-right: 200px;
  11. }

Dla IE należy poprawić tylko błąd wynikający z niepoprawnego zaokrąglania wartości, który powoduje, że sidebar nie mieści się tam gdzie powinien być.

Jeśli chcemy być perfekcyjni w każdym pikselu, możemy w arkuszu dla IE dodać taki kod:

  1. html {
  2. overflow-x: hidden;
  3. }
  4. #wrapper {
  5. width: 100.5%;
  6. }
  7. #content {
  8. width: 99.5%;
  9. position: relative;
  10. left: -0.5%;
  11. }

Jeśli nie, zmniejszenie width wystarczy.

Demo.

Informacje i hiperłącza

Blog o projektowaniu zgodnych ze standardami stron internetowych.

Praktyczne przykłady, sztuczki CSS, sposoby obchodzenia błędów przeglądarek, lekki i nieinwazyjny JavaScript, użyteczny design, dostępność i skrypty użytkownika.

Informacje o wpisie

Napisał riddle 16 listopada 2006 o 01:29

Kategorie: CSS, Dostępność, HTML & Semantyka, Użyteczność

Dodaj do:

Wpisy archiwalne

Archiwum miesięczne

  1. Zanim mi się zbierze na refleksje na temat tej metody, zwrócę uwagę, że w drugim przykładzie html masz id divów w tej samej kolejności co wcześniej.

  2. Proszę jeszcze o nagłówek i stopkę.

  3. Poza tym fajne, podoba się. Jedyny problem to taki, że sam nie wiem czy bym wolał mieć w takim linksie menu na dole czy do góry. No i osobiście staram się ograniczyć liczbę divów na stronie.

  4. No tak, może i dobrze dla wyszukiwarek (chociaż nie do końca bym się zgodził, że to ma, aż takie znaczenie – chyba, że część przed treścią ma 50000 znaków) to jednak czytałem, że użytkownicy korzystający z alternatywnych narzędzi odbioru są przyzwyczajeni do nawigacji na górze strony. Skip linki i tak musimy dać na samej górze, czy dajemy wyżej content czy nawigacje.

  5. No właśnie. Bo otwierając jakiś serwis w linksie bardzo prawdopodobne, że szukam konkretnego działu i wolałbym się nie przebijać przez cały content, żeby dotrzeć do menu.

  6. Dla mnie trochę przekombinowane.
    IMHO dużo lepiej po prostu ustawić szerokość na sztywno i tak się pomęczyć z budową strony, aby działo w ten sposób.

  7. Szczerze powiedziawszy to w przypadku menu o stałej szerokości i stronie z width 100% lepszym rozwiązaniem wydaje mi się position absolute. No i w przypadku overflow hidden jest problem z rozwijalnymi menu nad wrapperem.

  8. Pala: O, faktycznie. Po prostu kopiowałem kod i zapomniałem zamienić.

    Dzięki za komentarze. :-)

  9. Ja lubię robić tak, że w kodzie strony menu jest oczywiście za treścią. I mniejwięcej takie style: #menu {position:absolute; top:0; left:0; width:100px;} #content {margin-left:100px; min-height:xxx} (i oczywiście dla IE zamiast min-height, zwykłe height)

    Do flotowania mam jeszcze z początków mojej nauki kodowania dość... nieciekawy stosunek. To taka moja trauma :D

  10. @harp: Ale jeśli użyjesz position: absolute strasznie się namęczysz dodając do tego stopkę. A dzięki pływaniu, stopka otrzyma clear: both i po kłopocie.

  11. @lato_p: dodanie stopki do tego co ja pokazałem to banał. Wystarczy ją umieścić po treści w kodzie strony i nawet jej nie musisz ostylować.

  12. To teraz Reinmarze powiedz co się stanie, jak sidebar będzie dłuższy niż content (a zdarza się tak, zdarza). Bo ja już chyba wiem. ;-)

    Oczywiście można stosować takie zabiegi jak Absolute Clearance, ale to już hak po prostu. ;]

  13. Jasne – wszystko się może zdarzyć, ale jakoś nigdy mi się nic aż tak nie wydłużyło niezaplanowanie, żeby wylecieć poza ekran. Odpowiednio duża minimalna wysokość bloku #content i w 99,(9)% działa, a kod jest najprostszy i moim zdaniem najniezawodniejszy.

  14. Reinmar: Rozumiem, że przewidziałeś, że mogę sobie powiększać czcionkę?

  15. Pala: Wystarczy określić min-height w em.

  16. Nie do końca rozumiem po co, ale Reinmar chyba tego nie stosuje

  17. @Pala; no właśnie napisałem – min-height:xxx co miało znaczyć, że w dowolnych jednostkach dowolna wartość. A jednostki em się tutaj nadają, bo kiedy powiększasz litery (ctrl + ‘+’), to wszystko co jest w jednostkach em też się powiększa ;).

  18. (Komentarz zmodyfikowany 22.11.2006 o 14:36)

    A nie lepiej tak:

    <!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=„pl” >
        <head>
            <title></title>
            <style type=„text/css” media=„all”>
                #page{margin-left:200px}
                #content{background-color:red;width:100%;float:left}
                #menu{background-color:green;width:190px;margin-left:-200px;float;left}
            </style>
        </head>
        <body>
            <div id=„page”>
                <div id=„content”>
                    content
                </div>
                <div id=„menu”>
                    menu
                </div>
            </div>
    
        </body>
    </html>
  19. Riddle’owe demo ma jedną bardzo niefajną właściwość:
    po zmniejszeniu okienka przeglądarki zawartość nam gdzieś ucieka… nie ma nawet scrolli…

  20. zuut@onet.eu 20 04 grudnia 2006, 20:21

    no dobra
    ale czy nie prościej użyć <table> 2 kolumny
    albo lepiej tables nested
    jedna na 100% wight
    a w niej druga sztywna na 200 pix wight fix

    natomiast spellbound jest tylko w en-US
    i na dodatek do wcześniejszej wersji Firefoxa

  21. wzs: Bo nie bawiłem się w to dłużej. Należy wyclearować kontener i wtedy będzie już ok.

    Gurthg: Chyba nie działa w IE (ale to może wina zakrąglania i przekroczenia 100%)

  22. mike_mech 22 02 lutego 2007, 09:04

    „spada wartość naszej strony dla wyszukiwarek” – Nieprawda. Zawartość dokumentu (treść oraz jej kolejność pojawiania się w dokumencie) nie ma najmniejszego znaczenia dla wyszukiwarek.
    Mit ten obalił niedawno Google, odbierając zwolennikom XHTML’a odbiera niestety jeden z argumentów.

  23. Hmm… źródło? :-)

  24. A to ?

  25. A czy tak mogę zrobić?
    CSS:
    #obraz { width: 100px; } #info{ float: right; width: 100%; margin-right: -200px; margin-top: -150px; }
    HTML:
    <div id="obraz"> … </div> <div id="info"> … </div>

    Wszystko jest umieszczone w jeszcze jednym div’ie (wpisy w WordPress, a konkretnie w miejscu pokazywania wpisu, tzn. w tym div’ie odpowiadającym za to).
    Pozdrawiam! :)