CSS Positionierungs-Problem (für Profis und die, die ALLE Tricks kennen). unlösbar?!

benneq

Fleet Admiral
Registriert
Juli 2010
Beiträge
12.620
Moin!

Also mein Layout-Problem ist einfach erklärt und (unendlich) schwer zu lösen. Vielleicht habe ich aber auch ein paar Möglichkeiten übersehen. Klärt mich auf, falls ihr eine Lösung kennt.

Optisch soll das Ganze aussehen, wie auf dem Bild im Anhang. D.h. ich habe mehrfach solche "Layer" untereinander. Und zu jedem Layer gehört eine Blaue Box.
Es geht hier nur um das Design eines einzelnen Layers.

Ein Layer besteht aus
- einer vorgegebenen Höhe (Anhaltspunkt 20px) und
- einer beliebigen Breite. (Die Breite wird auch fest vorgegeben und ist in jedem Fall größer als der Bildschirm (Anhaltspunkt 10000px))
Rechts sieht man die Blaue Box, ihre Höhe ist 100% des Layers. D.h. wenn ich den Layer in der Höhe verändere, ändert sich die Box auch.
So weit, so einfach.....

Jetzt kommt der happige Teil: Die Positionierung der Box!
Die Box soll IMMER am rechten Bildschirmrand kleben und natürlich IM Layer liegen. Da die Layer nun ziemlich breit sind, ist es klar, dass man dort scrollen kann. D.h. Wenn ich nach links/rechts scrolle, soll sich nur(!) der Inhalt des Layers verschieben, die Blaue Box bleibt aber an Ort und Stelle.
Außerdem muss es wie gesagt möglich sein, die Layer dynamisch zu vergrößern bzw. zu verkleinern (und die Blauen Boxen dann automatisch auch).

Beachte: Es können ruhig 100 Layer oder mehr werden. D.h. es gibt dann auch noch vertikale Scrollbalken ;)


Das Projekt ist komplett mit dem Google Web Toolkit (GWT) geschrieben, von daher wäre eine Lösung in JavaScript natürlich möglich, ABER es ist verdammt umständlich und überhaupt nicht performant bei ca. 5000 Layern! (Vielleicht waren meine Algorithmen auch zu mies)...
  1. Blaue Box liegt IM Layer und bekommt per CSS 'height: 100%;'. Dann muss ich per JS die horizontalen ScrollEvents abfangen und jede Box einzeln mit CSS 'left' anpassen. Das dann für 5000 Elemente und ununterbrochen beim Scrollen. Ganz schön kacke ...
  2. Blaue Box mit 'position: absolute' (außerhalb des Layers) an den rechten Rand tackern 'right: 0'. Und dann die vertikalen ScrollEvents abfangen und die Boxen neu setzen. Dieser Algorithmus läuft noch langsamer als Nr.1...


Daher möchte ich eine Lösung OHNE JavaScript. Ich bin für jeden Hinweis dankbar :)
Bisher hab ich auf der Suche etwas gefunden, was ineinander verschachtelte 'position: fixed' Panels sind. Allerdings habe ich das Gefühl, dass ich es damit nicht umsetzen kann.




EDIT: Es ist im Grunde egal, ob die Blaue Box IM oder neben dem Layer liegt (da diese eh alles verdeckt was drunter ist). Hauptsache ist, dass es irgendwie umsetzbar ist...
 

Anhänge

  • Bildschirmfoto 2011-08-27 um 20.30.10.png
    Bildschirmfoto 2011-08-27 um 20.30.10.png
    10,7 KB · Aufrufe: 223
Also ich bin blutiger Anfänger in CSS, aber dein Problem scheint doch nichts großartiges zu sein (vielleicht funktioniert meine mögliche Lösung auch nicht. Das musste dann probieren^^ :D
Du verschachtelst einfach 2 Layer ineinander: Der gelbe Layer und in diesen Layer machst du den blauen.
Der blaue bekommt die Größe vom umgebenden Layer und position:fixed
Dann musst du ihn nur noch rechts ausrichten (zb mit right: 100px oder du musst mit float arbeiten).

Wie gesagt bin totaler Anfänger was CSS angeht, aber ich denke so sollte das gehen.
Hoffe ich hab dir jetzt nichts falsches erzählt :p
 
Das muss ich gar nicht erst ausprobieren ;) Das geht nicht.

