[CSS]Menu: header, content en footer-met-variabele-lengte

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • SilentStorm
  • Registratie: November 2000
  • Laatst online: 27-04 11:59
[CSS]Menu: header, content en footer-met-variabele-lengte

Allereerst maar even een 'plaatje', voor de duidelijkheid:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
________________________________________________________
|         HEADER                                        |
|_______________________________________________________|
_______________________    _____________________________
|   TAB1   |  TAB2     |  |                             |
|______________________|  |                             |
|                      |  |       //rest van app        |
|    Content           |  |                             |
|                      |  |                             |
|                      |  |                             |
|______________________|  |                             |
|    [input field 1]   |  |                             |
|                      |  |                             |
|  <prev   |   next>   |  |                             |
|______________________|  |_____________________________|
________________________________________________________
|         FOOTER                                        |
|_______________________________________________________|


situatie
Ik ben bezig met een webapp, waarin aan de linkerkant van het scherm een panel (fixed-height div) in het midden staat.

Aan de bovenkant van deze div staat
• een div (fixed-height) met twee 2 controls ('tabbladen'), die de inhoud van het content-divje aanpassen.
• een div met content (variabel in lengte)
• een div met navigatie-knoppen ('vorige-volgende' en nul tot 3 invoervelden en daardoor ook variabel in lengte)[/li]

(de invoervelden zouden desgewenst in een ander divje kunnen, maar zijn in aantal nog steeds variabel)

Ik zie op het forum al allemaal problemen bij mensen die proberen een fixed-length header en footer te gebruiken (ik gebruikte deze termen in de topictitle ook voor de beide control-divjes in het menu).

gewenste situatie
• De menu-header en de menu-footer zijn altijd volledig zichtbaar en de content gebruikt de overige ruimte en heeft een scrollbar als hij niet volledig zichtbaar is.
• De menu-footer hangt altijd tegen de onderkant van het panel.

spoiler:
Bullet 2, hierboven vereist (afaik) dat de menu-footer op zijn minst deze layout krijgt:

position:absolute;bottom:0px;

Als de footer absoluut is gepositioneerd, gaat de content-div over de footer heen lopen. Het aanpassen van de z-index zorgt daarbij niet voor een andere uitlijning.


probleem
Ik krijg het niet voor elkaar om de content div goed te positioneren.

Tenzij ik een vaste hoogte opgeef, helpt het toevoegen van een scrollbar niets en ik weet niet wat de vaste hoogte moet zijn, omdat die afhangt van de grootte van de menu-footer. Als ik een andere hoogte opgeef, bv 100% (heeft geen effect zonder position:absolute en let daarna nog steeds niet op de menu-footer) of auto (doet uberhaupt niets), blijft de content doorlopen, voorbij het omsluitende panel.
Ik zit al twee dagen te spelen met (vooral) display, position, height en overflow attributen, maar krijg het nog steeds niet voor elkaar.

[ Voor 0% gewijzigd door SilentStorm op 20-10-2009 14:25 . Reden: [code] tags werken niet in spoiler, [li] werkt niet met [*] ]

Localhost is where the heart is


Acties:
  • 0 Henk 'm!

  • mcDavid
  • Registratie: April 2008
  • Laatst online: 25-05 10:12
Ik zal vast niet de enige zijn die totaal geen kaas kan maken van deze chaotische topicstart. Echter klinkt het wel als een interessant probleem, dus kom eens met wat code-voorbeeldjes!

Acties:
  • 0 Henk 'm!

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Met ^

In plaats van alles proberen te omschrijven a.d.h.v. ASCII art met naamgeving die inconsistent is tussen plaatje en tekst, gewoon een minimaal voorbeeld online zetten ergens, want zo is er geen touw aan vast te knopen.

menu-header, menu-footer, welk menu heb je het over? Wat is nou content, het vakje genaamd content in de ASCII art? Of is dat het menu? Wat moet een variabele lengte hebben?

En spoiler tags? Kom nou...

"Any sufficiently advanced technology is indistinguishable from magic."


Acties:
  • 0 Henk 'm!

  • SilentStorm
  • Registratie: November 2000
  • Laatst online: 27-04 11:59
Blijkbaar heb ik mezelf niet helemaal duidelijk gemaakt. Ik dacht dat ik het conceptueel duidelijker maakte met de term menu-header en menu-footer. Laat me het op een andere manier proberen, met wat code erbij.

Ik liet net dit plaatje zien voor de hele applicatie:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
________________________________________________________
|         HEADER                                        |
|_______________________________________________________|
_______________________    _____________________________
|   TAB1   |  TAB2     |  |                             |
|______________________|  |                             |
|                      |  |       //rest van app        |
|    Content           |  |                             |
|                      |  |                             |
|                      |  |                             |
|______________________|  |                             |
|    [input field 1]   |  |                             |
|                      |  |                             |
|  <prev   |   next>   |  |                             |
|______________________|  |_____________________________|
________________________________________________________
|         FOOTER                                        |
|_______________________________________________________|


