Fitting everything within a static flex column - html

I am trying to fit 4 divs within the view bounds of a non-scrolling column flexbox but I can't seem to get it working.
What I want:
What I experience:
I have no idea what I am doing and just randomly permutating flex-related CSS fields to try and fix it haha. If someone could point out what is wrong I would love you forever.
Here is the gist of my code:
body {
overflow: hidden;
margin: 0;
width: 100%;
height: 100%;
}
#flexcontent {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
#header #firstContent #secondContent {
flex: 1 1 auto;
}
#header {
background-color: green;
font-weight: 700;
align-content: center;
font-size: 7rem;
}
#firstContent {
background-color: red;
}
#secondContent {
background-color: yellow;
}
#picture {
background-color: blue;
flex: 0 1 auto;
}
<body>
<div id="flexcontainer">
<div id="header">Title</div>
<div id="picture"><img src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg"/></div>
<div id="firstContent">first</div>
<div id="secondContent">second</div>
</div>
</body>

Try this below. And use object-fit if image doesn't expand or shrink as expected or aspect ratio changes.
#flexcontainer {
display: flex;
flex-direction: column;
height: 100vh;
}
#picture {
flex: 1;
min-height: 0;
}
body {
margin: 0;
}
img {
object-fit: contain;
height: 100%;
width: auto;
}
<div id="flexcontainer">
<div id="header">Title</div>
<div id="picture"><img src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg" /></div>
<div id="firstContent">first</div>
<div id="secondContent">second</div>
</div>

Please check your container div id
<div id="flexcontainer">
change
#flexcontent {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
to
#flexcontainer {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
try object-fit for img
img {
object-fit: contain;
height: 100%;
}

there is a few thing to fix in your CSS, typo and value used
html, /* to inherit height */
body {
margin: 0;
width: 100%;
height: 100%;
}
#flexcontainer {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
min-height: 0; /* force size calculation*/
}
#header,/* you meant each one of them */
#firstContent,
#secondContent {
flex: 1;
margin: 2px 5vw;/* for demo */
}
#header {
background-color: green;
font-weight: 700;
/* align-content: center; or did you forget display:flex here */
font-size: calc(1rem + 2vw);
}
#firstContent {
background-color: red;
}
#secondContent {
background-color: yellow;
}
#picture {
display: flex;
min-height: 0; /* force size calculation*/
}
img {
max-height: 90%;/* whatever */
margin: auto;/* or align-content + justify-content : center on flex parent*/
}
<div id="flexcontainer">
<div id="header">Title</div>
<div id="picture"><img src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg" /></div>
<div id="firstContent">first</div>
<div id="secondContent">second</div>
</div>

Allow the item holding the image to shrink below its content size.
Define the parameters of the image.
(Tested in Chrome, Firefox and Edge.)
#flexcontainer {
display: flex;
flex-direction: column;
height: 100vh;
}
#picture {
min-height: 0;
background-color: blue;
}
#picture>img {
width: 100%;
max-height: 100%;
object-fit: contain;
}
#header {
background-color: green;
font-weight: 700;
font-size: 7rem;
}
#firstContent {
background-color: red;
}
#secondContent {
background-color: yellow;
}
body {
margin: 0;
}
<div id="flexcontainer">
<div id="header">Title</div>
<div id="picture"><img src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg" /></div>
<div id="firstContent">first</div>
<div id="secondContent">second</div>
</div>
jsFiddle demo

I've tidied up your html a little and simplified the CSS. You want to take the overflow: hidden off of the body tag, and give each of your elements a class instead of an id. Finally, simplify the image section by making the image tag itself a flexbox item:
html,
body {
height: 100%
}
body {
/*overflow: hidden;*/
margin: 0;
}
.flexContainer {
display: flex;
flex-direction: column;
height: 100%;
}
.flexContainer__header,
.flexContainer__firstContent,
.flexContainer__secondContent {
flex: 1 1 auto;
}
.flexContainer__header {
background-color: green;
font-weight: 700;
align-content: center;
font-size: 7rem;
}
.flexContainer__firstContent {
background-color: red;
}
.flexContainer__secondContent {
background-color: yellow;
}
.flexContainer__picture {
display: block;
width: 100%;
}
<div class="flexContainer">
<div class="flexContainer__header">Title</div>
<img class="flexContainer__picture" src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg" />
<div class="flexContainer__firstContent">first</div>
<div class="flexContainer__secondContent">second</div>
</div>

