Home > Net >  Background-color vertical 50% split does not work when the footer is positioned with flex-box
Background-color vertical 50% split does not work when the footer is positioned with flex-box

Time:01-18

I would like to display the background of a website in two colors. Green at the top and grey at the bottom. The separation should be at ~50%. I have given the main tag a height of 50vh and the background-color: green. I have given the body the background-color: gray. That worked quite well so far.

But now I wanted to position the footer with flex-box at the bottom. But that would destroy my background-color-50%-split, because I have to stretch (flex:1). How can I still make such a background color split? It should not be static.

Without flex-box split:

:root {
  --header-height: 42px;
  --container-width: 900px;
  --bg-dark-primary: #333;
  --bg-dark-secondary: gray;
  --text-color-primary: #333;
}

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

body {
  font-family: Arial, Helvetica, sans-serif;
  font-family: sans-serif;
  background-color: var(--bg-dark-secondary);
  color: var(--text-color-primary);
  min-height: 100vh;
}

header {
  text-align: center;
  width: 100%;
  position: fixed;
  top: 0;
  overflow: hidden;  
  background: var(--bg-dark-primary);
}

footer {
  max-height:200px;
  min-height:50px; 
  background:black; 
  color: white;
}
.container {
  max-width: var(--container-width);
  width:100%;
  margin: 0 auto;
}

.header {  
  display:inline-flex;
  justify-content: space-between;
  align-items: center;
  height: var(--header-height);
}

.logo {
  display: flex;
  align-items: center;
}

.navbar {
  display: flex;
  align-items: stretch;
}

main {
  margin-top: var(--header-height);
  height: calc(55vh - var(--header-height));
  color: white;
  background: green;
} 
<header>
  <div >
    
    <div >
      <img  src="https://via.placeholder.com/40">
      <span >brand</span>
    </div>
    
    <nav >  

    </nav>    
  </div><!-- container header -->
</header>

<main>
  <div>x</div>
</main>

<footer>
  footer
</footer>

With flex-box to position footer

:root {
  --header-height: 42px;
  --container-width: 900px;
  --bg-dark-primary: #333;
  --bg-dark-secondary: gray;
  --text-color-primary: #333;
}

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

body {
  font-family: Arial, Helvetica, sans-serif;
  font-family: sans-serif;
  background-color: var(--bg-dark-secondary);
  color: var(--text-color-primary);
  min-height: 100vh;
  display:flex; 
  flex-direction:column;
}

header {
  text-align: center;
  width: 100%;
  position: fixed;
  top: 0;
  overflow: hidden;  
  background: var(--bg-dark-primary);
}

footer {
  max-height:200px;
  min-height:50px; 
  background:black; 
  color: white;
}
.container {
  max-width: var(--container-width);
  width:100%;
  margin: 0 auto;
}

.header {  
  display:inline-flex;
  justify-content: space-between;
  align-items: center;
  height: var(--header-height);
}

.logo {
  display: flex;
  align-items: center;
}

.navbar {
  display: flex;
  align-items: stretch;
}

main {
  flex: 1;
  margin-top: var(--header-height);
  /*height: calc(55vh - var(--header-height));*/
  color: white;
  background: green;
} 
<header>
  <div >
    
    <div >
      <img  src="https://via.placeholder.com/40">
      <span >brand</span>
    </div>
    
    <nav >  

    </nav>    
  </div><!-- container header -->
</header>

<main>
  <div>x</div>
</main>

<footer>
  footer
</footer>

CodePudding user response:

As commented, it is easy enough to create a two-color linear gradient and use that as a background-image for any container element you require. As you are obviously accustomed to use CSS custom variables I created a variable holding a vertical gradient with only green and #333:

