2016-04-11 14 views
5

Sto provando a produrre il seguente layout, utilizzando flexbox.Ottenere un div altezza al 100% all'interno di un articolo Flexbox

enter image description here

La barra nera in alto, la sezione centrale e la barra nera in basso sono tutti elementi flessibili, che sono figli di un div involucro appena dentro il tag body, che appare come segue.

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="utf-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic' rel='stylesheet' type='text/css'> 
    <link href="~/Styles/bootstrap.min.css" rel="stylesheet" /> 
    <link href="~/Styles/font-awesome.min.css" rel="stylesheet" /> 
    <link href="~/Styles/ppt_site.css" rel="stylesheet" /> 
</head> 
<body> 
    <div class="wrapper"> 

     <div id="topRow"> 
     </div> 

     <div id="centralRow"> 

      <div id="sidebarColumn"> 
      </div> 

      <div id="contentColumn"> 
      </div> 

     </div> 

     <div id="bottomRow"> 
     </div> 

    </div> 

    @Section['customScripts'] 
    <script src="~/Scripts/siteGlobals.js"></script> 

    <script src="~/requireconfig"></script> 
    <script data-main="~/scripts/NewTemplatesAppLoader.js" src="~/requirejs"></script> 

</body> 
</html> 

Il foglio di stile che controlla tutto questo è il seguente

.wrapper, html, body { 
    height: 100%; 
    margin: 0; 
} 

.wrapper { 
    display: flex; 
    -ms-flex-direction: column; 
    -webkit-flex-direction: column; 
    flex-direction: column; 
} 

#topRow { 
    background-color: black; 
    color: white; 
} 

#centralRow { 
    -ms-flex: 1; 
    -webkit-flex: 1; 
    flex: 1; 
    display: flex; 
    -ms-flex-direction: row; 
    -webkit-flex-direction: row; 
    flex-direction: row; 
} 

#bottomRow { 
    background-color: #333333; 
    color: white; 
} 

#sidebarColumn { 
    background-color: #B83B1D; 
    color: white; 
} 

#contentColumn { 
    -ms-flex: 1; 
    -webkit-flex: 1; 
    flex: 1; 
    background-color: #F7F7F7; 
    color: black; 
    padding: 10px; 
    overflow-y: auto; 
} 

Per quanto riguarda il layout principale va, tutto questo funziona perfettamente, si noterà se si guarda l'immagine, il barra laterale rossa come area in alto con un bordo giallo.

Quell'area, è destinata ad essere un div che stende l'intera area rossa (Colonna della barra laterale) nel CSS sopra, ma prova come potrei non riuscire a fare ciò che mi serve.

Idealmente, voglio che sia un div, che è un contenitore flessibile, che posso quindi inserire 4 elementi flessibili e ognuno di loro occupa un quarto dello spazio disponibile ciascuno, ma perché il div con il giallo non sembra che il bordo veda l'altezza del contenitore genitore (la barra laterale rossa, che è un oggetto flessibile stesso), ma prende sempre solo l'altezza dello spazio attorno al suo contenuto.

Ho provato a racchiuderlo in più div e posizionando quelle div, ho avvolto ulteriori flex box in ulteriori div, ho provato blocchi, inline, celle di tabella e praticamente tutto quello che posso pensare.

Non importa quello che provo, non riesco proprio a ottenere che il contenitore con bordi gialli abbia la stessa altezza di un genitore.

Qualche idea a qualcuno?

Update (Il mattino seguente)

Le 2 soluzioni proposte, effettivamente il lavoro, nel loro diritto e funzionano come li avrei aspettato troppo.

Nel mio caso particolare, tuttavia, non funzionano.

Sto utilizzando NancyFX con il suo motore di visualizzazione super semplice e sto utilizzando KnockoutJS per comporre "Componenti Web" in modo da poter riutilizzare i miei pezzi.

Se modifico il mio "modello principale" e inserisco i div direttamente nel markup, nidificati sotto #sidebarColumn ottengo i 4 div di uguale dimensione come desiderato.

Tuttavia, ciò che in realtà deve accadere è il seguente, il mio modello si presenta come segue:

<div class="wrapper"> 

    <div id="topRow"> 
     @Section['topbarContent'] 
    </div> 

    <div id="centralRow"> 

     <div id="sidebarColumn"> 
      @Section['sidebarContent'] 
     </div> 

     <div id="contentColumn"> 
      @Section['bodyContent'] 
     </div> 

    </div> 

    <div id="bottomRow"> 
     @Section['bottombarContent'] 
    </div> 

</div> 

Se rimuovo il "@Section [ 'sidebarContent']" e mettere direttamente i div in cui lavorano.

Se metto le div direttamente nella mia "pagina" che utilizza il modello come segue:

@Master['shared/ppt_layout.html'] 

@Section['topbarContent'] 
    <toptoolbar></toptoolbar> 
@EndSection 

@Section['sidebarContent'] 
    <div>aaa</div> 
    <div>aaa</div> 
    <div>aaa</div> 
    <div>aaa</div> 
@EndSection 

@Section['bodyContent'] 
    <h1>Body Content</h1> 
    <p class="lead">I am the test page that uses a wide sidebar component</p> 
    <p>If you notice however, I also have a top toolbar with title added to me, and a footer bar.</p> 
    <p>We all use the same template however....</p> 
@EndSection 

@Section['bottombarContent'] 
    <footerbar></footerbar> 
@EndSection 

@Section['customScripts'] 
@EndSection 

che funziona anche, ma se metto il markup in un componente ad eliminazione diretta, anche solo le div dritto come funziona nella pagina, quindi ottengo l'effetto che avevo inizialmente notato.

