Skeeve: img:after funktioniert nicht p:after schon

Moin!

Ich wollte gerne zu jedem Bild automatisch, per CSS einen Text hinzufügen. Die Forensuche hat mich auf img:after (img::after?) gebracht. Allerdings funktioniert das hier im Mozilla 1.7 / FF 1.5 nicht. Wenn ich statt "img" "p" nehme, dann erscheint korrekt, hinter jedem <p> der angegebene Content. Hier ein Beispiel:

  
<html>  
  <head>  
    <style type="text/css">  
      img {  
        display:block;  
      }  
  
      img:after {  
        content:attr(alt);  
        display:block;  
      }  
  
      p:after {  
        content:attr(class);  
      }  
    </style>  
  </head>  
  <body>  
    <p class="gibtsnicht">  
      <img alt="Google Logo" src="http://www.google.de/images/logo_sm.gif"/>  
    </p>  
  </body>  
</html>  

Hier wird das alt-attribut des img nicht angezeigt. das class-attribut von p aber schon.

Ist das ein bekannter bug? Mache ich was falsch? Oder hat jemand einen Tipp, was ich sonst noch unternehmen könnte?
-- Skeeve

  1. Moin!

    Ich wollte gerne zu jedem Bild automatisch, per CSS einen Text hinzufügen. Die Forensuche hat mich auf img:after (img::after?) gebracht. Allerdings funktioniert das hier im Mozilla 1.7 / FF 1.5 nicht. Wenn ich statt "img" "p" nehme, dann erscheint korrekt, hinter jedem <p> der angegebene Content. Hier ein Beispiel:

    <html>
      <head>
        <style type="text/css">
          img {
            display:block;
          }

    img:after {
            content:attr(alt);
            display:block;
          }

    p:after {
            content:attr(class);
          }
        </style>
      </head>
      <body>
        <p class="gibtsnicht">
          <img alt="Google Logo" src="http://www.google.de/images/logo_sm.gif"/>
        </p>
      </body>
    </html>

    
    > Hier wird das alt-attribut des img nicht angezeigt. das class-attribut von p aber schon.  
    >   
    >   
    > Ist das ein bekannter bug? Mache ich was falsch? Oder hat jemand einen Tipp, was ich sonst noch unternehmen könnte?  
    > -- Skeeve  
      
      
    Hey Skeeve,  
      
    das alt Attribut wird bei FF und Mozilla gar nicht angezeigt. Probiers mal mit dem title Attribut.  
    ~~~html
      
    <html>  
      <head>  
        <style type="text/css">  
          img {  
            display:block;  
          }  
      
          img:after {  
            content:attr(title);  
            display:block;  
          }  
      
          p:after {  
            content:attr(class);  
          }  
        </style>  
      </head>  
      <body>  
        <p class="gibtsnicht">  
          <img title="Google Logo" src="http://www.google.de/images/logo_sm.gif"/>  
        </p>  
      </body>  
    </html>  
    
    
    1. hi,

      das alt Attribut wird bei FF und Mozilla gar nicht angezeigt.

      Das ist falsch.
      Natürlich zeigen auch die Geckos den alt-Inhalt an, wenn sie das Bild nicht darstellen können.

      Probiers mal mit dem title Attribut.

      Das sollte m.E. keinen Unterschied machen.

      gruß,
      wahsaga

      --
      /voodoo.css:
      #GeorgeWBush { position:absolute; bottom:-6ft; }
      1. ja wenn das Bild nicht da ist schon ... aber beim MouseOver halten aber nicht. Habe es mal ausprobiert ... funktioniert aber auch mit meiner Variante nicht.

        1. hi,

          ja wenn das Bild nicht da ist schon ... aber beim MouseOver halten aber nicht.

          Das hat herzlich wenig damit zu tun, ob ein HTML-Element ein bestimmte Attribut hat, und ob dieses sich per CSS selektieren lässt.

          gruß,
          wahsaga

          --
          /voodoo.css:
          #GeorgeWBush { position:absolute; bottom:-6ft; }
        2. Hi,

          ja wenn das Bild nicht da ist schon ... aber beim MouseOver halten aber nicht.

          korrekt, genau das soll beim alt-Attribut passieren. Und um es noch einmal deutlich zu sagen: Etwas anderes soll beim alt-Attribut *nicht* passieren. Es ist ein ALTernativ-, kein Tooltip-Text.

          Cheatah

          --
          X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
          X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
          X-Will-Answer-Email: No
          X-Please-Search-Archive-First: Absolutely Yes
  2. Hello out there!

    Ich wollte gerne zu jedem Bild automatisch, per CSS einen Text hinzufügen. Die Forensuche hat mich auf img:after (img::after?) gebracht.

    '::after' ist CSS-3-Syntax. Einige Browser verstehen die schon, andere nicht; deshalb ist vorläufig besser noch ':after' zu verwenden. [CSS3-SELECTORS §7]

    Allerdings funktioniert das hier im Mozilla 1.7 / FF 1.5 nicht.

    Kann auch nicht: „Wie ihre Namen schon sagen, geben die Pseudoelemente :before und :after die Position von Inhalt vor und hinter dem Dokumentbauminhalt eines Elements an.“ [CSS2 §12.1]

    Das 'img'-Element ist ein leeres; darin kann also kein Inhalt sein, auch kein erzeugter.

    See ya up the road,
    Gunnar

    --
    “Remember, in the end, nobody wins unless everybody wins.” (Bruce Springsteen)
    1. Hallo Gunnar.

      Allerdings funktioniert das hier im Mozilla 1.7 / FF 1.5 nicht.

      Kann auch nicht: „Wie ihre Namen schon sagen, geben die Pseudoelemente :before und :after die Position von Inhalt vor und hinter dem Dokumentbauminhalt eines Elements an.“ [CSS2 §12.1]

      Ob es wohl ein CSS 2.2 geben wird, was diesen – in meinen Augen – Unsinn korrigiert?

      Das 'img'-Element ist ein leeres; darin kann also kein Inhalt sein, auch kein erzeugter.

      Wenn die Pseudoelemente nicht auf *jedes* Element angewandt werden können, haben sie meiner Meinung nach keinen Nutzen.

      Einen schönen Donnerstag noch.

      Gruß, Mathias

      --
      sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
      debian/rules
      1. hi,

        Das 'img'-Element ist ein leeres; darin kann also kein Inhalt sein, auch kein erzeugter.

        Wenn die Pseudoelemente nicht auf *jedes* Element angewandt werden können, haben sie meiner Meinung nach keinen Nutzen.

        Du kannst sie, wie alles andere in CSS, natürlich "anwenden" worauf du lustig bist.

        Dass sie nicht überall auch eine Auswirkung haben, ist ein anderes Thema - so ist's nun mal definiert.

        http://www.w3.org/TR/CSS21/generate.html#before-after-content
        The formatting objects (e.g., boxes) generated by an element include generated content. [...]
        The :before and :after pseudo-elements elements interact with other boxes, such as run-in boxes, as if they were real elements inserted just inside their associated element.

        Und in ein Bild, da hat Gunnar vollkommen recht, kann man nun mal keine weiteren Elemente einfügen.

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }
        1. Hallo wahsaga.

          Das 'img'-Element ist ein leeres; darin kann also kein Inhalt sein, auch kein erzeugter.

          Wenn die Pseudoelemente nicht auf *jedes* Element angewandt werden können, haben sie meiner Meinung nach keinen Nutzen.

          Du kannst sie, wie alles andere in CSS, natürlich "anwenden" worauf du lustig bist.

          Natürlich. Was ich gemeint habe, sollte dennoch klar sein.

          Dass sie nicht überall auch eine Auswirkung haben, ist ein anderes Thema - so ist's nun mal definiert.

          Das bezweifle ich auch nicht, sondern lediglich die Sinnhaftigkeit dessen.

          http://www.w3.org/TR/CSS21/generate.html#before-after-content

          Schauen wir uns diesen Text einmal genauer an:

          Authors specify the style and location of generated content with the :before and :after pseudo-elements. As their names indicate, the :before and :after pseudo-elements specify the location of content before and after an element's document tree content.

          Ich weiß nicht, ob es an mir liegt, aber für mich deutet „vorher“ und „nachher“ recht unmissverständlich darauf hin, dass etwas *vor* ein Objekt oder *nach* einem Objekt platziert wird und nicht darin davor und darin danach.

          Und überhaupt: was, wenn ein Element eigentlich Inhalt haben darf, aber keinen hat?

          So zeigen Firefox und Konqueror bei folgendem nichtsdestotrotz die Pseudoelemente beim Link an:

          <img src="graphic.png" alt="" />  
          <a href=""></a>
          

          Einen schönen Donnerstag noch.

          Gruß, Mathias

          --
          sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
          debian/rules
          1. Hi,

            Authors specify the style and location of generated content with the :before and :after pseudo-elements. As their names indicate, the :before and :after pseudo-elements specify the location of content before and after an element's document tree content.
            Ich weiß nicht, ob es an mir liegt, aber für mich deutet „vorher“ und „nachher“ recht unmissverständlich darauf hin, dass etwas *vor* ein Objekt oder *nach* einem Objekt platziert wird und nicht darin davor und darin danach.

            exakt das steht dort aber _nicht_. Das "vorher" bzw. "nachher" bezieht sich _nicht_ auf das Objekt, sondern auf dessen Inhalt. Was mich persönlich etwas irritierte ist, dass mein Mozilla ein img:before { content:'Foo'; } nicht auf den Alternativtext angewendet hat, wenn die Grafik nicht geladen werden konnte.

            Worüber man vortrefflich streiten kann ist, ob das W3C eine Sonderregelung für Replaced Elements hätte vorsehen sollen. Da bin ich, zumindest bei der ersten Betrachtung, ebenfalls der Ansicht, :before und :after sollen sich außerhalb des Elements befinden.

            Und überhaupt: was, wenn ein Element eigentlich Inhalt haben darf, aber keinen hat?

            Dann hat es einen Inhalt, nämlich einen leeren.

            Cheatah

            --
            X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
            X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
            X-Will-Answer-Email: No
            X-Please-Search-Archive-First: Absolutely Yes
            1. Hallo Cheatah.

              Das "vorher" bzw. "nachher" bezieht sich _nicht_ auf das Objekt, sondern auf dessen Inhalt.

              Ja, per Definition.

              Was mich persönlich etwas irritierte ist, dass mein Mozilla ein img:before { content:'Foo'; } nicht auf den Alternativtext angewendet hat, wenn die Grafik nicht geladen werden konnte.

              Stimmt; wie soll ein UserAgent in diesem Fall mit dem generierten Inhalt umgehen? Da hierzu in der Spezifikation keine Aussage getroffen wird, ist es wieder einmal den Browserherstellern überlassen, wie sie dies umsetzen.

              Worüber man vortrefflich streiten kann ist, ob das W3C eine Sonderregelung für Replaced Elements hätte vorsehen sollen. Da bin ich, zumindest bei der ersten Betrachtung, ebenfalls der Ansicht, :before und :after sollen sich außerhalb des Elements befinden.

              Ich bin generell der Ansicht, dass Pseudoelemente außerhalb von Elementen zu platzieren sind.

              Und überhaupt: was, wenn ein Element eigentlich Inhalt haben darf, aber keinen hat?

              Dann hat es einen Inhalt, nämlich einen leeren.

              OK, dies kann ich akzeptieren. Interessant ist in diesem Zusammenhang auch das Rendering Firefox’ und Konquerors’ bei folgendem Code:

              <a href="" />

              Sowohl ::before als auch ::after werden hier doppelt eingefügt. Eine Ahnung, warum?

              Einen schönen Donnerstag noch.

              Gruß, Mathias

              --
              sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
              debian/rules
              1. Hi,

                Was mich persönlich etwas irritierte ist, dass mein Mozilla ein img:before { content:'Foo'; } nicht auf den Alternativtext angewendet hat, wenn die Grafik nicht geladen werden konnte.
                Stimmt; wie soll ein UserAgent in diesem Fall mit dem generierten Inhalt umgehen? Da hierzu in der Spezifikation keine Aussage getroffen wird, ist es wieder einmal den Browserherstellern überlassen, wie sie dies umsetzen.

                ja, wobei ich persönlich der Ansicht bin, dass nur eine reelle Interpretationsmöglichkeit vorhanden ist - nämlich die, die Gecko demonstriert.

                Ich bin generell der Ansicht, dass Pseudoelemente außerhalb von Elementen zu platzieren sind.

                Beide Varianten haben erhebliche Auswirkungen, die die jeweils andere Wahl als vorteilhaft erscheinen lassen ;-) Ich glaube aber, dass die "innerhalb"-Variante das bessere Verhältnis von Vor- zu Nachteilen hat.

                Interessant ist in diesem Zusammenhang auch das Rendering Firefox’ und Konquerors’ bei folgendem Code:
                <a href="" />
                Sowohl ::before als auch ::after werden hier doppelt eingefügt. Eine Ahnung, warum?

                Ja: Schau Dir den Generated Source an. Bei (X)HTML akzeptiert Gecko die Kurzschreibweise "<foo/>" nicht, wenn das Content-Modell des Elements nicht Empty ist. In Folge dessen wird das Element lediglich geöffnet, aber nicht an dieser Stelle geschlossen. Ein "<span/><span/><span/><img/><div>..." wird somit zum "<span><span><span><img/></span></span></span><div>...".

                Dass KHTML sich ähnlich verhält, ist mir allerdings neu :-)

                Cheatah

                --
                X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
                X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
                X-Will-Answer-Email: No
                X-Please-Search-Archive-First: Absolutely Yes
                1. Hallo Cheatah.

                  Ich bin generell der Ansicht, dass Pseudoelemente außerhalb von Elementen zu platzieren sind.

                  Beide Varianten haben erhebliche Auswirkungen, die die jeweils andere Wahl als vorteilhaft erscheinen lassen ;-) Ich glaube aber, dass die "innerhalb"-Variante das bessere Verhältnis von Vor- zu Nachteilen hat.

                  Inwiefern genau? Welchen Nachteil sollte es haben, wenn Pseudoelemente außerhalb platziert werden?

                  Interessant ist in diesem Zusammenhang auch das Rendering Firefox’ und Konquerors’ bei folgendem Code:
                  <a href="" />
                  Sowohl ::before als auch ::after werden hier doppelt eingefügt. Eine Ahnung, warum?

                  Ja: Schau Dir den Generated Source an. Bei (X)HTML akzeptiert Gecko die Kurzschreibweise "<foo/>" nicht, wenn das Content-Modell des Elements nicht Empty ist. In Folge dessen wird das Element lediglich geöffnet, aber nicht an dieser Stelle geschlossen. Ein "<span/><span/><span/><img/><div>..." wird somit zum "<span><span><span><img/></span></span></span><div>...".

                  Aha, danke.

                  Aus:

                  <p><a href=""/></p>

                  Wird:

                  <p><a href=""></a></p>  
                  <a href="">  
                  </a>
                  

                  Nur dass er das „Echo“ des eigentlichen Elementes außerhalb seines Elternelementes platziert, ist merkwürdig.

                  Einen schönen Donnerstag noch.

                  Gruß, Mathias

                  --
                  sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
                  debian/rules
  3. Hallo,

    Ich wollte gerne zu jedem Bild automatisch, per CSS einen Text hinzufügen. Die Forensuche hat mich auf img:after (img::after?) gebracht. Allerdings funktioniert das hier im Mozilla 1.7 / FF 1.5 nicht. Wenn ich statt "img" "p" nehme, dann erscheint korrekt, hinter jedem <p> der angegebene Content.

    Natürlich, die Pseudoelemente :after und :before erzeugen _innerhalb_ des selektierten Elements ein weiteres beliebiges Element, das entweder am Anfang (:before) oder am Ende (:after) steht.

    Hier ein Beispiel:
    [Beispiel]
    Hier wird das alt-attribut des img nicht angezeigt. das class-attribut von p aber schon.

    Das was du vorhast, würde folgendes erzeugen:

    Absatz (p):
    <p>Normaler Text[Klasse]</p>

    Bild (img):
    <img src="blablabla">[Alternativtext]</img>

    Ist das ein bekannter bug?

    Nö, img ist ein Element, das keinen Inhalt haben _darf_.

    Mache ich was falsch?

    Gewissermaßen schon, ja. Ich fand die Wirkungsweisen dieser Pseudoelemente aber auch immer etwas verwirrend.

    Oder hat jemand einen Tipp, was ich sonst noch unternehmen könnte?

    Ein anderes Element um das Bild ziehen, und diesem die Pseudoelemente zuweisen.

    Dann würde etwas in der Form rauskommen:
    span:after {content:"After-Text"}
    <span><img src="blablabla"/>After-Text</span>

    Leider kannst du dann aber nicht mehr auf Attribute von img zugreifen.

    mfg. Daniel

  4. Moin!

    Vielen Dank für Eure Hilfe! Jetzt habe sogar ich es kapiert ;-)

    Gelöst habe ich es nun wie folgt (Die übliche Randbemerkung: Applikation. Nur mit JavaScript. Nur Gecko)

    Da die Datei mit AJAX Methoden geholt wird, und ich ohnehin schon Hand anlege, suche ich per JavaScript alle img mit alt-tag und baue ein <br><small>/inhalt von alt/</small> ein:

      
    content.innerHTML= text;  
    var img= content.getElementsByTagName( 'img' );  
    for (var i= img.length; i--; ) {  
     var alt= img[i].getAttribute( 'alt' );  
     if ( ! alt ) continue;  
     var br= document.createElement( 'br' );  
     var sml= document.createElement( 'small' );  
     sml.textContent= alt;  
     var crsr= img[i].nextSibling;  
     with ( img[i].parentNode) {  
      insertBefore( br, crsr );  
      insertBefore( sml, crsr );  
     }  
    }  
    
    

    -- Skeeve

    1. Hi,

      (Die übliche Randbemerkung: Applikation. Nur mit JavaScript. Nur Gecko)

      dann gestatte mir folgenden Tipp:

      [...]

      var crsr= img[i].nextSibling;
      with ( img[i].parentNode) {
        insertBefore( br, crsr );

      [...]

        
      Du kannst Gecko wunderbar per Element.prototype eine Methode insertAfter() verpassen, die den nextSibling verwendet, so vorhanden, und andernfalls ein appendChild() auf das Vaterelement ausführt. Mit ähnlichem Vorgehen kannst Du obige Funktion kürzen auf:  
        
      ~~~javascript
        
      content.innerHTML= text;  
      var img= content.getElementsByTagName( 'img' );  
      for (var i= img.length; i--; ) {  
          img[i].initElement(); // o.ä.  
      }  
      
      

      Bzw. wenn Du noch weiter gehen möchtest:

        
      content.innerHTML= text;  
      content.init();  
      
      

      Viel Spaß ;-)

      Cheatah

      P.S.: Dank Getter und Setter könnte bei Gecko sogar nur die erste Zeile reichen ...

      --
      X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
      X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
      X-Will-Answer-Email: No
      X-Please-Search-Archive-First: Absolutely Yes