Erklärung:
Wenn ich die Blaue Box in den gelben Layer stecke, und der blauen Box sage 'right: 100px'. dann ist die blaue Box 100px vom rechten Rand des gelben Layer entfernt. D.h. wenn der gelbe Layer nun 10000px breit ist, dann ist die blaue Box bei ca. 9990px. Dann müsste ich dahin scrollen, um sie zu sehen... Die Box soll aber IMMER sichtbar sein am rechten Bildschirmrand.
Wenn ich dazu dann noch das von dir vorgeschlagene 'position: fixed' nehme, dann ist die box 100px vom rechten Bildschirm-Rand entfernt. Hinzu kommt dann noch, dass bei 'height: 100%' die Box so hoch wird wie der Bildschirm...

Aber danke :)
 
Hm das mit height: 100% (das es über den ganzen Bildschirm geht) dachte ich mir schon fast. Glaube das Problem hatte ich nämlich auch mal.

Wohl doch nicht so einfach wie ich dachte :)

Mein Lösungvorschlag: Links nen Frame mit dem gelben und rechts einen Frame mit dem blauen Teil.
Dann kann man im linken Frame nach rechts scrollen und das blaue bleibt.

Ist dann wahrscheinlich nicht so wie du dir das gewünscht hast, aber das dürfte gehen...

Mal gucken ob das hier irgendjemand mit reinem css lösen kann.

edit: Normal dürfte das mit dem fixed rechts aber auch i-wie gehen.
Einen div fixed am oberen bzw. unteren Rand geht ja auch ohne Probleme. Dann dürfte das doch links bzw. rechts auch kein Problem sein
 
Zuletzt bearbeitet:
Hey :)

Das mit den 2 Frames ist auch gerade die Idee die ich habe.

quasi:
Code:
<div>    <- CONTAINER
    <div>    <- LAYER CONTAINER
        <div>LAYER</div>
        <div>LAYER</div>
        <div>....</div>
    </div>
    <div>    <- BLAUE BOX CONTAINER
        <div>BOX</div>
        <div>BOX</div>
        <div>....</div>
    </div>
</div>

Alle 'layer' werden durch nummeriert. D.h. zu jedem Layer gibt es eine Box mit der selben Nummer.
Im 'container' bekommt der 'box-container' die attribute 'right: 0'. Dann hab ich alle Boxen schon mal auf der Rechten Seite. Beim erstellen, von einem Layer erstellt man dann halt ein div im 'layer-container' und eins im 'box-container'. Muss halt drauf achten, dass die höhe gleich ist. Wenn man dann ein 'layer-div' in der Höhe ändert muss man das mit der selben Nummer im 'box-container' auf die selbe Höhe ändern.
Für das vertikale Scrollen muss man den äußeren 'container' nutzen (damit boxen und layer gleichzeitig hoch und runter scrollen). Und für das horizontale nimmt man dann halt den 'layer-container'...
Das ist im Vergleich zu meiner alten Lösung viel viel viel weniger JavaScript.

Aber gibt's denn wirklich keine schönere Lösung? :D



EDIT: das mit dem 'fixed' stimmt zwar, aber es bringt mir nichts. 'fixed' heißt ja, dass er die Elemente anhand des Browser-Fensters ausrichtet. Das hat für mein Vorhaben viele Nachteile:
1. Du muss JEDEM Element einzeln sagen wo es ist (top: 0px, dann top: 20px, dann nächstes mit top: 40px.....).
2. (viel wichtiger) wenn es mit position: fixed arbeitet. dann habe ich nicht die Möglichkeit, dass ich die ganzen layer in ein eigenes div lege. z.B. möchte ich evtl. nur die Hälfte des Bildschirms mit den layern füllen. Dann müsste ich da ganz schön häßlich rumrechnen.
3. vertikales Scrollen ist unmöglich! Ich müsste einen eigenen Scrollbalken simulieren, der dann alle Elemente einzeln um x Pixel hoch oder runter schiebt. Das ist untragbar ;)
 
Zuletzt bearbeitet:
Wenn du aber nen fixed div um die blauen boxen legst und den fixed machst, dann dürften die sich ohne das top:20px usw. untereinander ausrichten lassen?!
Also ich bin auf jeden Fall an dem Punkt angekommen an dem ich auch nixmehr weiß^^

Ich würde das per frame machen, wobei man eben den gelben frame nach links und rechts scrollen kann.
Sowas in der Art (deute es mal mit einer Tabelle an)
HTML:
<table>
<tr><th>gelber Teil</th><th>blauer Teil</th></tr>
<tr><th>Frame für ersten gelben-scrollbar</th><th>Frame für ersten blauen</th></tr>
<tr><th>Frame für zweiten gelben-scrollbar</th><th>Frame für zweiten blauen</th></tr>
</table>

So würde ich das in etwa machen.
 
Moin!

Ich seh gerade, du hast da was falsch verstanden... Habs wohl nicht ordentlich erklärt.
Es soll nur EINEN Scrollbalken geben,der alle Layer gleichzeitig bewegt ;)