Related

Can't figure how to properly center those images

Hello everyone, I'm trying to setup the main content of the homepage as shown in the image but can't really figure a few things.
Somehow everything I try results in the image to overflow the container and be as big as the page. I don't want to set a fixed size for the image, but rather have it proportional to the view height and width
This is my code right now:
<section class="main">
<div class="main-left">
<div class="container">
<img src="assets/images/wine.png">
</div>
</div>
<div class="main-right">
<div class="container">
<img src="assets/images/oil.png">
</div>
</div>
</section>
.main {
display: flex;
background-color: #f1eee9;
height: 100%;
}
.main-left, .main-right {
display: flex;
flex-direction: row;
}
.main-left {
background-color: #111;
width: 50%;
}
.main-right {
background-color: #1f1f1f;
width: 50%;
}
.container {
display: flex;
justify-content: center;
align-items: center;
width: 80vw;
height: 80vw;
}
.container img {
display: block;
width: 100%;
height: 100%;
}
I haven't yet added the text so it would be REALLY helpful if you could suggest how to do that as well..
You should use : object-fit: cover;
which is documented here : https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit
With your exemple I made that (changed container height to 80vh and not vw)
.main-left, .main-right {
display: flex;
flex-direction: row;
}
.main-left {
background-color: #111;
width: 50%;
}
.main-right {
background-color: #1f1f1f;
width: 50%;
}
.container {
width: 80vw;
height: 80vh;
background-color: blue;
}
.container img {
display: block;
width: 100%;
height: 100%
object-fit: cover;
}
You can optimize your code like below it got correct:
<section class="main">
<div class="main-left">
<img src="assets/images/wine.png">
</div>
<div class="main-right">
<img src="assets/images/oil.png">
</div>
</section>
.main {
display: flex;
flex-direction: row;
}
.main-left , .main-right{
flex: 1;
}
.main-left {
background-color: #111;
}
.main-right {
background-color: #1f1f1f;
}
.main > div img {
display: block;
width: 100%;
height: 100%
object-fit: cover;
}

Image not taking parent height

I have following html:
<div class='fullHeight'>
<div class='flexbox'>
<div class='first'>
<p>foo</p>
</div>
<div class='second'>
<p>bar</p>
<img src='http://www.mandysam.com/img/random.jpg'>
</div>
</div>
</div>
and css:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.fullHeight {
height: 100vh;
background-color: red;
}
.flexbox {
display: flex;
flex-direction: column;
height: 100%;
maxHeight: 100%;
width: 100%;
background-color: green;
}
.first {
background-color: magenta;
}
.second {
background-color: yellow;
flex: 1 1 auto;
max-height: 100%;
height: 100%;
widht: auto;
}
As long there is no image, everything works fine:
But as soon as a picture comes in, it overflows the container, instead of being shrinked to fit available height:
Codepen
You missed
display: flex;
flex-direction: column;
in your .second class, that's why the flex property isn't doing anything. Also it should be max-height instead of maxHeight and width instead of widht.
You can use background-image for your purpose.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.fullHeight {
height: 100vh;
background-color: red;
}
.flexbox {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
background-color: green;
}
.first {
background-color: magenta;
}
.second {
background-color: yellow;
display: flex;
flex-grow: 1;
flex-direction: column;
}
.container {
background-color: green;
flex-grow: 1;
background-image: url('http://www.mandysam.com/img/random.jpg');
background-size: contain;
background-repeat: no-repeat;
}
<div class='fullHeight'>
<div class='flexbox'>
<div class='first'>
<p>foo</p>
</div>
<div class='second'>
<p>bar</p>
<div class="container">
</div>
</div>
</div>
</div>
Add height and width properties to your image. Or just height. Maybe also object-fit: cover;
.second img {
height: 100%;
width: 100%;
object-fit: cover;
}
Using positions is the other solution but it's very risky and it depends on your plan for future code in this project!!
.second {
background-color: yellow;
flex: 1 1 auto;
max-height: 100%;
height: 100%;
widht: auto;
position:relative
}
.second img{
height: 95%;
width: 100%;
position:absolute;
bottom:0;
right:0;
}