Het relevante menu hierin is dit:

code:
1
2
3
4
5
6
7
8
9
10
11
12
_______________________ 
|   TAB1   |  TAB2     |
|______________________|
|                      |
|    Content           |
|                      |
|                      |
|______________________|
|    [input field 1]   |
|                      |
|  <prev   |   next>   |
|______________________|


Het bestaat uit 3 onderdelen:

de menu-header (tabbladen):
code:
1
2
3
 ______________________ 
|   TAB1   |  TAB2     |
|______________________|


De content:
code:
1
2
3
4
5
6
 ______________________
|                      |
|    Content           |
|                      |
|                      |
|______________________|


En de menu-footer:
code:
1
2
3
4
5
 ______________________
|    [input field 1]   |
|                      |
|  <prev   |   next>   |
|______________________|


De laatste heeft altijd 2 knoppen (vorige / volgende) en soms invoervelden (nul tot 3).

Wat ik wil is dat de menu-header, (bovenste div) die een vaste grootte heeft, en de menu-footer, (onderste div) die een variabele lengte heeft, altijd zichtbaar zijn, en dat de content (middelste div) de overige ruimte gebruikt om zoveel mogelijk van zichzelf te laten zien (en de rest via een scrollbar).

in html ziet de structuur er ongeveer zo uit:

HTML:
1
2
3
4
5
6
7
<div id="menu" class="menuStyle">
  <div id="tab-box"> <!-- geen style -->
    <div id="tabs" class="tabsStyle"> [...] </div>
    <div id="content" class="contentStyle">  [...] </div>
    <div id="navigation" class="navigationStyle">  [...] </div>
  </div>
</div>


Ik postte eerder geen css, omdat dat juist is waar ik probeer achter te komen -- hoe de css voor deze elementen er uit moet zien om het gevraagde voor elkaar te krijgen. Bij wijze van voorbeeld hieronder echter een styleset die niet doet wat ie moet doen, maar wel behoorlijk in de buurt komt.

Cascading Stylesheet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.menuStyle {
  display:inline
  float:left
  height:424px;
  position:relative;
  overflow:visible;
}

.tabStyle {
  display:inline;
  float:left;
}

.contentStyle {
  clear:both;
  height:100%;
  overflow-y:scroll;
}

.navigationStyle {
  position:absolute;
  bottom: 0px;
}


Ik hoef ook niet meteen een hapklare oplossing voor mijn specifieke probleem, maar zoek vooral naar de 'denkrichting', waarmee het beschreven gedrag kan worden verkregen.

Localhost is where the heart is


Acties:
  • 0 Henk 'm!

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Kijk, dat willen we zien :) Code met divs met de juiste IDs maakt het een stuk makkelijker om precies te snappen waar je het over hebt. Ik zal er eens een blik op werpen vanavond.

"Any sufficiently advanced technology is indistinguishable from magic."


Acties:
  • 0 Henk 'm!

  • SilentStorm
  • Registratie: November 2000
  • Laatst online: 27-04 11:59
Thanks! Het is maar een labeltje, maar ik snap dat het zonder dat ietwat onduidelijk werd. Ik heb zelf ook nog even een volledig werkend voorbeeldje in elkaar gesleuteld. Zie hieronder.

HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
    <title>test</title>
    <style type="text/css">
      .menuStyle { 
        display:inline;
        float:left;
        height:300px;
        position:relative; 
        overflow:visible;        
        background-color:#00FF00;        
        width: 300px;
      } 
      
      .tabsStyle { 
        background-color:#00FFFF;
        height: 20px;
      } 
      
      .contentStyle {  
        height:80%; 
        overflow-y:scroll;        
        background-color:#EEEEEE;        
      } 
      
      .navigationStyle { 
        position:absolute; 
        bottom: 0px;        
        background-color:#FF0000;
        width:100%;
      }
      
      .applicationStyle {
        background-color:#FFFF00;
        float:right;
        width:250px;
        height:300px;        
      }
    </style>
  </head>
  <body>
    <div id="page" style="width:600px; height 400px;">
        <div id="menu" class="menuStyle"> 
          <div id="tab-box"> <!-- geen style --> 
            <div id="tabs" class="tabsStyle"> Tabs </div> 
            <div id="content" class="contentStyle">  

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc mollis
pellentesque placerat. Donec dignissim luctus libero vitae cursus.
Vestibulum vulputate tellus magna, eget scelerisque justo.
Suspendisse velit neque, vestibulum non tristique vitae, pellentesque
id neque. Duis auctor metus nec arcu ultrices fringilla. Nunc non
libero a turpis ultrices faucibus. Curabitur volutpat felis nec lectus
semper faucibus molestie dolor ullamcorper. Cras viverra felis a ligula
auctor ac pulvinar urna sollicitudin. Nulla pharetra ipsum at odio
dapibus sollicitudin. Quisque aliquet volutpat dui nec ornare. Maecenas
euismod sapien in nulla tincidunt lacinia. raesent porta vulputate
vehicula. Vestibulum condimentum hendrerit gravida. Praesent auctor
facilisis hendrerit. Aliquam vel arcu vel sem cursus adipiscing vel ac
nisl. Nulla vulputate sagittis elit, eget pulvinar mi commodo non.
Fusce vitae scelerisque neque. 

            </div> 
            <div id="navigation" class="navigationStyle">

 [inputBox] <br> prev | next

           </div> 
          </div><!-- tab-box -->
        </div><!-- menu -->
        <div id="application" class="applicationStyle">

 app

      </div>    
    </div><!-- page -->
  </body>