Mit Fixed kommt man auf keinen Fall weiter....
 
Um mich nochmal abzusichern:

Du willst ganz viele "Layer" machen - jeder "Layer" besteht quasi aus 2 Elementen: der gelben, breiten Linie (10k px) und einem blauen Balken. Der Blaue Balken soll auf der gleichen Höhe sitzen wie der gelbe Balken - aber nur eben immer am rechten Rand "geklatscht" positioniert sein - egal wie man horizontal hin und her scrolled?

Edit: Was genau spricht denn HIER dagegen?
Code:
<div style="background-color: #ff0000; height: 35px; width: 10000px;">
  <div style="background-color: #00ff00; position: fixed; right: 0px; height: 35px;">test</div>
</div>

Speziell:
Code:
position: fixed; right: 0px;
Damit bleibt die Box IMMER am rechten Rand - egal wie man horizontal scrolled. Vertikal ist sie nicht fixiert und bleibt somit IMMER auf der Position des ihr zugehörigen "Layers".
 
Zuletzt bearbeitet:
Klingt interessant. Ich werde es sofort testen :) Melde mich gleich wieder

EDIT: Zurück ich bin. War doch zu schön um wahr zu sein... :(
Also es funktioniert teilweise. Solang die Layer zusammen nicht die Bildschirmhöhe erreicht haben ist alles perfekt. Aber wenn ich 30 von deinen Layern erstelle, dann bekomme ich einen vertikalen Scrollbalken und da die Boxen 'position: fixed' sind bleiben die natürlich stehen und scrollen nicht mit...

Und deine Idee hat noch einen kleinen Haken (den man vermutlich nur mit JS lösen kann): Wenn ich die Layerhöhe änder, dann muss ich die Boxhöhe manuell mit ändern, da sich 'height: 100%' natürlich wieder auf das gesamte Fenster bezieht.

Hmm.. Noch jemand eine Idee? Ich warte noch auf die Revolution :D
 
Zuletzt bearbeitet:
Wenn man jetzt aber einen Frame macht (mit dem scrollt man nach unten), der wiederrum 2 Frames enthält, wovon sich der linke nach rechts und links scrollen lässt??
Dann würden die beiden inneren Frames gleichzeitig nach oben/unten scrollen und nach rechts und links würde der komplette gelbe Block gehen.

Das mit fixed wird natürlich wirklich ein Problem wenn es höher als der Bildschirm ist. Aber mit den Frames könnte das so gehen.
 
benneque schrieb:
Hmm.. Noch jemand eine Idee? Ich warte noch auf die Revolution :D
Dann fällt mir jetzt leider nur die Javascriptlösung ein. Aktuelle Scrollposition auslesen und danach deinen Layer entsprechend "absolute" positionieren.
Stichworte: pageXOffset, pageYOffset

Wird aber vermutlich recht Rechenintensiv - besser fällt es mir im Moment aber auch nicht ein.

Darf ich fragen, was für ein Programm das werden soll? Vielleicht lässt sich ja etwas an dem Userinterface drehen, damit die Probleme nicht mehr auftreten ...
 
Das Userinterface ist von unserem UI Designer vorgegeben. ^^ Da lässt sich nichts machen (außerdem macht der blaue Kasten auch nur genau da Sinn). Also der Blaue Kasten ist eigentlich ein Button und mit diesem Button kann man den Layer auf- bzw. zuklappen. Wäre doof, wenn der User erst weit weg scrollen muss, um den zu sehen oder wenn sich nach dem aufklappen die Buttons nicht mehr beim zugehörigen Layer befinden ;)

Deine JS Lösung ist denkbar inperformant. Ich habe mir schon eine akzeptable ausgedacht. Aber es ist halt immer wesentlich schöner wenn's ohne geht, da unser Programm eh verdammt riesig ist und jede CPU killt :D
Meine Lösung: (grob)
Code:
<div> <-- globaler container
    <div> <-- layer container
    </div>
    <div> <-- blaue box container
    </div>
</div>

Der globale container ist erstmal variabel in der Größe, die Buttons richten sich dann am globalen container aus.
In den layer container kommen alle layer und in den blaue box container kommen genau so viele blaue boxen. Alle Boxen und Layer werden durchnummeriert (Array oder was weiß ich was). Und dann wie folgt:
Button8 wurde geklickt -> Layer8 vergrößern. Neue Layer8-Größe auslesen und Panel mit dem Button8 vergrößern. Da ist nicht viel mit rechnen :)



@te one: Ich versteh nicht so ganz was du meinst. Könntest du evtl n paar Zeilen Code schreiben ? :)
 