Quindi, per qualche motivo, l'aggiunta del contenuto, utilizzando componenti ad eliminazione diretta, è proprio la causa del problema.

Anche se provo a creare un nuovo layout flessibile all'interno del componente, in verticale non funziona affatto, tuttavia in orizzontale tutto funziona perfettamente.

Il footer bar, ad esempio, è suddiviso in sezioni sinistra e destra senza problemi, ma l'allineamento verticale viene annullato.

risposta

2

Così, dopo quello che sembra giorni di torture, ho finalmente capito qual è il problema.

Sto usando knockout.js nel mio progetto, in particolare componenti a eliminazione diretta, ed è la barriera tra questi che causa il problema.

Per coloro che non hanno utilizzato componenti KO prima, è un processo abbastanza semplice. Si costruisce un modello di visualizzazione JS e un piccolo frammento di codice HTML per fornire la superficie di visualizzazione dei componenti.

È quindi utilizzare:

ko.components.register("myComponent", { 
    viewModel: "Components/myComponent.js", 
    template: "Components/myComponent.html" 
}); 

ko.applyBindings(); 

Per registrare il componente.

volta che il componente è registrato, si può poi semplicemente utilizzarlo mettendo

<myComponent></myComponent> 

Dove mai si desidera aggiungere nella vostra pagina web.

Ora tutto va bene e dandy, MA ... quando KO crea un'istanza del componente, lascia il tag personalizzato in posizione.

Quindi, se si immagina che il componente assomiglia in modo

<div> 
    <div>Item...</div> 
    <div>Item...</div> 
    <div>Item...</div> 
    <div>Item...</div> 
</div> 

e la pagina si presenta come

<body> 
    <div> 
     <myComponent></myComponent> 
    </div> 
</body> 

L'uscita finale sarà simile

<body> 
    <div> 
     <myComponent> 
      <div> 
       <div>Item...</div> 
       <div>Item...</div> 
       <div>Item...</div> 
       <div>Item...</div> 
      </div> 
     </myComponent> 
    </div> 
</body> 

Dato che la le regole del CSS di cui sopra, la mia e entrambi i responder stavano prendendo di mira il div wrapper, la regola era nev er corrispondente al div target per consentire il flex su di esso.

La chiave (come ho trovato attraverso tentativi ed errori) è quello di utilizzare il nome del tag personalizzato, EG:

#sidebarColumn > narrowsidebar { 
    width: 70px; 
    flex: 1; 
    display: flex; 
    flex-direction: column; 
} 

e poi, scendere ulteriormente le operazioni di flex da quel genitore.

Tuttavia, non spiega ancora perché, quando si esegue il layout completo di una flexbox da zero all'interno del componente (ovvero senza operazioni di flessione nella pagina Web principale e/o nel modello), il problema persiste allineamento verticale, per quanto posso vedere, KO non fa nulla al dom che dovrebbe causare questo comportamento.

Per il mio problema iniziale, tuttavia, il targeting tramite il tag personalizzato mi ha portato dove dovevo essere.

Shawty

1

È possibile utilizzare FlexBox nidificato:

<div id="sidebarColumn"> 
    <div>...</div> 
    <div>...</div> 
    <div>...</div> 
    <div>...</div> 
</div> 

#sidebarColumn { 
    display: flex; 
    flex-direction: column; 
} 
#sidebarColumn > div { 
    flex: 1; 
} 

jsFiddle

+0

Ok, quindi la soluzione proposta funziona in modo indipendente proprio come mi aspettavo troppo, ma non funziona nel mio progetto, io invece ho la risposta perché adesso. – shawty

+0

Felice di vedere che l'hai capito, altrimenti potrebbe essere troppo difficile per chiunque altro vedere cosa stava succedendo lì. – Stickers

+0

Sì, è stata una sfida, devo ammettere ... – shawty

1

Usa flex: 1 ad un bambino flex per renderlo abbracciano lo spazio più possibile

.wrapper, html, body { 
 
    height: 100%; 
 
    margin: 0; 
 
    padding:0; 
 
} 
 

 
/* header */ 
 
#topRow { 
 
    background-color: black; 
 
    color: white; 
 
    height:20%; 
 
} 
 

 
/* footer */ 
 
#bottomRow { 
 
    background-color: #333333; 
 
    color: white; 
 
    height:10%; 
 
} 
 

 
/* main */ 
 
#centralRow { 
 
    height:70%; 
 
    display: flex; 
 
} 
 

 
/* sidebar */ 
 
#sidebarColumn { 
 
    background-color: #B83B1D; 
 
    color: white; 
 
    width:20%; 
 
    display: flex; 
 
    flex-direction: column; 
 
} 
 

 
#sidebarColumn nav { 
 
    padding:1em; 
 
    border:1px solid yellow; 
 
    flex:1; 
 
} 
 

 
/* content */ 
 
#contentColumn { 
 
    overflow: auto; 
 
    flex:1; 
 
} 
 

 
.big { 
 
    border:1px solid red; 
 
    margin:1em; 
 
    height:400px; 
 
}
<div class="wrapper"> 
 

 
    <div id="topRow"> 
 
    header 
 
    </div> 
 

 
    <div id="centralRow"> 
 
    <div id="sidebarColumn"> 
 
     sidebar 
 
     <nav> 
 
     nav links 
 
     </nav> 
 
    </div> 
 
    <div id="contentColumn"> 
 
     body content 
 
     <div class="big">some big content</div> 
 
    </div> 
 
    </div> 
 

 
    <div id="bottomRow"> 
 
    footer 
 
    </div> 
 
</div>

https://jsfiddle.net/azizn/y4hag5o3/

+0

Come con l'altra soluzione, questo funziona da solo, ma si rifiuta di lavorare nel mio progetto. – shawty

Problemi correlati