Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flexbox width of header aligned with outer part of content

Tags:

html

css

flexbox

I'm using flexbox to align my content blocks in the middle of the page, now i'm willing to align the header with the outer content blocks

In the image you can see what needs to happen

This is my current result:

And this is how it need's to look like enter image description here

So when scaling the browser the content is going to the first line if there is space, the header needs to grow with this at that moment.

Here is a codepen with the flexbox in it

.flex {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

http://codepen.io/Dirkandries/pen/XmpGzw

Is this possible without using media queries and keeping the content boxes the same size?

*The padding and margin can be removed

like image 358
Ivo Avatar asked Oct 01 '15 13:10

Ivo


3 Answers

Challenge #1

In looking at your code, you have a 10px margin applied to each box:

section {
    background: red;
    width: 300px;
    height: 200px;
    margin: 10px;
}

So one problem you will encounter in trying to align the header edges with the box edges is that there's an additional 10px of transparent space beyond the border of each box. But you're asking for the header to align with the border of the box. So we can either remove the margin from each box, or adjust the width of the header. I've gone with the latter in my solution below.

Challenge #2

You've specified a fixed width for each box (300px). This makes it difficult to match the header width with the row of boxes. What happens when the screen is 750px or 1150px wide? The boxes don't stretch to fill the width, a gap is created as a result, and the box row doesn't align with the header.

The box row width is 960px but the header width is 1150px.

enter image description here


One possible solution (or step in the right direction)

  • Align the flexbox in a column direction to vertically stack the header and the boxes (which are wrapped in a new container)
  • Use a nested flexbox to align the boxes in a row
  • Use calc for width values
  • Use media queries for screen adjustments

HTML

<article class="flex">
    <header>
        Header needs to be alignd with the container outer part
    </header>
    <div id="nested-inner-container"><!-- new container for nested flexbox -->
        <section>content</section>
        <section>content</section>
        <section>content</section>
        <section>content</section>
        <section>content</section>
        <section>content</section>
    </div>
</article>

CSS

body {  margin: 0; }

.flex {
    display: flex;
    flex-direction: column; /* main groups (header and div) in column direction */
    align-items: center;
}

header {
    height: 50px;
    width: calc(100% - 20px); /* width accounts for left and right box margins */
    background-color: blue;  
}

#nested-inner-container {
    display: flex; /* box group (flex item) becomes flex container, as well */
    justify-content: center;
    flex-wrap: wrap;
    width: 100%; /* width equal to header width */
}

section {
    flex: 1 1 calc(25% - 80px); /* flex basis equals four boxes per row less margins */
    height: 200px;
    margin: 10px;
    background: red;
}

@media screen and (max-width: 1500px) {
  section { flex-basis: calc(33.33% - 60px); } /* three boxes per row less margins */
}    
@media screen and (max-width: 1250px) {
  section { flex-basis: calc(50% - 40px); } /* two boxes per row less margins */
}
@media screen and (max-width: 1000px) {
  section { flex-basis: calc(100% - 20px); } /* one box per row less margins */
}

DEMO: http://codepen.io/anon/pen/wKgVYb

NOTE: This answer may or may not be exactly what you're looking for. The question didn't address all the details (like "can the margins be adjusted?", "are the box widths adjustable?", "are media queries not an option or just something you're hoping to avoid?"). So my goal in this answer was to offer up some concepts that hopefully get you where you want to go. AT A MINIMUM, the header and the boxes align in all screen sizes :-)

like image 174
Michael Benjamin Avatar answered Oct 22 '22 15:10

Michael Benjamin


As far as I know, there is no solution to your question using only CSS and the flex box model.

If what you want is just to align the background of the header, you can fake it.

You need another flex container, that will give you a background with the same rules as the real one. (And that will be used only for this... not really semantic)

.flex{
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  position: relative;
}
header{
  width: 100%;
  background: lightblue;
  height: 50px;
  margin: 0px 170px;
  text-align: center;
}
section{
  background: red;
  width: 300px;
  height: 200px;
  margin: 10px;
}
.headerbkg {
  position: absolute;
  left: 0px;
  right: 0px;
  top: 0px;
  height: 50px;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  overflow: hidden;
  z-index: -1;
}

.headerbkg div {
  background: lightblue;
  width: 300px;
  height: 50px;
  margin: 0px 10px;
}
<article class="flex">
  <header>
    Header needs to be alignd with the container outer part
  </header>
  <div class="headerbkg">
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
  </div>
  <section>content</section>
  <section>content</section>
  <section>content</section>
  <section>content</section>
  <section>content</section>
  <section>content</section>
</article>

The real header is given a margin that will keep it always narrower that the background, so that won't spoli the effect.

To make this less evident, I have given it a centered text

like image 26
vals Avatar answered Oct 22 '22 16:10

vals


The following are my adressment of the question.

<!DOCTYPE html>

<html>
    <head>
        <meta charset = "utf-8">

        <meta name    = "viewport"
              content = "width = device-width, initial-scale = 1.0"
        >

        <link href = "CSS/Example.css"
              rel  = "stylesheet"
              type = "text/css"
        >
    </head>

    <body>
        <header>
            Header needs to be alignd with the container outer part
        </header>

        <div class="flex">
            <section>content</section>
            <section>content</section>
            <section>content</section>
            <section>content</section>
            <section>content</section>
            <section>content</section>
        </div>
    </body>
</html>

CSS

html,
*
{
    border     : 0;
    box-sizing : border-box;
    margin     : 0;
    padding    : 0;
}

.flex
{
    display         : flex;
    flex-wrap       : wrap;
    justify-content : center;
}

header
{
    background : blue;
    display    : block;
    height     : 50px;
    margin     : auto;
    width      : 300px;
}

@media only screen and (min-width : 620px)
{
    body header
    {
        width : 620px;
    }
}

@media only screen and (min-width : 940px)
{
    body header
    {
        width : 940px;
    }
}

@media only screen and (min-width : 1260px)
{
    body header
    {
        width : 1260px;
    }
}

@media only screen and (min-width : 1580px)
{
    body header
    {
        width : 1580px;
    }
}

@media only screen and (min-width : 1900px)
{
    body header
    {
        width : 1900px;
    }
}

section
{
    background : red;
    display : block;
    width      : 300px;
    height     : 200px;
    margin     : 10px;
}

Firstly, in the CSS file there is the segment...

*
{
    border     : 0;
    box-sizing : border-box;
    margin     : 0;
    padding    : 0;
}

By setting border, margin and padding to 0 for all elements you can eliminate any default settings for those properties that some or all browsers might display for an element. By adding box-sizing : border-box; any border or padding settings you make will be contained within the width of an element rather than without, making laying out a page much simpler.

I tend to include this snippet as a precaution.

As for setting the width of your header, it will need to be set to a fixed width that will need to be changed whenever the concentration of section's (themselves of a fixed width) to a line changes, which will occur whenever the viewport reaches certain widths.

The width of the header, and the width of the viewport at which it is changed, will equal the total width of the sections in one full line plus the total width of the margins between them, nnamely 300px, 620px, 940px, 1260px, 1580px, and 1900px. I have used media queries to perform the changeover at those points.

Note : Because of specificity issues caused when seeking to override a property using media queries I have placed body in front of the definition of header in each of the media queries.

Since the width of header isn't flexible and flex is mainly there to distribute the section's, I have placed header outside of flex.

If you have any questions or comments about my answer, then please feel free to reply.

like image 22
toonice Avatar answered Oct 22 '22 14:10

toonice