Mir ist gerade noch eine Idee gekommen, konnte sie aber noch nicht testen. Wenn es reicht immer nur eine gelbe Box scrollen zu können, könntest du diesem die Eigenschaft "overflow:scroll" geben und die blaue Box dann daneben setzen. Ansonsten müsstest du alle gelben Boxen in einen container stecken und dort dann die Eigenschaft setzen. Dann ist es aber sehr schwer deine Vorgabe einzuhalten, dass die blauen Boxen so hoch sein soll wie die gelbe, wenn du sie nicht einfach festlegst. Dazu noch eine Frage, wenn du die höhe der helben Box festlegst wieso dann nicht auch der blauen, dann sind beide gleich hoch.
 
Danke für die Antwort :)

Also, es sollen ALLE gleichzeitig gescrollt werden. Deswegen fällt Lösung 1 weg.
Lösung 2 hatte ich ja im Post davor schon geschildert. Das wäre eine Möglichkeit, eigentlich auch ganz in Ordnung. Mich stört daran nur dieses hin und her:
Blaues Panel kriegt einen Click -> sagt dem gelben es soll sich vergrößern -> gelbes Panel vergrößert sich -> sagt dem blauen es soll sich anpassen -> blaues Panel liest die Größe aus dem gelben aus und vergrößert sich.
Das muss so umständlich gemacht werden, weil bei uns nicht height: 100px (== vergrößern) gesetzt wird, sondern es wird ein neues Panel innerhalb des gelben Layers eingeblendet. Und dieses neue Panel hat eine unbestimmte Größe. Daher kann ich die Höhe vom Blauen erst setzen, wenn das Gelbe sich vergrößert hat.

Naja, wahrscheinlich ist es wirklich die einzige mögliche Lösung ^^
 
Ja gut dann hatte ich deinen vorherigen Post nicht ganz richtig verstanden :D,
Aber mit jquery oder einem vergleichbarem Framework brauchst du so doch nur ca. 5-7 Zeilen javascript code um das zu programmieren, das dürfte ja noch im Rahmen liegen und ist doch noch recht performant.
 
Nur, weil ihm jQuery die Arbeit abnimmt heißt das nicht, dass sie nicht gemacht werden muss ...
 
Liest eigentlch niemand den ersten Beitrag?
Da steht deutlich, dass wir das Google Web Toolkit (GWT) benutzen. Mir ist durchaus klar, dass ich das damit komplett manuell machen kann.
Aber sehen wir den Tatsachen ins Gesicht: Wenn der Browser es selbstständig machen kann per CSS ist es immernoch schneller als wenn da diverse Zeilen JS interpretiert ausgeführt werden müssen. Und das Projekt ist im aktuellen Zustand schon extrem riesig. Ich rede hier von durchschnittlich 500-1000 <div>-Elementen. Wovon dann auch noch sehr viele animiert sind (per JS) und in etwa jedes 5te Element Events durch den kompletten DOM-Tree schießt.
Wenn man es richtig anstellt kann man auch auf 10000 div-Elemente kommen ;) Je nach dem, was der User so mit dem Programm anstellt. Und dann ist es wohl auch klar, dass ich extrem auf Performance und möglichst wenig Code im DOM-Baum achte ;)
 
Mal 'ne dumme Frage: Was soll das für eine Software werden?

Das klingt für mich irgendwie so halbdurchdacht - wäre es da nicht wesentlich intelligenter, eine "richtige" Programmiersprache zu nutzen?
 
Ich hab eine Art NDA unterschrieben, aber in einem Monat ca. gibt's die öffentliche BetaPhase :)
Zur Zeit kann ich euch nur Homepage der Firma zeigen (die quasi 0 Inhalt hat): http://www.farfromhomepage.net/

Und nein, es ist schon voll durchdacht. Das Programm ist quasi Web 2.0 wie es leibt und lebt. Und es soll Geräteunabhängig funktionieren. Deshalb haben wir nicht sonderlich viel Auswahl an Programmiersprachen ;)
Flash fällt raus und Java Applets auch. Die ganzen serverseitigen Sprachen auch, da es zu 99% auf Benutzerinteraktion basiert ;)

Und wenn man sich die ganzen großen Webapps von Google anschaut, dann bin ich mir sicher, dass GWT genau das richtige ist!
 
Dann bookmarke ich mir den Thread hier mal - da bin ich aber echt gespannt.

Darf man wenigstens fragen, in welche Richtung es geht?
 

Ähnliche Themen

Antworten
23
Aufrufe
1.831
N
Antworten
4
Aufrufe
1.192
Netrunner
N
Zurück
Oben