3

I have the following markup:

.content {
  display: flex;
}
<div class="content">
  <div class="contact">email@example.com</div>

  <div class="branding">
    <h1>Name</h1>
    <img src="http://lorempixel.com/200/200" />
  </div>

</div>

I essentially want the contact div to appear top-right of the window and the branding div to be centered on the remaining space on the page; i.e. I don't want the branding div to overlap the contact div at any point.

How would I achieve this with flexbox?

Update: here is an example of the desired layout: enter image description here

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
harryg
  • 23,311
  • 45
  • 125
  • 198
  • 2
    Do you have an image of the desired result? Is the centering vertical/horizontal or both...it's not clear from your question? – Paulie_D Oct 21 '15 at 14:19
  • To reopen voters: this question is still unclear regarding layout details. Providing a desired layout would invalidate at least one and possibly all of the answers. Also let's try to avoid voting on questions where we have no experience on the tags... – TylerH Oct 21 '15 at 21:24
  • I've added a layout to clarify the question – harryg Oct 22 '15 at 07:59
  • @TylerH, I'm not clear why the rush to close this question. The OP, in my view, clearly states the layout he is working to achieve. The key paragraph in the question, which I highlighted in my answer, is clear, unambiguous and straightforward. There are three parts to the layout as described in the paragraph. *What part is not clear?* – Michael Benjamin Oct 22 '15 at 15:30
  • Also, I can understand that different people reading a question may not fully understand it (I admit that happens to me sometimes), but to blame the OP isn't always fair. For what it's worth, I don't feel the OP needed to edit the text or add an illustration. – Michael Benjamin Oct 22 '15 at 15:31
  • @Michael_B Now that OP has added more details (via screenshot) of the layout he wants, it's no longer unclear. Before that, it wasn't clear whether OP wanted the divs displayed above one another, side by side, etc. Declaring he wanted them one above the other would invalidate my answer. Declaring he wanted them side by side would invalidate yours, etc. – TylerH Oct 22 '15 at 15:31
  • Yeah, we discussed this before. Thanks for your response. – Michael Benjamin Oct 22 '15 at 15:32

3 Answers3

4

I essentially want the contact div to appear top-right of the window and the branding div to be centered on the remaining space on the page; i.e. I don't want the branding div to overlap the contact div at any point.

CSS

html, body { height: 100%; } /* enable percentage height for flex container */

.content {
    display: flex;
    flex-direction: column;
    height: 100%; /* give the flex container a height */
}

.contact {
    align-self: flex-end; /* align-right */
}

.branding {
    margin: auto; /* center branding div in container */
}

DEMO

With the code above, the contact div appears top-right of the window, the branding div is centered on the page, and there is no overlap at any time.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • The branding div is clearly overlapping the contact div here. – TylerH Oct 21 '15 at 14:22
  • You see how your red-bordered element is *within* the area of the green-bordered element? That is overlap. Your divs are 100% overlapping. – TylerH Oct 21 '15 at 14:25
  • @TylerH, the green border represents to primary flex container. The `.contact` and `.branding` divs are in red borders. They don't overlap at any time, like required in the question. – Michael Benjamin Oct 21 '15 at 14:29
  • I see, in that case I'm not sure why you have a green border in the first place, considering JSFiddle includes grey resizable borders around the iframe to begin with. – TylerH Oct 21 '15 at 14:33
  • @TylerH, I added the key part of the question to my answer. The green border was included to outline the flex container, just as a matter of clarity and consistency (with the other bordered elements). – Michael Benjamin Oct 21 '15 at 14:35
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/92980/discussion-between-tylerh-and-michael-b). – TylerH Oct 21 '15 at 14:36
  • This is the best answer I could see. Only problem I had was that any padding of the `contact` div is squashed away when the viewport height is reduced. Otherwise does exactly what I asked – harryg Oct 21 '15 at 15:12
  • @harryg, the text in the `.contact` div is considered an [*anonymous flex item*](http://stackoverflow.com/a/33139215/3597276) and is therefore unselectable, and therefore, unstyleable. Simply wrap the content in a `span`, then you can style it. Here's an updated demo with padding: http://jsfiddle.net/ky2k7jdr/3/ – Michael Benjamin Oct 21 '15 at 15:17
  • @harryg, there's actually an even more efficient way to achieve your layout. The nested flex container in the `content` div isn't necessary. I've updated the answer and demo. – Michael Benjamin Oct 21 '15 at 16:53
  • This answer may be useful, as well: [Methods for Aligning Flex Items along the Main Axis](http://stackoverflow.com/a/33856609/3597276) – Michael Benjamin Nov 22 '15 at 16:55
1

Here's one way to do it, though I think it will be better once CSS Grid Layouts gets better support.

The lightgrey background is just to show that the branding div is in fact taking up the rest of the space. As you can see, there's no overlap.

.content {
    display: flex;
    flex-direction: row-reverse;
}

.branding {
    width: 100%;
    background: lightgrey;
    text-align: center;
}
<div class="content">
    <div class="contact">email@example.com</div>
    <div class="branding">
        <h1>Name</h1>
        <img src="http://lorempixel.com/200/200" />
    </div>
</div>

Here's an external JSFiddle, too.

TylerH
  • 20,799
  • 66
  • 75
  • 101
  • 1
    Maybe it's my browser (Chrome 46) but there is no centering there. The branding and content appear side-by-side and are both aligned at the top of the page – harryg Oct 21 '15 at 15:14
  • @harryg I missed that keyword; the branding div's content is centered now. As for being side by side; you didn't specify in your question how you wanted them to be laid out; side-by-side or one over the other, as Paulie_D mentioned in his comment. – TylerH Oct 21 '15 at 15:30
-1

You can do this:

COLUMNS

CSS

.content {
    display: -webkit-flex;
    display: flex;
    -webkit-flex-flow: row-reverse nowrap;
    flex-flow: row-reverse nowrap;
}
div {
    -webkit-flex: none;
    flex: none;
}
.branding {
    -webkit-flex: 1 0 auto;
    flex: 1 0 auto;
    align-items:center;
    text-align:center;
}

HTML

<div class="content">
    <div class="contact">email@example.com</div>
    <div class="branding">
         <h1>Name</h1>

        <img src="http://lorempixel.com/200/200" />
    </div>
</div>

DEMO HERE

ROWS

CSS

.content {
    display: -webkit-flex;
    display: flex;
    -webkit-flex-flow: column nowrap;
    flex-flow: column nowrap;
}
div {
    -webkit-flex: none;
    flex: none;
}
.contact {   
    text-align:right;
}


.branding {
    -webkit-flex: 1 0 auto;
    flex: 1 0 auto;
    align-items:center;
    text-align:center;
}

HTML

<div class="content">
    <div class="contact">email@example.com</div>
    <div class="branding">
         <h1>Name</h1>

        <img src="http://lorempixel.com/200/200" />
    </div>
</div>

DEMO HERE

Luís P. A.
  • 9,524
  • 2
  • 23
  • 36