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 <body> 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 <div> has no background, so the <body> background is visible.</p>
</div>
<!-- Overlays the <body> background -->
<div >
<p>
This <div> 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 <div> 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>