How to enable scrollbar with non-fixed height in a window-centered div?

I am creating a div which is centered to the window. It's content can grow, and if it grows passed the size of the window, the content div should have it's scrollbar account for the overflow. But instead, the div just grows off the screen and gets clipped. If I set an explicit height on the content, everything works, but since I don't know the explicit height of the environment I cannot do that. What is the correct way to do this?
JSFiddle: https://jsfiddle.net/CodeVirtue/cjhz31xq
Here is the template:
<div class="fullscreen-overlay">
<div class="fullscreen-container">
<div class="window-with-titlebar">
<div class="titlebar">
<div class="titlebar-left">
Left
</div>
<div class="titlebar-right">
Right
</div>
</div>
<div class="content">
1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40
</div>
</div>
</div>
</div>
And all the CSS:
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
overflow: hidden;
}
.fullscreen-overlay {
background-color: red;
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
padding: 12px 12px;
}
.fullscreen-container {
background-color: orange;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
overflow: hidden;
}
.window-with-titlebar {
background-color: yellow;
max-width: 100%;
max-height: 100%;
}
.titlebar {
background-color: green;
display: flex;
align-items: center;
justify-content: space-between;
height: 30px;
}
.titlebar-left {
background-color: darkgreen;
}
.titlebar-right {
background-color: lightgreen;
}
.content {
background-color: blue;
overflow-y: scroll;
max-width: 100%;
max-height: 100%;
}
I believe I was able to achieve what you are looking for by making the parent container use flexbox:
.window-with-titlebar {
background-color: yellow;
max-width: 100%;
max-height: 100%;
display: flex;
flex-direction: column;
}

Add responsive image to a website split into 4 responsive boxes

I want to make a website that would consist of 4 boxes each 50% height and width. I found code that does that, but now I struggle to add images into each box. I want each of the four divs to have a different image, and they should scale according to window size. Any help is appreciated.
Here's my codepen: https://codepen.io/alanvkarlik/pen/OJRdyRR
Here's what I would like to achieve: https://i.imgur.com/7CR7sW8.jpg
HTML:
<div class="container">
<div class="column"><img src="https://f4.bcbits.com/img/a0846297992_16.jpg"></div>
<div class="column">IMG 2</div>
<div class="column">IMG 3</div>
<div class="column">IMG 4</div>
</div>
CSS:
html, body {
height: 100%;
margin: 0;
}
.container {
height: 100%;
}
.column {
height: 25%;
display: flex;
justify-content: center;
align-items: center;
}
#media screen and (min-width: 600px) {
.container {
display: flex;
flex-wrap: wrap;
}
.column {
flex-basis: 50%;
height: 50%;
}
}
/* general styles */
body {
font-family: 'Lato', sans-serif;
font-size: 1.3em;
color: #ccc;
background: #000;
/*margin-bottom: 70px;*/
}
.column {
padding: 15px;
/*border: 1px solid #666;*/
box-sizing: border-box;
}
.column:nth-child(1) {
background: #5c9;
}
.column:nth-child(2) {
background: #fb0;
}
.column:nth-child(3) {
background: #39f;
}
.column:nth-child(4) {
background: #f33;
}
main {
max-width: 1200px;
margin: 0 auto;
}
h1,
h2 {
text-align: center;
}
Not sure if this is what you're trying to achieve but I'd do it with by setting object-fit: contain on images. I also changed a bit the way (css) you're defining the divs.
body {
margin: 0;
}
.container {
display: flex;
flex-wrap: wrap;
}
.column {
height: 50vh;
width: 50vw;
display: flex;
justify-content: center;
align-items: center;
padding: 15px;
box-sizing: border-box;
}
.column img {
height: 100%;
width: 100%;
object-fit: contain;
}
.column:nth-child(1) {
background: #5c9;
}
.column:nth-child(2) {
background: #fb0;
}
.column:nth-child(3) {
background: #39f;
}
.column:nth-child(4) {
background: #f33;
}
<div class="container">
<div class="column"><img src="https://f4.bcbits.com/img/a0846297992_16.jpg"></div>
<div class="column">IMG 2</div>
<div class="column">IMG 3</div>
<div class="column">IMG 4</div>
</div>
I think this is what you are looking for.
Your column img class is set to 100% width and height. I set the height to 50% and the width to auto so it detects the image size and displays it noramlly.
And i simply removed the "object-fit: cover;".
If you change your .colum img {} to the following it should be exactly what you want.
.column img {
height: 50%;
width: auto;
}
I added a snippet so you can see it working.
body {
margin: 0;
}
.container {
display: flex;
flex-wrap: wrap;
}
.column {
height: 50vh;
width: 50vw;
display: flex;
justify-content: center;
align-items: center;
padding: 15px;
box-sizing: border-box;
}
.column img {
height: 50%;
width: auto;
}
.column:nth-child(1) {
background: #5c9;
}
.column:nth-child(2) {
background: #fb0;
}
.column:nth-child(3) {
background: #39f;
}
.column:nth-child(4) {
background: #f33;
}
<div class="container">
<div class="column"><img src="https://f4.bcbits.com/img/a0846297992_16.jpg"></div>
<div class="column">IMG 2</div>
<div class="column">IMG 3</div>
<div class="column">IMG 4</div>
</div>

