HartleySan
HartleySan

Reputation: 7810

How do I create this layout using CSS flexbox?

I'm trying to create the following basic layout:

enter image description here

And I'm currently using the following basic HTML markup (with slightly different class names and additional markup within each of the HTML elements):

<div class="siteContainer">
    <div class="sidebar">
        <div class="topGreenStrip">
        </div>
        <div class="sidebarContainer">
            <div class="sidebarInnerContainer">
                <div class="brownSection">
                </div>
                <div class="purpleSection">
                </div>
                <div class="pinkSection">
                </div>
                <div class="redSection">
                </div>
            </div>
            <div class="rightOrangeStrip">
            </div>
        </div>
    </div>
    <div class="lightPurpleContent">
    </div>
</div>

And then the following starting CSS for the markup above:

.sidebar {
    bottom: 0;
    display: flex;
    flex-direction: column;
    left: 0;
    position: fixed;
    top: 0;
    width: 300px;
}

.topGreenStrip {
    height: 5px;
    justify-self: flex-start;
}

.sidebarContainer {
    flex-grow: 1;
    justify-self: stretch;
}

The problem I'm having though is that because I start by stretching everything vertically with flexbox, I don't know how to then stretch things horizontally but still keep everything 100% the height of the screen.

That is, minus the 5px green top strip, I want the rest of the sidebar to occupy 100% the height of the screen. The large pink section should fill in whatever the brown, purple and red sections don't naturally.

I was able to get that part working without the orange bar by using justify-self: flex-start;, justify-self: stretch; and justify-self: flex-end;. However, once I add the orange bar in, I don't know how to keep doing what I'm doing.

The orange bar has a bit of dynamic content in it, so I can't set a static width, and the brown, purple, pink and red sections should use whatever width is not taken up by the orange bar (I'm assuming with flex-grow: 1;).

Anyway, how do I get this layout where (within the sidebar), I'm trying to stretch things both to 100% the height and 100% the width? Can I do this with just flexbox, or am I going to have to used positioned/floated elements to get this all to work?

Sorry for the vagueness, but after trying several things and getting nowhere close, I'm not sure where to begin. Thank you.

Upvotes: 0

Views: 97

Answers (1)

itodd
itodd

Reputation: 2373

You need to make use of flex-direction: column on certain elements to stack the children. Also, using flex: 1 will force that element to grow and fill available space in it's parent.

By setting height: 100% on the html and body you can stretch .siteContainer to be the full height of the window.

I've added the background colours so you can see the layout in action.

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

.siteContainer {
  display: flex;
  height: 100%;
}

.sidebar {
  display: flex;
  flex-direction: column;
  width: 300px;
}

.topGreenStrip {
  height: 5px;
}

.sidebarContainer {
  flex: 1;
  display: flex;
}

.sidebarInnerContainer {
  display: flex;
  flex-direction: column;
  flex: 1;
}

.pinkSection,
.lightPurpleContent {
  flex: 1;
}

.topGreenStrip { background: green; }
.brownSection { background: peru; }
.purpleSection { background: darkviolet ; }
.pinkSection { background: pink; }
.redSection { background: red; }
.rightOrangeStrip { background: orange; }
.lightPurpleContent { background: lavender; }
<div class="siteContainer">
    <div class="sidebar">
        <div class="topGreenStrip">green
        </div>
        <div class="sidebarContainer">
            <div class="sidebarInnerContainer">
                <div class="brownSection">brown
                </div>
                <div class="purpleSection">purple
                </div>
                <div class="pinkSection">pink
                </div>
                <div class="redSection">red
                </div>
            </div>
            <div class="rightOrangeStrip">orange
            </div>
        </div>
    </div>
    <div class="lightPurpleContent">lightpurple
    </div>
</div>

Upvotes: 2

Related Questions