Ankündigung

Einklappen
Keine Ankündigung bisher.

4,39: Von ausgezeichneten DIV-Süppchen und anderen Spezialitäten

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • 4,39: Von ausgezeichneten DIV-Süppchen und anderen Spezialitäten

    4,39:

    Nachdem wir uns in Kalendertürchen 2,32 angesehen haben, wie wir jQuery durch die Verwendung von class-Attributen flexibler und näher am Schichtenkonzept einsetzen können, soll das heutige Türchen diese Klassen einmal näher beleuchten.

    Gerade im Bereich CSS fällt es dem Webentwickler schwer, eine konsequente Linie zu fahren. Da ist zum einen das Vererbungsprinzip, das bei unsachgemäßer Anwendung Eigenschaften bis in die Tiefe des Dokumentbaums transportiert, zum Zweiten verführt die einfache Handhabung von CSS zum schnellen Bugfixing von Anzeigeproblemen und schließlich findet sich der Designer noch in den Untiefen der Browser-Hacks wieder.

    All dies führt zu einer Fragmentierung von CSS und HTML - Klassen werden ergänzt, benamt nach Gusto oder aktuellem Einsatzzweck, spezifische CSS-Eigenschaften werden notiert, um Seiteneffekten vorzubeugen. Gegenmaßnahmen sind Layoutumsetzung an definierten Strukturmustern, wie es bereits das erwähnte Konzept OO-CSS, aber auch Fertiglösungen wie YAML oder Gridsysteme liefern.

    Viele Individualisten bauen Ihre Seiten jedoch noch vom Doctype an selbst und sollen hier ein paar Vorschläge erhalten.

    1. (Bau)kastenlayout

    Layouts werden komplexer - eben weil es geht - und der semantikbewußte Webdesigner hat das Nachsehen. Die berühmte DIV-Suppe entsteht. Die erste Maßnahme muss also erstmal sein, das DOM so weit wie möglich zu entschlacken bzw. redundanzfrei aufzubauen (was zugegeben etwas Erfahrung voraussetzt). So starten wir bei unseren konkreten Inhalten und Seitenelementen und arbeiten uns dann nach außen vor. Vor allem Eye-Candy wie Schlagschatten, runden Ecken und Seitenzentrierung sollte also erstmal strukturell alles ausgezeichnet werden. Hilfestellung kann uns dabei das WAI-ARIA bieten, das bereits wesentliche Elemente wie document, main oder navigation als Role definiert. Ein Blick in die Spezifikation lohnt sich. Damit haben wir bereits unsere wichtigsten Elemente, die via CSS das Seitenaussehen definieren. Zum Ansprechen der Elemente lassen sich hier fast ausnehmlich IDs verwenden, für gemeinsame Funktionalität empfielt sich, zusätzlich eine Klasse zu vergeben. Solche Gemeinsamkeiten können funktional sein (wie bspw. gleiche top-margin-Angaben mehrerer gefloateter Spalten) oder semantisch (wie z.B. mehrere Navigationsbereiche mit der Klasse Navigation auszuzeichnen). Natürlich dient auch diese Semantik später zur Definition von gemeinsamen Aussehen oder Verhalten (Hover-Effekte oder dergl.).

    2. Helper und struktur-semantische Wrapper

    Ganz ohne Helper funktioniert CSS nicht. Das liegt an der mangelnden Unterstützung von modernen CSS-Angaben oder diversen Browserbugs. Auch eine Zentrierung der Seite, die Aufhebung von Floatings oder der Textausrichtung kann durch „Wrapper-Elemente“ erreicht werden.

    Einer der wichtigsten Wrapper behebt den Box-Model-Bug des Internetexplorer. Für einen Inhaltscontainer definiert er den padding-Wert über den margin eines zusätzlichen inneren Hilfscontainers. Aber auch ohne IE kann das nötig werden, bspw. wenn noch eine feste Breitenangabe ins Spiel kommt und verschiedene Maßeinheiten wie Pixel und em zu Grunde liegen. Bisher fehlende Berechnungsmöglichkeiten bieten uns hier keine Möglichkeit, direkt pixelgenau zu arbeiten.

    Auch Elemente der inneren Inhaltsstrukturen, die bspw. farbige oder gerahmte Infoboxen bilden, Bilder und Bildunterschriften gruppieren oder die ul-Elemente von Aufzählungslisten kann man in diese zweite Kategorie einordnen.

    3. Flags

    Als Flags bezeichne ich Eigenschaften, die mit solchen in der Objektorientierung verglichen werden können. „Ein Element ist…“ könnte man sagen. Einige typische (und nützliche) Flags werden durch die CSS-Pseudoselektoren vorgegeben. Solange nicht alle Browser diese vollumfänglich unterstützen, kann es sinnvoll sein, benötigte Funktionalitäten durch Markup oder Javascript zusätzlich abzubilden und doppelt anzulegen:

    PHP-Code:
    #MainNavi li:hover ,
    #MainNavi li.hover {
      
    background #f00;
    }

    #ContactForm input:focus ,
    #ContactForm input.focus {
      
    border 2px solid #0b0;
    }

    #Content p:first-child ,
    #Content p.first {
      
    margin-top 0;

    Natürlich müssen die Klassen dann im HTML ausgezeichnet werden, bspw. durch PHP oder nachträglich über Javascript.

    Typische Flags haben wir auch im Kalendertürchen bei unserer Toggle-Funktion kennengelernt.

    Achten sollte man auf eine semantische Auszeichnung. So sollte man bspw. bei einer fehlgeschlagenen Validierung die invaliden Elemente eben auch mit .invalid auszeichnen, statt mit .red oder ähnlichem. Auch unser CSS soll flexibel bleiben, denn nichts ist unübersichtlicher als das:

    PHP-Code:
    #myForm input.red {
      
    background   #ddd url(invalid.jpg) 0 0 no-repeat;
      
    padding-left 14px;

    Offensichtlich wurde die frühere „rote“ Auszeichnung hier gegen eine andere Fehlermarkierung ausgetauscht.


    Ein kleines Gesamtbeispiel
    PHP-Code:
    <html>
      <
    head>
        <
    title></title>
        <
    style media="screen">

          
    /* gehört ins Reset-Stylesheet */

          
    {
            
    margin 0 0 1em 0;
          }


          
    /* Basis-Layout */

          #Page {
            
    float left;
            
    width 50em
          }

          
    #InfoSidebar {
            
    float left;
            
    width 10em;
          }

          
    #MainContent {
            
    width       40em;
            
    margin-left 10em;
          }



          
    /* Hilfscontainer: Rahmen für Boxes mit fester Breite */ 

          #MainContent .hlp-FixedWidthBorder {
            
    border      4px solid #000;
            
    margin-top  : -4px;
          }

          
    /* Gemeinsames Padding aller Boxes */ 

          
    .Content .hlp-InnerPadding {
            
    padding     2em 0.4em 0.4em 0.4em
          }

          
    /* Individuelles Padding */ 

          #MainContent .hlp-InnerPadding {
            
    padding-left  1em
            
    padding-right 1em
          }


          
    /* kein hlp-FixedWidthBorder, weil semantische Bedeutung */

          #InfoSidebar .InfoBox {
            
    border      1px solid #000;
            
    background  #fff;
          
    }

          
    #InfoSidebar .InfoBox p { 
            
    margin      4px 4px 1em 4px;
          }


          
    #InfoSidebar .InfoBox p.last , /* Fallback */
          #InfoSidebar .InfoBox p:last-child {
            
    margin-bottom 4px;
          }


          
    /* nur zur Illustration des Beispiels */

          #Page {
            
    background #bbb;
            
    height     500px;
          }

          
    #InfoSidebar {
            
    background #f00;
          
    }

          
    #MainContent {
            
    background #ff0;
          
    }

        </
    style>
      </
    head>
      <
    body role="document">
        <
    div id="Page">
        
          <
    div id="InfoSidebar" class="Content" role="complementary">
            <
    div class="hlp-InnerPadding">
              <
    p>Hier steht Inhalt</p>
              <
    div class="InfoBox">
                <
    p>Infos</p>
                <
    class="last">Infos</p>
              </
    div>
            </
    div>
          </
    div>
          
          <
    div id="MainContent" class="Content" role="main">
            <
    div class="hlp-FixedWidthBorder hlp-InnerPadding">
              <
    p>Hier steht Inhalt</p>
              <
    p>Hier steht mehr Inhalt</p>
            </
    div>
          </
    div>
          
        </
    div>
      </
    body>
    </
    html
    4. Javascript-Selektoren

    JQuery macht es ja sehr einfach, bestimmt DOM-Elemente über Ihre ID, Ihr name-Attribut oder eine Klasse anzusprechen. Im Hinblick auf das früher erwähnte Schichtenmodell ist es eine gute Idee, generell eine eigene Klasse pro Funktionalität zu benutzen. Damit laufen wir nicht Gefahr, unsere Funktionalität an eine bestimmte Struktur zu binden, die sich im Laufe der Zeit vielleicht ändert und unser Javascript nicht mehr wiederverwendbar macht. Generell ist es eine gute Idee, das Script so allgemein und konfigurierbar wie möglich zu machen und möglichst wenige Konventionen hinsichtlich der benötigten Elementstruktur einzugehen. Eine solche Konvention könnte z.B. sein, dass in einem Klappmenü der umzuschaltende Inhalt stets auf den schaltenden Link folgt. Näher betrachtet ist diese Regel aber sehr wenig zukunftsgewand und kann viel besser mit einigen spezifischen Klassen abgebildet werden, z.B.

    - eine Klasse, über die der schaltende Link mit seinem Event versehen wird *)
    - eine Klasse, über die der zu schaltende Inhalt angesprochen wird *)
    - eine Klasse, über die ein Wrapperelement bestimmt wird, das beide Elemente miteinander verbindet.

    *) können auch mehrere Elemente sein

    Auf diese Weise lässt sich der Schalter mehrfach verwenden, ohne dass bspw. für jede Aktion eigene Bezeichner verwendet werden müssen. Ein Beispiel gabs in Türchen 2,32 zu sehen.

    Faustregel: Dient zur Strukturierung der Javascript-Funktionalität (JS-Semantik)

    5. Javascript-dynamische Flags und Hilfselemente

    Viele Javascript-UI-Funktionen benutzen zusätzliche, dynamisch generierte DOM-Helper oder zustandsbasiert existierende Klassenattribute. Hier muss abgewogen werden, ob eigene CSS Settings für den dynamischen Bereich verwendet werden sollen oder statische (Nicht-JS) und dynamische Seite CSS-Settings teilen sollen. Hier befindet sich die „Schnittstelle“ zwischen den Schichten, die früher schon einmal angesprochen wurde. Auch bspw. eine PHP-seitige Anbindung könnte hier erfolgen (vordefinierter/Fallback-Zustand o.ä.). Soweit möglich sollten solche Informationen aber besser in der .data-Eigenschaft der beteiligten DOM-Elemente abgelegt werden.

    Natürlich dienen Flags hier auch zur Selektierung, gerade für Hilfselemente sind die Grenzen hier fließend.

    Faustregel: Dient als Interface zum CSS oder server-dynamischen Sprachen

    JS-only-Klassen sollte man sinnvollerweise speziell auszeichnen, z.B. durch ein Präfix wie „js-“. Die unter 4) und 5) genannten Elemente kann man ähnlich wie die unter 2) und 3) genannten charakterisieren:


    Charakterisierung und „Namespaces“

    1. Basislayout

    - ID (nur Einmal-Elemente wie „Page“) oder class-Attribut
    - Großschreibung / CamelCase
    - semantische Auszeichnung als Substantiv
    - kann sich an WAI-ARIA-Roles (Document Structure und Landmarks) orientieren

    Beispiele:

    #Page
    #MainContent
    #MainNavigation
    .Navigation
    .Content

    2. Hilfselemente und Wrapper

    - class-Attribut
    - Großschreibung / CamelCase
    - semantische Auszeichnung als Substantiv
    - ggf. Präfix, wie „hlp-“ oder „wrp-“
    - allgemeine Auszeichnung enthält Gemeinsamkeiten aller Elemente
    - Auszeichnung in Verbindung mit spezifischem Elternelement die Abweichungen davon

    Beispiele:

    .hlp-InnerPadding
    .wrp-PageCenter
    .wrp-PageFloating
    .layoutWrp-Shadow.Bottom
    .layoutWrp-RndCorner.Top
    .Body
    .InfoBox

    3. Flags

    - class-Attribut
    - Kleinschreibung
    - funktionsbeschreibend als Adjektiv

    - spezielle Flags orientieren sich an den CSS-Pseudoklassen

    Beispiele:

    .inactive
    .invalid
    .last
    (vgl. auch WAI-ARIA)
    .hover (siehe auch 5)
    .external
    .active

    4. JS-Selektoren

    - class-Attribut
    - Großschreibung
    - semantisch als Substantiv
    - ggf. Präfix, wie „js-“

    5. JS-Flags

    - class-Attribut
    - Kleinschreibung
    - funktionsbeschreibend als Adjektiv
    - ggf. Präfix, wie „js-“

    Beispiele:

    .js-moveable
    .js-draggable
    .js-current
    .js-hidden
    (vgl. unterschiedliches Browserverhalten mit und ohne JS)
    .active
    .hover (vgl. CSS-Pseudoelemente in 3)


    Wohlgemerkt sind das unverbindliche Vorschläge. Für jede Anwendung und Vorliebe ist hier die eigene Phantasie gefragt. Trotzdem bieten die Welten Javascript und CSS jede Menge Möglichkeiten zu konformem Arbeiten. Auch wenn es nicht immer objektorientiertes CSS sein muss.



  • #2
    Sehr schön, besonders die praxisnahen Beispiele, das hilft sicherlich vielen Anfängern auf einen geraden Weg zu kommen und den Profis ihr Konzepte auszufeilen.

    Danke dafür!
    You know, my wife sometimes looks at me strangely. „Duncan“, she says, „there's more to life than Solaris“. Frankly, it's like she speaks another language. I mean, the words make sense individually, but put them together and it's complete nonsense.

    Kommentar

    Lädt...
    X