</html>


Dit lijkt trouwens ongeveer te werken in ie6, maar dat is omdat die wel let op de 'height:80%' voor de content. Deze waarde is overigens volslagen willekeurig. Waar het om gaat is dat de grootte van de content box wordt bepaald door 'de ruimte die overblijft na het plaatsen van de 'tabs' en de 'navigation'.

Het gaat hierbij ook enkel om de visuele layout, dwz, deze indeling in divjes is niet heilig, al denk ik niet dat je er iets aan hebt om bv de navigatie op hetzelfde niveau als de tab-box te zetten, want hier verplaats je het probleem alleen maar mee.

Localhost is where the heart is


Acties:
  • 0 Henk 'm!

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
In FF 3.5 werkt die niet, de navigation valt over de content. Ik ben even aan het kijken of ik er wat van kan maken (hou wel van een CSS puzzeltje ;)).

Edit: ik heb even e.e.a. geprobeerd, maar de variabele hoogte van "navigation" lijkt de killer te zijn.

Ik moet morgen op de zaak nog even kijken naar een oplossing die we een keer voor een klant gebouwd hebben, maar ik meen me te herinneren dat daarvoor JavaScript nodig was (de hoogte was daar door de gebruiker aanpasbaar, dus JavaScript hadden we toch nodig).

[ Voor 120% gewijzigd door Herko_ter_Horst op 20-10-2009 22:40 ]

"Any sufficiently advanced technology is indistinguishable from magic."


Acties:
  • 0 Henk 'm!

  • SilentStorm
  • Registratie: November 2000
  • Laatst online: 27-04 11:59
Iig bedankt voor de moeite :) -- ik zat ook al even te kijken naar een soort body onload variant, maar omdat de box ook groter kan worden bij errormessages die betrekking hebben op de velden, is de hoogte niet vast en zou je ook daar weer javascript moeten toevoegen. Uiteindelijk zit daar waarschijnlijk wel een oplossing, maar met divjes zou toch veel mooier zijn :X :P
In FF 3.5 werkt die niet, de navigation valt over de content. Ik ben even aan het kijken of ik er wat van kan maken (hou wel van een CSS puzzeltje ).

Edit: ik heb even e.e.a. geprobeerd, maar de variabele hoogte van "navigation" lijkt de killer te zijn.
Dat was inderdaad waar ik ook mee zat. De andere foute variant is dat navigation op relatieve positionering staat. Hierbij is de content altijd zo lang als zijn inhoud en komt de navigation daar nog weer onder.

Ik heb een collega er nog even mee laten stoeien via tables, maar die kwam er daarmee ook niet uit. Blijkbaar heb ik een probleem dat niet met styling alleen is op te lossen..

Localhost is where the heart is


Acties:
  • 0 Henk 'm!

  • Da Weef
  • Registratie: Januari 2004
  • Laatst online: 25-05 11:25
Volgens mij gaat de exacte functionaliteit die je wilt alleen lukken met gebruik van javascript. In CSS kun je deze functionaliteit enkel benaderen. Een mogelijke benadering is door de content div op de header na de rest van de menu div te laten vullen en dan de navigation div absoluut te plaatsen op de bodem van de menu div. Als je dan de content div een padding-bottom geeft die groter is dan de maximale hoogte van de navigation div, krijg je iets wat erop begint te lijken.

In jouw CSS wordt dat bijvoorbeeld:

HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
    <title>test</title>
    <style type="text/css">
      .menuStyle { 
        display:inline;
        float:left;
        height:300px;
        position:relative;      
        background-color:#00FF00;        
        width: 300px;
      } 
      
      .tabsStyle { 
        position:absolute;
        background-color:#00FFFF;
        height: 20px;
      } 
      
      .contentStyle {  
        float:left;
        margin-top:20px;
        padding-bottom:60px; <!-- max hoogte navigation div -->
        height:220px;
        overflow-y:scroll;        
        background-color:#EEEEEE;        
      } 
      
      #tab-box{
        float:left;}
        
      .navigationStyle { 
        position:absolute; 
        bottom: 0px;        
        background-color:#FF0000;
        width:100%;
      }
      
      .applicationStyle {
        background-color:#FFFF00;
        float:right;
        width:250px;
        height:300px;        
      }
    </style>
  </head>
  <body>
    <div id="page" style="width:600px; height 400px;">

        <div id="menu" class="menuStyle"> 
            <div id="tabs" class="tabsStyle"> Tabs </div> 
            <div id="content" class="contentStyle">  

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc mollis
pellentesque placerat. Donec dignissim luctus libero vitae cursus.
Vestibulum vulputate tellus magna, eget scelerisque justo.
Suspendisse velit neque, vestibulum non tristique vitae, pellentesque
id neque. Duis auctor metus nec arcu ultrices fringilla. Nunc non
libero a turpis ultrices faucibus. Curabitur volutpat felis nec lectus
semper faucibus molestie dolor ullamcorper. Cras viverra felis a ligula
auctor ac pulvinar urna sollicitudin. Nulla pharetra ipsum at odio
dapibus sollicitudin. Quisque aliquet volutpat dui nec ornare. Maecenas
euismod sapien in nulla tincidunt lacinia. raesent porta vulputate
vehicula. Vestibulum condimentum hendrerit gravida. Praesent auctor
facilisis hendrerit. Aliquam vel arcu vel sem cursus adipiscing vel ac
nisl. Nulla vulputate sagittis elit, eget pulvinar mi commodo non.
Fusce vitae scelerisque neque. 

            </div> 
            <div id="navigation" class="navigationStyle">

 [inputBox] <br> prev | next

           </div> 
        </div><!-- menu -->
        <div id="application" class="applicationStyle">

 app

      </div>    
    </div><!-- page -->
  </body>
</html>


Dit werkt geloof ik enkel voor standard compliant browsers

Is er trouwens een specifieke reden dat je divs styled via een aparte class ipv de id?

.


Acties:
  • 0 Henk 'm!

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Da Weef schreef op woensdag 21 oktober 2009 @ 11:01:
Is er trouwens een specifieke reden dat je divs styled via een aparte class ipv de id?
Grappig, viel mij ook op. Ik gebruik classes meestal alleen voor herbruikbare layout.

"Any sufficiently advanced technology is indistinguishable from magic."


Acties:
  • 0 Henk 'm!

  • SilentStorm
  • Registratie: November 2000
  • Laatst online: 27-04 11:59
Goede opmerking over het gebruik van classes vs id's.

Het 'tab' element dat ik hier gebruik, is een herbruikbaar component, ik zit het alleen nu wat aan te passen. Als je het inderdaad volgens de regels der kunst wilt doen, is het netter om dat op basis van de id te doen omdat dit een afwijking is van het normale tab element. In de uiteindelijke applicatie doe ik dat wel weer goed, maar thanks voor de aanwijzing :)

De oplossing van Da Weef is helaas niet helemaal toereikend fout omdat het geen rekening houdt met de grootte van het navigation veld. Als er maar 1 regel tekst in staat, is de content nog steeds vrij klein. Als er dan wel veel tekst in staat en een gebruiker veel zou moeten scrollen, zou dat op zijn minst vreemd zijn. De oplossing werkt, zoals hier gegeven ook niet. In firefox wordt de content alleen maar langer en in ie6 gaat de layout helemaal kapot (zoals je trouwens al zei).

Localhost is where the heart is


Acties:
  • 0 Henk 'm!

  • Da Weef
  • Registratie: Januari 2004
  • Laatst online: 25-05 11:25
Het was ook alleen een benadering, ik denk dat je met CSS qua functionaliteit niet veel dichterbij dan dit gaat komen...
Overigens is een oplossing waarbij de menu div iets afwijkt in hoogte afhankelijk van de hoogte van de navigation div dan waarschijnlijk een meer logische benadering

Is het trouwens echt geen mogelijkheid om javascript te gebruiken? En waarom niet?

.


Acties:
  • 0 Henk 'm!

  • SilentStorm
  • Registratie: November 2000
  • Laatst online: 27-04 11:59
Het is niet onmogelijk, het is de tweede keus. Met javascript kom ik er zelf ook wel uit :)

Het enige dat je dan hoeft te doen is de hoogte van het content div vast in te stellen:
content.height = menu.height - tabs.height - navigation.height.

Maar het zou toch niet nodig moeten zijn om bij het laden van je pagina nog eens code moet uitvoeren om wat divjes recht te zetten omdat css dat niet kan?

Localhost is where the heart is

Pagina: 1