Felix Riesterer: Breite des Viewports im IE wenn body margins hat?

Liebe Mitlesende,

ich brauche die Breite des Viewports im IE. Meine bisherigen Recherchen haben ergeben, dass ich zwei Dinge ermitteln kann:

* document.body.clientWidth (oder document.body.offsetWidth)
* document.documentElement.clientWidth

Beide Angaben liefern mir interessante Werte, aber nicht die tatsächliche Breite meines Viewports, denn mein <body>-Element hat per CSS margins bekommen (body { margin: 0.2em 2em; }). Nun stimmen die per JavaScript ermittelten Werte anscheinend nicht.

Szenario: Ich möchte ein <p>-Element über die gesamte Breite an den Anfang des Dokuments legen, sodass dieses <p>-Element das erste Kindelement von <body> ist. Dieses habe ich absolut positioniert:

p {  
    position: absolute;  
    top: 0px;  
    left: 0px;  
    right: 0px;  
    width: auto;  
}

Wer kann mir weiterhelfen?

Liebe Grüße,

Felix Riesterer.

--
ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
  1. @@Felix Riesterer:

    nuqneH

    Szenario: Ich möchte ein <p>-Element über die gesamte Breite

    Wessen gesamte Breite? Des Viewports?

    an den Anfang des Dokuments legen, sodass dieses <p>-Element das erste Kindelement von <body> ist.

    ?? Das ist so im Markup?

    Dieses habe ich absolut positioniert:

    Warum?

    Du willst, dass sich dieser Absatz (wie selektierst du nur diesen? ID? 'body>p:first-child'?) über die Ränder des 'body' erstreckt?

    p  
    {  
      margin: -0.2em 2em 1em;  
    }
    

    Wozu JavaScript?

    Qapla'

    --
    Volumen einer Pizza mit Radius z und Dicke a: pi z z a
    1. Lieber Gunnar,

      ich habe mein Problem gelöst.

      Szenario: Ich möchte ein <p>-Element über die gesamte Breite

      Wessen gesamte Breite? Des Viewports?

      Ja.

      an den Anfang des Dokuments legen, sodass dieses <p>-Element das erste Kindelement von <body> ist.

      ?? Das ist so im Markup?

      Nein, aber im DOM.

      Dieses habe ich absolut positioniert:

      Warum?

      Damit ich es auch in IE "fixed" anzeigen kann. Wenn man scrollt, soll die "fake" Infobar sich wie die echte verhalten und sich nicht wegscrollen lassen.

      Du willst, dass sich dieser Absatz (wie selektierst du nur diesen? ID? 'body>p:first-child'?) über die Ränder des 'body' erstreckt?

      Ja. Er besitzt eine ID.

      p

      {
        margin: -0.2em 2em 1em;
      }

        
      Das klappt nur, wenn die margin-Werte im Body des jeweiligen Dokuments exakt diesen Werten entsprechen... sie sollen aber \_immer\_ passen -> JavaScript.  
        
      
      > Wozu JavaScript?  
        
      s.o.  
        
      Liebe Grüße,  
        
      Felix Riesterer.
      
      -- 
      ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
      
  2. Liebe Mitlesende,

    inzwischen bin ich etwas weiter.

    * document.body.clientWidth (oder document.body.offsetWidth)
    * document.documentElement.clientWidth

    Wenn man die Differenz, die sich aus den beiden Werten ergibt, als negative Zahl dem right-Wert zuweist, dann erreicht man den rechten Rand des Viewports um absolut positionierte Elemente korrekt daran auszurichten.

    Das Ganze hatte den folgenden simnplen Zweck:
    Angeregt durch die Idee von ie6update.com wollte ich ein schlankeres Script, das vor allem auch ohne jquery-Bibliothek auskommt, um denselben Zweck zu erreichen. Auf meiner Website kann man das Ergebnis in einem Internet Explorer betrachten, wenn der IE eine Version kleiner 8 hat. Eventuelle visuelle Schönheitsfehler im IE7 werden noch behoben (konnte noch nicht testen).

    Liebe Grüße,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
    1. @@Felix Riesterer:

      nuqneH

      inzwischen bin ich etwas weiter.

      Etwas weiter auf dem Holzweg?

      Die Frage, wozu du überhaupt JavaScript brauchst, hast du nicht beantwortet?

      Was ist dein Problem, was du damit zu lösen gedachtest (und wofür es vielleicht auch eine CSS-Lösung gibt)?

      Qapla'

      --
      Volumen einer Pizza mit Radius z und Dicke a: pi z z a
      1. Lieber Gunnar,

        Etwas weiter auf dem Holzweg?

        Die Frage, wozu du überhaupt JavaScript brauchst, hast du nicht beantwortet?

        Was ist dein Problem, was du damit zu lösen gedachtest (und wofür es vielleicht auch eine CSS-Lösung gibt)?

        eine reine CSS-Lösung scheint es nicht zu geben. Die Aufgabenstellung ist eigentlich völlig klar... nur ist die scheinbare CSS-Lösung keine erfolgreiche, sonst hätte ich das längst so gelöst.

        Nochmal für Dich: Es geht um den IE6(!), der mit CSS so seine Eigenheiten entwickelt. Das, was Du als CSS-Lösung bezeichnest, erfüllt nicht die Aufgabenstellung. Daher diese extra für Dich:

        Gegeben sei ein beliebiges HTML-Dokument mit beliebigen CSS-Regeln für das <body>-Element. In dieses Dokument soll per JavaScript ein zusätzliches Element als erstes Kindelement eingefügt werden, um eine Art "Layer" zu erzeugen. Es geht um eine Nachempfundene Informationsleiste, wie sie im IE eingeblendet wird, wenn z.B. Popups geblockt, oder Plugins benötigt werden. Diese Leiste soll dem User anbieten, dass er den IE8 installiert (siehe ie6update.com - nur dass die dortige Lösung zusätzlich noch jquery benötigt und von daher für mich erst recht nicht in Frage kommt).

        Dieses neue firstChild soll nun die verfügbare Anzeigebreite bedecken (aka Breite des Viewports). Daher hatte ich folgenden css-basierten Lösungsansatz:

        #mein_element {  
            position: absolute;  
            top: 0px;  
            left: 0px;  
            right: 0px;  
        }
        

        Da ich ein <p>-Element für ausreichend halte, wollte ich auf <div> verzichten. Und ja Struppi, die eventuell vorhandenen margin- und padding-Werte sind zu "löschen", daran habe ich gedacht.

        Obige Lösung kann zu ungewollten Zwischenräumen führen, wenn das <body>-Element selbst mit margins versehen ist, denn dann hat unsere Leiste rechts und links einen Abstand zum Fensterrahmen, den sie aber nicht haben soll. Da mein Script aber auf verschiedenen Seiten bei verschiedenen Ausgangssituationen dieselbe Erscheinungsform haben soll, kann ich im CSS den margin-Wert des <body>-Elements nicht einfach mit einrechnen, da dieses eine "Seiten-spezifische" Lösung wäre, die auf einer anderen Seite bei anderen CSS-Regeln prompt versagt. Daher muss die Lösung mittels JavaScript erfolgen, welches solche margin-Werte ermitteln, bzw. asugleichen soll.

        Falls Du wirklich helfen willst, dann nimm einen IE6 und schau auf meiner Seite vorbei, denn dort wird das Script eingesetzt. Du kannst es auch bei mir herunterladen ("ie-update") und testen.

        Liebe Grüße,

        Felix Riesterer.

        --
        ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
  3. ich brauche die Breite des Viewports im IE. Meine bisherigen Recherchen haben ergeben, dass ich zwei Dinge ermitteln kann:

    * document.body.clientWidth (oder document.body.offsetWidth)

    Das sind die Werte die quirksmode gelten. Das eine die Fensterbreite (offset), das andere die Dokumentenbreite (client). Zumindest im IE, der Unterschied dieser Werte, ist der Fensterahmen und ein eventueller Scrollbalken.

    * document.documentElement.clientWidth

    Der Wert ist gültig im Standardmode und entspricht der Fenster(innen)breite im IE.

    Szenario: Ich möchte ein <p>-Element über die gesamte Breite an den Anfang des Dokuments legen, sodass dieses <p>-Element das erste Kindelement von <body> ist. Dieses habe ich absolut positioniert:

    p {

    position: absolute;
        top: 0px;
        left: 0px;
        right: 0px;
        width: auto;
    }

    
    >   
    > Wer kann mir weiterhelfen?  
      
    Warum nimmst du nicht width:100%;? Un did rist klar, dass p per Default ein margin hat?  
      
    Struppi.
    
    1. Lieber Struppi,

      Warum nimmst du nicht width:100%;?

      diese Idee führt in die Wüste, wenn <body> ein margin-left oder margin-right größer null hat, denn dann ist für die Kindelemente "width" genau das, was "dazwischen" an Breite übrig bleibt, wenn man die Außenabstände von <body> von der Breite des Viewports abgezogen hat.

      Un did rist klar, dass p per Default ein margin hat?

      Ja, das habe ich im Beispiel vernachlässigt, das stimmt.

      Liebe Grüße,

      Felix Riesterer.

      --
      ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
      1. Warum nimmst du nicht width:100%;?

        diese Idee führt in die Wüste, wenn <body> ein margin-left oder margin-right größer null hat, denn dann ist für die Kindelemente "width" genau das, was "dazwischen" an Breite übrig bleibt, wenn man die Außenabstände von <body> von der Breite des Viewports abgezogen hat.

        Das verstehe ich nicht. Wenn du absolut positionierst dann erbt doch p nicht von Body? ein p mit width:100% geht genau über die Breite der Seite.

        Struppi.

        1. Lieber Struppi,

          Das verstehe ich nicht. Wenn du absolut positionierst dann erbt doch p nicht von Body? ein p mit width:100% geht genau über die Breite der Seite.

          das hätte ich auch so erwartet... aber der IE(6) ist nunmal der IE... anscheinend. Probier's aus!

          Liebe Grüße,

          Felix Riesterer.

          --
          ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
          1. Das verstehe ich nicht. Wenn du absolut positionierst dann erbt doch p nicht von Body? ein p mit width:100% geht genau über die Breite der Seite.

            das hätte ich auch so erwartet... aber der IE(6) ist nunmal der IE... anscheinend. Probier's aus!

            Ich hab hier nur einen IE 8 und der hat keine Probleme damit.

            Struppi.

            1. Lieber Struppi,

              Ich hab hier nur einen IE 8 und der hat keine Probleme damit.

              das überrascht mich nicht. Solange Du keinen IE6 benutzt, wirst Du mein Problem eben nicht nachvollziehen können.

              Liebe Grüße,

              Felix Riesterer.

              --
              ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
  4. ich brauche die Breite des Viewports im IE.

    Folgendes habe ich mir vor ein paar Jahren bei quirksmode.org zusammengeklaut und leicht modifiziert, die Referenz kann ich auf der Seite nicht mehr finden. Es leistet mir bis heute verlässliche Dienste. In einem kurzen Test lieferte es mir sowohl mit wie auch ohne deinem "Body margin" den exakten Wert. Evtl. willst du auch auf resize für ein etwaiges Update horchen?

        this.getPageSize = function () {  
    		var xScroll, yScroll;  
    		if (window.innerHeight && window.scrollMaxY) {	  
    			xScroll = document.body.scrollWidth;  
    			yScroll = window.innerHeight + window.scrollMaxY;  
    		} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac  
    			xScroll = document.body.scrollWidth;  
    			yScroll = document.body.scrollHeight;  
    		} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari  
    			xScroll = document.body.offsetWidth;  
    			yScroll = document.body.offsetHeight;  
    		}  
    		  
    		var windowWidth, windowHeight;  
    		if (self.innerHeight) {	// all except Explorer  
    			windowWidth = self.innerWidth;  
    			windowHeight = self.innerHeight;  
    		} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode  
    			windowWidth = document.documentElement.clientWidth;  
    			windowHeight = document.documentElement.clientHeight;  
    		} else if (document.body) { // other Explorers  
    			windowWidth = document.body.clientWidth;  
    			windowHeight = document.body.clientHeight;  
    		}	  
    		  
     // for small pages with total height less then height of the viewport  
    		if(yScroll < windowHeight){  
    			pageHeight = windowHeight;  
    		} else {  
    			pageHeight = yScroll;  
    		}  
      
     // for small pages with total width less then width of the viewport  
    		if(xScroll < windowWidth){	  
    			pageWidth = windowWidth;  
    		} else {  
    			pageWidth = xScroll;  
    		}  
    		return {pageWidth:pageWidth, pageHeight:pageHeight, windowWidth:windowWidth, windowHeight:windowHeight};  
    	}	
    
    1. Liebe(r) Pragma,

      this.getPageSize = function () {

      vielen Dank für Deinen Code, jedoch habe ich es einfacher gelöst. Wie bereits beschrieben brauche ich eine Lösung ausschließlich für IE6, da IE7 ausreichend CSS unterstützt, um meine Bedürfnisse ohne JavaScript zu lösen. Meine Lösung sieht so aus:

      correctPosition = function () {  
          // This function gets called only in IE6.  
          var myElement = document.getElementById("myElement"),  
              body = (document.compatMode && document.compatMode == "CSS1Compat") ?  
                  document.documentElement : document.body || null, // Thanks to Struppi!  
              l, r, t  
        
          l = body.scrollLeft;  
          myElement.style.left = l.toString() + "px";  
        
          // the body's width in IE6 isn't always the same as the viewports's  
          r = body.clientWidth ?  
              document.body.offsetWidth - body.clientWidth :  
              document.body.offsetWidth - body.offsetWidth;  
        
          r -= l;  
          myElement.style.right = r.toString() + "px";  
        
          t = body.scrollTop;  
          myElement.style.top = t.toString() + "px";  
      };
      

      Liebe Grüße,

      Felix Riesterer.

      --
      ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)