CSS overlay scrolling issues

I posted a question here that was answered and worked for me at the time. I had to re-write my code with flex box and now the overlay scrolling doesn't work. I tried adding position:sticky; to the behind div that fixed it in the first question I posted, but doesn't work for my current code. Using my current code, how can I get the overlay scrolling to work again? What am I missing?
Edit:
using only css and html, is it possible to scroll away the front div (overlay div ontop of the image) completely before scrolling down the rest of the page? Essentially, wondering if overlay scrolling while freezing the behind div is possible in only css? Then once the front div is gone, unfreeze the background scrolling and continue on. Similar to this site here: https://humaan.com/ .
html,
body {
margin: 0;
height: 100%;
width: 100%;
}
#container {
height: 100%;
}
#front {
background-color: pink;
height: 91%;
display: flex;
position: relative;
z-index: 2;
}
#left {
width: 50%;
background-color: lightgreen;
display: flex;
flex-direction: column;
}
#left>* {
flex: 1;
}
#leftnav {
height: 8%;
width: 100%;
background-color: green;
display: flex;
}
#logotext {
display: flex;
}
#right {
width: 50%;
background-color: lightgreen;
display: flex;
flex-direction: column;
}
#right>* {
flex: 1;
}
#logo {
width: 100%;
max-width: calc(80vh - 25px);
background-color: blue;
}
#logo:before {
content: "";
display: flex;
padding-top: 100%;
}
#llogo {
width: 100%;
max-width: calc(80vh - 25px);
background-color: lightblue;
margin: 0;
}
#llogo:before {
content: "";
display: flex;
padding-top: 100%;
}
#rightsidetop {
background-color: lightgrey;
}
#leftsidetop {
background-color: lightgrey;
}
ul {
display: flex;
text-align: center;
justify-content: space-between;
width: 85%;
text-decoration: none;
}
li {
display: block;
font-size: 17px;
text-decoration: none;
}
#rightsideright {
background-color: lightgreen;
flex: 1;
}
#leftsideright {
background-color: lightgreen;
flex: 1;
}
#rightsidebottom {
background-color: pink;
}
#leftsidebottom {
background-color: pink;
}
.wrapper {
display: flex;
}
.video {
background: url(https://picsum.photos/id/107/800/800) center/cover;
height: 100%;
margin-top: -100%;
position: sticky;
top: 0;
}
<div id="container">
<div id="front">
<div id="left">
<div id="leftsidetop">
<p>logo</p>
</div>
<div class="wrapper">
<div id="leftsideright"></div>
<div id="llogo"></div>
</div>
<div id="leftsidebottom"></div>
</div>
<div id="right">
<div id="rightsidetop">
<ul>
<li>About</li>
<li>Services</li>
<li>Clients</li>
<li>Contact</li>
</ul>
</div>
<div class="wrapper">
<div id="logo"></div>
<div id="rightsideright"></div>
</div>
<div id="rightsidebottom"></div>
</div>
</div>
</div>
<div class="video"></div>
<div style="height:150vh"> more content later </div>
just add to element you want to be scrollable an overflow: auto;
e.g :
#right {
overflow: auto;
}