--gradient: linear-gradient(to bottom, green 0% 50%, #333 50% 100%)

Make sure it fills the entire background of the container element concerned and that it has its background-attachment: fixed.

I created a four page demo (each min-height: 100vh) following your main Flexbox Layout page structure without the custom variables and alignments.

The code is commented and should be self-explanatory:

/*************************/
/* Main background setup */
/*************************/
.bg {
    /* Use background and blend-mode variables */
    background-image     : var(--background, none);  /* with fallbacks */
    background-blend-mode: var(--blend-mode, normal);
    background-size      : cover;
    background-position  : center;
    background-repeat    : no-repeat;

    background-attachment: fixed; /**/
    /*
        big difference 'background-attachment' en/disabled
        with multipage content and varying backgrounds...
    */
}

:root {
     /* define a two color gradient */
     --gradient: linear-gradient(to bottom, green 0% 50%, #333 50% 100%);
}

.bg.green {
    /* Attach to background variable */
    --background: var(--gradient);
    /* No blend-mode required */
}


/*****************************************************/
/* Just fun: fixed background image/gradient overlay */
/*****************************************************/
:root {
    /* define another custom background */
     --rainbow: linear-gradient(
                    60deg, 
                    aqua   , #00bcff, #007aff,
                    #0037ff, #0b00ff, #4e00ff,
                    #9000ff, #d300ff, #ff00e9,
                    #ff00a6, #ff0064, #ff0021,
                    #ff2100, #ff6400, #ffa600,
                    #ffe900, #d3ff00, #90ff00,
                    #4eff00, #0bff00, #00ff37,
                    #00ff7a, #00ffbc, aqua
                );

    --image: url("https://picsum.photos/id/281/1920/1200");
}

.bg.rainbow {
    /* Attach image and gradient to background variable */
    --background: var(--image), var(--rainbow);

    /* Define their background blending modes */
    --blend-mode: multiply, screen;
}


/****************************************/
/* Demo page setup, not too interesting */
/****************************************/
*, ::before, ::after { box-sizing: border-box }

body {
    margin: 0;

    display: flex; flex-direction: column;
    width: 100%; min-height: 100vh;

    line-height: 1.5; color: White;
}

p {
    padding: 3rem; max-width: 75%;
    backdrop-filter: blur(10px);
    border: 1px solid Gray;
}

a { color: inherit }

main, header, footer {
    /* easy centering of content */
    display: grid; place-items: center;
}

/* Header and footer height */
:root { --headfoot: 3.5rem }

main {
    flex: 1; min-height: 100vh;
    padding: var(--headfoot) 0;
}

header, footer {
    opacity: 0.7; /* for debugging */

    height: var(--headfoot); width: 100%;
    background-color: black; color: white;

    position: fixed; z-index: 1;
}
header { top   : 0 }
footer { bottom: 0 }

div.bg {
    display: grid; place-items: center;
    width: 100%; min-height: 100vh;
}
<!-- <body> contains the main page background -->
<body >
    <header>some header</header>
    <main>
        <p>The &lt;body&gt; background image is a fixed two-color gradient.</p>

        <!-- to proove the background stays in place -->
        <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
        <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
        <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
        <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
        <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
        <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
        <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
        <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
        <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
        <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    </main>
 
        <!--
            Just for some extra fun!
        -->
        <div >
            <p>This &lt;div&gt; has no background, so the &lt;body&gt; background is visible.</p>
        </div>

        <!-- Overlays the <body> background -->
        <div >
            <p>
                This &lt;div&gt; overrides the fixed two-color gradient with a gradient overlayed image.<br>
                Image Credit: <a target="_blank" href="https://unsplash.com/photos/_poRbNNfcE8">Victor Erixon, Unsplash</a>
                retrieved via <a target="_blank" href="https://picsum.photos/images">Lorem Picsum, photo id: #281</a>
            </p>
        </div>

        <div >
            <p>This &lt;div&gt; too has no background showing the original background again.</p>
        </div>

    <footer>some footer</footer>
 </body>

CodePudding user response:

You can put the green background as a kind of cover over the darker background. But then you have to work with position absolute and z-index. I personally have nothing against positioning. But I had heard before that it should always be the last choice. Which I personally don't find. Without these CSS elements we would be a lot poorer in web design ;-)

Here is an example of how you can implement it:

body {
  background: gray;
  display: flex;
  flex-direction:column;
  height: 100vh;
}

header, footer {
  background: black;
  min-height: 80px;
  color: white;
  font-size: large;
  text-align: center;
  padding-top:30px;
}

main {
  position: relative;
  background: yellow;
  flex: 1;
  z-index: -3;
}

article {
  margin: 0 auto;
  background: white;
  width: 600px;
  height: 200vh;
}

.blender {
  z-index: -2;
  position: absolute;
  top:0;
  width: 100%;
  height: 50vh;
  background: green;
}
<body>
  <header>
    HEADER
  </header>
  <main>
    <div ></div>
    <article>
      MAIN
    </article>    
  </main>

  <footer>
    FOOTER
  </footer>
</body>

  • Related