7

Following this answer I tried to vertically center my header elements, however I'm having trouble since there's a container element in between that makes sure they're contained within a certain max-width and centered. I applied display: table-cell to this element and now its max-width doesn't work (occupies the whole screen width regardless of its max-width). How to solve this problem?

Markup:

<header class="banner">
  <div class="container">
    <a class="header__branding" href="<?php bloginfo( "wpurl" ); ?>">
      <img src="<?php bloginfo( "template_url" ); ?>/dist/images/baia_logo.svg" />
    </a> 
    <nav class="nav_primary">
      <?php wp_nav_menu( array( 'menu' => 'main menu' ) ); ?>
    </nav>
  </div>
</header>

CSS:

.banner {
    height: 160px;
    width: 100%;
    display: table;
    background: url(../images/header.jpg) 50% 50% repeat-x;
}
.container {
    max-width: 1500px;
    margin-left: auto;
    margin-right: auto;
    overflow: hidden;
    vertical-align: middle;
    display: table-cell;
}    
.header__branding {
    float: left;
    width: 150px;
    height: 52px;
    display: block;
}
.nav_primary {
    float: right;
}
Community
  • 1
  • 1
drake035
  • 3,955
  • 41
  • 119
  • 229
  • So you want `container` and all of it contents centered inside `header`. Regardless of what is inside `container`? – theblindprophet Jul 26 '16 at 18:51
  • Yes I want "container" to be centered within "header". – drake035 Jul 26 '16 at 19:53
  • To clarify, you want: 1. A header, which has a background that covers the whole width of a screen. 2. A container inside that header which is centered and max 1500px wide. 3. A logo on the left and navigation on the right side of said container. – vkopio Jul 29 '16 at 20:04

4 Answers4

5

Here is an answer to your question exactly. I will leave the old one as an alternative.

The problem

From CSS 2.2 Specification:

In CSS 2.2, the effect of 'min-width' and 'max-width' on tables, inline tables, table cells, table columns, and column groups is undefined.

So it seems there is no way of adding a max-width to a table-cell currently. You could add a table-cell to each side of the container and set a 1500px width to the container with media queries but this isn't preferred as there is a workaround.


A solution

If you want to limit the width of the nav provided in your link to 1500px you can add a container like you did but the block structure should be a little different.

Now you have:

  • banner as a table
  • container as a table-cell
  • header_branding and nav_primary as blocks inside the cell

Consider changin the structure to following:

  • banner to a block
  • container to a table
  • header_branding and nav_primary to table-cells

The banner is only a 100% wide background element.

Then give the container a max-width of 1500px like you did but remember to give it a 100% width also. Otherwize it wont try to expand to the whole width of the screen as it doesn't have to but now the max-width will be a limiting factor.

Here is a CodePen example provided here but with a container limiting the width to 1500px.

Your example modified:

.banner {
    width: 100%;
}

.container {
    max-width: 1500px;
    width: 100%;
    height: 160px;
    margin: auto;
    overflow: hidden;
    display: table;
}

.header_branding, .nav_primary {
    vertical-align: middle;
    display: table-cell;
}

.header_branding {
    width: 150px;
    height: 52px;
}

.nav_primary {
    text-align: right;
}

/* To make edges visible for the demo */
.banner, .container, .header_branding, .nav_primary { 
    background: rgba(0, 0, 0, 0.3);
    border: 1px dotted red;
}
<header class="banner">
  <div class="container">
    <a class="header_branding" href="">
      <img src="" />
    </a>
    
    <nav class="nav_primary">
      [Menu items]
    </nav>
  </div>
</header>
Community
  • 1
  • 1
vkopio
  • 914
  • 1
  • 11
  • 28
  • Thanks! But you didn't really address the problem as presented in the question, which was to vertically center the "container" element itself. Instead, you center its content within "container". So in my case I would set a fixed height to "container" equal to the fixed height of "banner" element right? That's my understanding of your answer, correct me if I'm wrong. – drake035 Aug 01 '16 at 15:20
  • Basically the header element is just a wrapper to give you a 100% width background at all times. The container element is your table with the vertically centered content which is limited to 1500px max-width. I can update this answer to include your code modified to make it more understandable. – vkopio Aug 01 '16 at 15:41
  • The answer is now modified, hope it answers the question better. – vkopio Aug 01 '16 at 16:09
  • Now the text itself should also be more clear. I admit, it was a bit confusign. – vkopio Aug 01 '16 at 16:32
1

You can define a height or max-height for .container then use flex on header:

.banner {
    height: 300px;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}
.container {
    max-width: 500px;
    margin-left: auto;
    margin-right: auto;
    overflow: hidden;
}  

CodePen: http://codepen.io/theblindprophet/pen/NAzAWj

This will not work for some versions of IE, check here for details.


With display: inline-block:

/* This parent can be any width and height */
.block {
    text-align: center;

/* May want to do this if there is risk the container may be narrower than the element inside */
    white-space: nowrap;
}

/* The ghost, nudged to maintain perfect centering */
.block:before {
    content: '';
    display: inline-block;
    height: 100%;
    vertical-align: middle;
    margin-right: -0.25em; /* Adjusts for spacing */
}

/* The element to be centered, can also be of any width and height */ 
.centered {
    display: inline-block;
    vertical-align: middle;
    width: 300px;
}

CodePen: http://codepen.io/theblindprophet/pen/XKYKdy

Reference: CSS Tricks

theblindprophet
  • 7,767
  • 5
  • 37
  • 55
  • Thanks, but if you change the "max-width" value of "container" to say, 1500px, it doesn't work ("container" still doesn't visually get a width of 1500px) – drake035 Jul 26 '16 at 22:05
1

Maybe a

box-sizing: border-box;

property is what you are looking for ;)

Steven Dropper
  • 467
  • 3
  • 15
1

One possibility to vertically align elements inside the container it to use line-height as you know the height of your header. The downside of this is that you cannot have more than one row of text but usually this is the intent in the first place.

I tried to strip your code to the minimum and made a working demo here.

Basically if the container is 160px tall you can add line-height of 160px for the menu items to vertically align them to the middle.

To vertically align your image, I used the accepted method from this question.

To future proof, here is the code used in my demo:

* {
    margin: 0; /* Illustrative */
    padding: 0; /* Illustrative */
}

.banner {
 background: #222; /* Illustrative */
 width: 100%;
}
.container {
 background: #aaa; /* Illustrative */
 max-width: 800px; /* Change to desired value */
 margin: auto;
 overflow: hidden;
}    
.header__branding {
 background: #555; /* Illustrative */
 float: left;
 width: 150px;
 height: 160px;
 display: block;
}

.header__branding span {
 height: 100%;
 display: inline-block;
 vertical-align: middle;
 line-height: 160px;
}

.nav_primary {
 float: right;
}

.nav_primary a {
    line-height: 160px;
}

img {
    background: #3867EA; /* Illustrative */
    width: 100px; /* Illustrative */
    height: 100px; /* Illustrative */
    vertical-align: middle;
    display: inline-block;
}
<header class="banner">
  <div class="container">
 <a class="header__branding" href="#">
   <img alt="Logo" /><span>Title</span>
 </a>
 
 <nav class="nav_primary">
   <a>Menu1</a> <a>Menu2</a> <a>Menu3</a>
 </nav>
  </div>
</header>
Community
  • 1
  • 1
vkopio
  • 914
  • 1
  • 11
  • 28