skip to Main Content

I tried to divide the body into three parts with different sizes, HEADER, CONTAINER, and FOOTER.
Header with 10% of the height, a container with 70% of the height, and a footer with 20%.
I tried to complete this task with flex but I can’t do it with percentages.
Please help.

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

body {
  background-color: skyblue;
  width: 100%;
  height: 100%;
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  align-content: space-between;
}

.header {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  border-bottom-left-radius: 10px;
  border-bottom-right-radius: 10px;
  background-color: black;
  color: rgb(225, 150, 0);
  font-weight: bold;
  font-style: italic;
  height: 10%;
  padding: 5px 10px;
  border: 1px solid blue;
}

.container {
  width: 100%;
  height: 70%;
  border: 1px solid red;
}

.footer {
  width: 100%;
  height: 20%;
  border: 1px solid green;
}
<div class="header">
  <p>HEADER</p>
</div>
<div class="container">
  <p>CONTAINER</p>
</div>
<div class="footer">
  <p>FOOTER</p>
</div>

3

Answers


  1. To achieve this use the CSS flex property with the values flex-base and flex-growth. See the code snippet down below

    * {
      box-sizing: border-box;
      padding: 0;
      margin: 0;
    }
    
    body {
      background-color: skyblue;
      width: 100%;
      height: 100vh;
      display: flex;
      flex-direction: column;
    }
    
    .header {
      display: flex;
      justify-content: center;
      align-items: center;
      border-bottom-left-radius: 10px;
      border-bottom-right-radius: 10px;
      background-color: black;
      color: rgb(225, 150, 0);
      font-weight: bold;
      font-style: italic;
      padding: 5px 10px;
      border: 1px solid blue;
      flex: 0 0 10%;
    }
    
    .container {
      border: 1px solid red;
      flex: 1 0 70%;
    }
    
    .footer {
      border: 1px solid green;
      flex: 0 0 20%;
    }
    <div class="header">
      <p>HEADER</p>
    </div>
    <div class="container">
      <p>CONTAINER</p>
    </div>
    <div class="footer">
      <p>FOOTER</p>
    </div>
    Login or Signup to reply.
  2. You can modify your code with the flex property to achieve your desired output.

    In extra, I have added flex-shrink: 0; to prevent the header and footer from shrinking when the viewport width is reduced.

    * {
      box-sizing: border-box;
      padding: 0;
      margin: 0;
    }
    
    body {
      background-color: skyblue;
      width: 100%;
      height: 100vh;
      display: flex;
      flex-direction: column;
    }
    
    .header {
      display: flex;
      justify-content: center;
      align-items: center;
      border-bottom-left-radius: 10px;
      border-bottom-right-radius: 10px;
      background-color: black;
      color: rgb(225, 150, 0);
      font-weight: bold;
      font-style: italic;
      padding: 5px 10px;
      border: 1px solid blue;
      flex: 0 0 10%;
      flex-shrink: 0;
    }
    
    .container {
      border: 1px solid red;
      flex: 1 0 70%;
    }
    
    .footer {
      border: 1px solid green;
      flex: 0 0 20%;
      flex-shrink: 0;
    }
    <div class="header">
      <p>HEADER</p>
    </div>
    <div class="container">
      <p>CONTAINER</p>
    </div>
    <div class="footer">
      <p>FOOTER</p>
    </div>
    Login or Signup to reply.
  3. There are two ways of achieving this, with grid and flex; first, with grid:

    /* a simple reset, to remove default margin and padding, and using
       box-sizing to have all browsers use the same sizing algorithm,
       in order to have padding and border widths included within the
       declared sizing: */
    *,::before,::after {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    
    section {
      /* taking 100 units of viewport-height on the block axis (the
         axis on which block elements are placed): */
      block-size: 100vh;
      /* using grid layout: */
      display: grid;
      /* setting a 0.5rem gap between adjacent grid-items: */
      gap: 0.5rem;
      /* defining the three rows: the first 10%, the third 20% and
         the second taking 1 fraction of all the remaining space: */
      grid-template-rows: 10% 1fr 20%;
    }
    
    section > * {
      /* irrelevant to demo, but is just to center the content of
         the grid-items: */
      display: grid;
      place-content: center;
    }
    
    /* irrelevant to the demo, just to colour the various elements: */
    header {
      background-color: hsl(50deg 90% 70%);
    }
    
    main {
      background-color: hsl(100deg 90% 70%);
    }
    
    footer {
      background-color: hsl(150deg 90% 70%);
    }
    <section>
      <header>
        <p>Heading</p>
      </header>
      <main>
        <p>Main content</p>
      </main>
      <footer>
        <p>Footer</p>
      </footer>
    </section>

    JS Fiddle demo.

    And, second, using flex:

    /* simple reset - as above - to remove default margins and
       padding, and to have box-sizing include the padding and
       borders in the declared sizes: */
    *,::before,::after {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    
    section {
      /* sizing the <section> to take 100 viewport-height units: */
      block-size: 100vh;
      /* using flex layout: */
      display: flex;
      /* setting the main axis of the flex layout to columnnar: */
      flex-direction: column;
      /* setting a 0.5rem gap between adjacent flex-items: */
      gap: 0.5rem;
    }
    
    /* irrelevant to the demo, just centering the content of the
       flex-items: */
    section > * {
      display: grid;
      place-content: center;
    }
    
    header {
      background-color: hsl(50deg 90% 70%);
      /* setting the flex-basis - that defines the base-size
         of the element - to 10% of its parent's size: */
      flex-basis: 10%;
    }
    
    main {
      background-color: hsl(100deg 90% 70%);
      /* specifying that the element should grow to take
         available space: */
      flex-grow: 1;
    }
    
    footer {
      background-color: hsl(150deg 90% 70%);
      /* setting the flex-basis to 20% of the parent's size: */
      flex-basis: 20%;
    }
    <section>
      <header>
        <p>Heading</p>
      </header>
      <main>
        <p>Main content</p>
      </main>
      <footer>
        <p>Footer</p>
      </footer>
    </section>

    JS Fiddle demo.

    I feel it’s worth pointing out that – despite your stated requirements – you don’t really want to use those sizes as declared. A layout in which the elements are sized according to percentage can be great, but it also exposes the possibility of the content being displayed at the extremes, from ridiculously small (phones, watches) to ridiculously large (large screen displays).

    With that said, I’d like to offer a slight revision of the above, taking advantage of the clamp() function; this allows us to set a "preferred" size, but with a specified minimum, and maximum:

    /* a simple reset, to remove default margin and padding, and using
       box-sizing to have all browsers use the same sizing algorithm,
       in order to have padding and border widths included within the
       declared sizing: */
    *,::before,::after {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    
    section {
      /* taking 100 units of viewport-height on the block axis (the
         axis on which block elements are placed): */
      block-size: 100vh;
      /* using grid layout: */
      display: grid;
      /* setting a 0.5rem gap between adjacent grid-items: */
      gap: 0.5rem;
      /* defining the three rows,
           row 1: a minimum size of 4rem, a maximum size of 150px, with a
           preferred size of 10% (as specified in the question):,
           row 2: as before, set to take all available space once the
           elements with a specific defined size have been laid out,
           row 3: a mimum size of 8rem, a maximum of 250px, and a preferred
           size of 20%: */
      grid-template-rows: clamp(4rem, 10%, 150px) 1fr clamp(8rem, 20%, 250px);
    }
    
    section > * {
      /* irrelevant to demo, but is just to center the content of
         the grid-items: */
      display: grid;
      place-content: center;
    }
    
    /* irrelevant to the demo, just to colour the various elements: */
    header {
      background-color: hsl(50deg 90% 70%);
    }
    
    main {
      background-color: hsl(100deg 90% 70%);
    }
    
    footer {
      background-color: hsl(150deg 90% 70%);
    }
    <section>
      <header>
        <p>Heading</p>
      </header>
      <main>
        <p>Main content</p>
      </main>
      <footer>
        <p>Footer</p>
      </footer>
    </section>

    JS Fiddle demo.

    And, second, using flex:

    /* simple reset - as above - to remove default margins and
       padding, and to have box-sizing include the padding and
       borders in the declared sizes: */
    *,::before,::after {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    
    section {
      /* sizing the <section> to take 100 viewport-height units: */
      block-size: 100vh;
      /* using flex layout: */
      display: flex;
      /* setting the main axis of the flex layout to columnnar: */
      flex-direction: column;
      /* setting a 0.5rem gap between adjacent flex-items: */
      gap: 0.5rem;
    }
    
    /* irrelevant to the demo, just centering the content of the
       flex-items: */
    section > * {
      display: grid;
      place-content: center;
    }
    
    header {
      background-color: hsl(50deg 90% 70%);
      /* setting the flex-basis to a minimum of 4rem, a maximum of
         150px, with a preferred size of 10% within those constraints: */
      flex-basis: clamp(4rem, 10%, 150px);
    }
    
    main {
      background-color: hsl(100deg 90% 70%);
      /* specifying that the element should grow to take
         available space: */
      flex-grow: 1;
    }
    
    footer {
      background-color: hsl(150deg 90% 70%);
      /* setting the flex-basis to a minimum of 8rem, a maximum of
         250px, with a preferred size of 20% within those constraints: */
      flex-basis: clamp(8rem, 20%, 250px);
    }
    <section>
      <header>
        <p>Heading</p>
      </header>
      <main>
        <p>Main content</p>
      </main>
      <footer>
        <p>Footer</p>
      </footer>
    </section>

    JS Fiddle demo.

    References:

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search