Search code examples
htmlcssflexboxfooter

How to center flexbox sticky footer with a set width


I'm using flexbox to make my footer stick to the bottom, and for the most part it's working. My problem is, I need the content to be within a specified width, that I set with max-width and center with margin-left:auto; and margin-right:auto;. When I activate flexbox, the contents are squished by the margin-left and margin-right rules, and do not take up the space defined by max-width. I would like to know why this is happening and how to get my footer to look how I want it to look.

Here is how I want my footer to look: enter image description here

And here is how flexbox is affecting it: enter image description here

body {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

div#content {
  flex: 1 0 auto;
}

footer {
  flex: 0 0 auto;
  max-width: 67.5rem;
  margin-left: auto;
  margin-right: auto;
  padding-left: 1.25rem;
  padding-right: 1.25rem;
  padding-bottom: 1.875rem;
  padding-top: 3.5rem;
}
<body>
  <header>...</header>
  <div id="content">...</div>
  <footer>
    <span id="left">left text</span>
    <span id="mid">right text url@mail</span>
    <span id="icons">...</span>
  </footer>
</body>

If I change max-width to width then it works, but then when I test it in my browser using the device-mobile setting to see how it would look on a mobile device, the width property makes the footer too big and messes up the content. If I take out the margin-left and margin-right properties, then my footer looks like this: enter image description here

As you can see it's no longer centered. I can't use the flex-basis property because that only affects the height of the footer. Please help.

Edit

Here is a snippet with margin-left and margin-right taken out and replaced with display:flex; and justify-content:space-around;. Be sure to click "Full page" to view with a larger viewport.

body {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

div#content {
  flex: 1 0 auto;
}

footer {
  flex: 0 0 auto;
  max-width: 67.5rem;
  padding-left: 1.25rem;
  padding-right: 1.25rem;
  padding-bottom: 1.875rem;
  padding-top: 3.5rem;
  display: flex;
  justify-content: space-around;
}
<body>
  <header>...</header>
  <div id="content">...</div>
  <footer>
    <span id="left">left text</span>
    <span id="mid">right text url@mail</span>
    <span id="icons">...</span>
  </footer>
</body>


Solution

  • This can be done easily with justify-content: space-between;, but looking at your code I feel you may misunderstand a bit how Flexbox itself works. You want your footer to act as a flex container so you can manipulate the child spans as well.

    Consider checking out freeCodeCamp's Flexbox Challenges to get a better idea how Flexbox works.

    EDIT: CodePen now reflects what OP was meaning to immitate.

    Here's a CodePen to play around with.

    What this does is makes your footer both a child and container.

    1. First your body becomes a container to allow the main content to grow to fill the space pushing your footer to the bottom of the page. The flex-direction is set to column to flow vertically.
    2. You create a wrapper for your footer, because currently your footer is in the body container which is set to flex-direction:column; where in this case, you want the direction to be row to style horizontally. By default display:flex; will assume you wanted row so direction doesn't need declared. We then justify-content to the center so no matter the width the footer itself will be centered.
    3. You treat your <footer> as both a child and container. As a child we tell it not to grow or shrink and set the basis to auto. As a container, we tell it to distribute space-between its children which allows a consistently equal amount of space between the left & right spans.

    body {
      display: flex;
      height: 100%;
      flex-direction: column;
    }
    
    .main {
      flex: 1 0 auto;
      border: 1px solid #000;
    }
    
    .wrapper {
      display: flex;
      justify-content: center;
    }
    
    footer {
      flex: 0 0 auto;
      display: flex;
      margin: 1em;
      width: 80%;
      border: 1px solid #000;
      justify-content: space-between;
    }
    <body>
      <div class="main">
        <h1>Hello Flex</h1>
        <p>This is Flexbox</p>
        <h1>Hello Flex</h1>
        <p>This is Flexbox</p>
    
      </div>
    </body>
    <div class="wrapper">
      <footer>
        <span id="left">left text</span>
        <span id="mid">right text url@mail</span>
      </footer>
    </div>