CSS flexbox two columns - html

I am trying to make a pure HTML/CSS site using flex box, using an image that takes up 50% of the left, a text box that takes up 50% of the right, and the footer takes up 100% of the width below them(I'll want to add a navigation later, maybe a hamburger menu, not relevant to this issues atm) , while making them responsive to devices of different sizes. *I want the image and right text box to wrap into a column(img on top of text box) on smaller devices
Problems I am running in to are, setting the image to max-width or max-height 100% makes it larger than the div container it in is, the image is not filling the box fully, (I want to keep the image proportionate to original size)
As you can see below, the image is not taking up 100% of the container, the below CSS is not the only CSS I've been experimenting with. But I have been looking at other articles I've found on stackoverflow etc, but nothing is looking for quite the same issue;
body {
font-family: 'Roboto Mono', monospace;
margin: 0px;
padding: 0px;
text-align: left;
display:block
}
img {
// width:auto;
max-height: 100%;
// overflow: none;
// position: absolute;
height: 400px;
// max-width: 100%;
top: 0;
bottom: 0;
border: 1px solid green;
}
.container {
display: flex;
flex-flow: row wrap;
}
.container > * {
padding: 0px;
flex: 1 100%; }
#media all and (min-width: 600px) {
.content {
flex: 1 0;
}
}

Please check below example. it's maybe helps you.
*, ::after, ::before {
box-sizing: border-box;
}
body {
margin: 0;
font-family:sans-serif;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
}
img {
max-width: 100%;
}
.container {
width: 100%;
max-width: 1140px;
margin: 0 auto;
padding-left: 15px;
padding-right: 15px;
}
.content {
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin-left: -15px;
margin-right: -15px;
}
.content .col {
-ms-flex: 0 0 50%;
flex: 0 0 50%;
max-width: 50%;
padding-left: 15px;
padding-right: 15px;
}
.footer {
background: #eee;
height: 100px;
}
#media(max-width: 767px){
.content .col {
-ms-flex: 0 0 100%;
flex: 0 0 100%;
max-width: 100%;
}
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title></title>
</head>
<body>
<div class="wrapper">
<main>
<div class="container">
<div class="content">
<div class="col left">
<img src="https://images.pexels.com/photos/994517/pexels-photo-994517.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" title="" alt=""/>
</div>
<div class="col right">
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</div>
</div>
</main>
<footer>
<div class="footer"></div>
</footer>
</div>
</body>
</html>

Related

Why isn't my text aligned to the bottom-left of my container?

I tried with padding-top and padding-right but the box moves and the text never gets blocked on the corner. Look at the images. I'm doing a basic card. I'm a 1-week beginner.
This is what I'm supposed to do:
This is what it looks like when I do what the video says:
.card {
height: 300px;
background: silver;
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 50px;
padding-top: 100px;
padding-right: 100px;
width: 500px;
}
<div class="card">
<h3>Swiss Bank.</h3>
<p>Digital Card.</p>
</div>
If I put more padding-top and right, the box continues opening and opening and is FREAKING frustrating
The issue comes from the height property that you used.
It's creating the space under the text.
If you get rid of it, the box will only be as big as the content.
In this case: padding-top + height of the text.
.card {
background: silver;
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 50px;
padding-top: 100px;
padding-right: 150px;
width: 500px;
box-sizing: border-box;
}
<div class="card">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
If you want your elements inside .card to be on bottom left corner, you should:
Assign position: relative; to .card and create a div tag inside .card where you put your elements (h3 and p)
Assign to the div created
position: absoloute;
bottom: 0;
left: 0;
.card {
height: 300px;
background: silver;
display: block;
width: 500px;
position: relative;
}
.corner {
position: absolute;
bottom: 0;
left: 0;
}
<div class="card">
<div class="corner">
<h3>Swiss Bank.</h3>
<p>Digital Card.</p>
</div>
</div>
I like a flexbox solution here. It's simpler than absolute positioning in terms of markup and more, er, flexible.
.card {
width: 500px;
height: 300px;
background: silver;
margin-left: auto;
margin-right: auto;
display: flex;
flex-direction: column;
justify-content: end;
padding-right: 30%; /* only needed if you want to limit text width */
}
<div class="card">
<h3>Swiss Bank.</h3>
<p>Digital Card.</p>
</div>
If you're willing to add a bit more markup in your html, you can reduce the amount of CSS you use with flexbox (there's a good guide at CSS tricks and this video from Kevin Powell and also flexbox froggy game which is kinda fun.
.card {
height: 300px;
width: 500px;
background: silver;
display: flex;
align-items: flex-end;
}
<div class="card">
<div><!-- Added this extra container -->
<h3>Swiss Bank.</h3>
<p>Digital Card.</p>
</div>
</div>

position two divs with position fixed after each other without setting explicit heights

With the snippet below I would like to have the fixed divs appear in the screenshot below preferably without having to set an explicit height or margin-top because if I do that, I will need different heights at different breakpoints and I don't want to use javascript.
Is it possible to stack position: fixed divs in this way without explicit heights or margin-top?
body {
text-rendering: optimizespeed;
height: 100%;
background-color: rgb(241, 241, 241);
}
#root {
height: 100%;
display: grid;
grid-template:
"header" auto
"main" 1fr
"footer" auto / 1fr;
}
.scroller {
height: 150vh;
overflow: auto;
border: 10px solid red;
}
main {
position: relative;
}
.ours {
border: 10px solid blue;
position: fixed;
width: 100%;
left: 0px;
right: 0px;
top: 0px;
}
.third-party {
align-items: center;
background-color: rgb(255, 255, 255);
box-sizing: border-box;
display: grid;
grid-template-areas: "leading center trailing";
justify-content: space-between;
position: fixed;
width: 100%;
left: 0px;
right: 0px;
top: 0px;
z-index: 1000;
border: 3px solid green;
}
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
<link type="text/css" rel="stylesheet" href="/src/styles.css" />
</head>
<body>
<div id="root">
<header class="ours">Should be no.1</header>
<main>
<div class="third-party">
<header>should be no.2</header>
</div>
<div class="scroller">
scroller should come after 2
</div>
</main>
</div>
</body>
</html>
wrap div one and two with another div and apply position:sticky to it with top:0
Sample:
.one {
background-color: red;
}
.two {
background-color: green;
}
.scroll {
height: 800px;
border: 2px dashed;
padding: 10px;
}
.fixed {
position: sticky;
top: 0;
width: 100%;
}
.main {
padding: 0;
margin: 0
}
<div class="main">
<div class="fixed">
<div class="one">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </div>
<div class="two">Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</div>
<div class="scroll"> Something in scroll div </div>
</div>

How to make a lightbox with flexible content (headline, image and description) with flexbox?

I've created a web app based on Bootstrap and I try to add a lightbox to it. I've looked for various plugins, but none will meet my requirements unfortunately.
My lightbox has two main sections that fight me really hard: an image on the top and a text with a headline and a description on the bottom.
The problem that I'm facing is, I want the lightbox restrict the size of the content, means, if the whole content is bigger then 100% vh or vw it should scale it down. And because that is hard to do with text, the image needs to be scaled. But whatever I do, I can not make the image scalable.
This is what I have so far:
HTML
<div id="agp-lightbox" class="agp-lightbox" #click="$emit('close')">
<div class="lightbox-content" :key="this.index">
<div class="content-left">
<a class="prev" #click.stop="prev" v-show="hasPrev()"><span class="fa fa-chevron-left"></span></a>
</div>
<div class="content-middle">
<div class="close cursor fa fa-window-close" #click="$emit('close')"></div>
<div class="numbertext">{{this.index+1}}/{{this.amount}}</div>
<div class="img-box">
<img v-bind:src="this.imglink">
</div>
<div class="caption-container">
<h3>{{this.info.title}}</h3>
<span v-html="this.info.description_de"></span>
<p>
Material: {{this.info.material_de}},
Preis: {{this.info.price}},
Format: {{this.info.artwork_format}}
</p>
</div>
</div>
<div class="content-right">
<a class="next" #click.stop="next" v-show="hasNext()"><span class="fa fa-chevron-right"></span></a>
</div>
</div>
</div>
CSS
.agp-lightbox {
position: fixed;
display: flex;
justify-content: center;
align-items: center;
z-index: 99;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
min-width: 0;
min-height: 0;
background-color: rgba(0, 0, 0, 0.8);
}
.lightbox-content {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 20px;
height: 90%;
width: 90%;
min-width: 0;
min-height: 0;
border: solid 1px red;
overflow: hidden;
}
.content-left {
color: white;
border: solid 1px green;
}
.content-middle {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-width: 0;
min-height: 0;
overflow: hidden;
border: solid 1px lightskyblue;
}
.content-right {
color: white;
border: solid 1px yellow;
}
.caption-container {
color: white;
}
.img-box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-width: 0;
min-height: 0;
overflow: hidden;
border: solid 1px orange;
}
.img-box img {
display: flex;
}
.close, .number-text {
display: none;
}
As said, it works in general, but as soon the image gets to big, it will not shrink so the whole content will not fit and gets cut (.lightbox-content). It gets even tougher when the image is not in landscape, but portrait format...
Also here is a JS Fiddle for the example...
https://jsfiddle.net/qg52jh6a/
As a last resort, I could restrict the image size, but I want it as flexible as possible. Any ideas?
I'd use the image as a background-image and set its attributes via css instead of loading it as an image.
I have simplified your markup considerably because there is a lot of unnecessary bits in there. All you need is to use CSS flexbox in the lightbox, and then use object-fit: contain for your image. If you wish the image to be cropped so that it covers all area, then use object-fit: cover.
Object fit is actually very widely supported today, with the notable exception of IE11 of course.
body {
margin: 0;
padding: 0;
}
.lightbox {
position: fixed;
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
}
.lightbox__caption {
flex-grow: 0;
}
.lightbox__image {
flex-grow: 1;
overflow: hidden;
}
.lightbox__image img {
object-fit: contain;
width: 100%;
height: 100%;
}
<div class="lightbox">
<div class="lightbox__image">
<img src="https://picsum.photos/800/600">
</div>
<div class="lightbox__caption">
<h3>Title</h3>
<span>Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </span>
</div>
</div>

White space outside the html

I have a simple div which is supposed to be at the centre of the screen. The same code works in Chrome, Firefox but a white space is generated around the html in IE11 and Microsoft Edge.
Please provide any workarounds other than setting the overflow to hidden. I have content which might overflow vertically.
https://i.stack.imgur.com/ayi34.png
body {
margin: 0;
padding: 0;
}
.container {
position: relative;
width: 100%;
height: 100%;
background-color: blue;
}
.inner {
position: absolute;
width: 200px;
height: 300px;
background-color: red;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div class="container">
<div class="inner"></div>
</div>
Use flexbox, here is an example that I tested in IE11 so it should work for all your supported browsers. I added a margin for the max size so the red box doesn't take up the entire screen, you can remove that if you don't care about that. I also converted your height and width into min-height and min-width in case you wanted the default smallest size.
body {
margin: 0;
padding: 0;
height: 100%;
}
.container {
width: 100%;
height: 100%;
background-color: blue;
display: flex;
align-content: center;
align-items: center;
justify-content: center;
}
.inner {
min-width: 200px;
min-height: 300px;
background-color: red;
margin: 4em;
}
<div class="container">
<div class="inner">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
</p>
</div>
</div>
The code snippet you provided doesn't reproduce the issue. It only shows the red div. Do you want the inner red div in the center of the outside blue div? I make a demo and it works in IE 11 and Edge, you could check it:
body {
margin: 0;
padding: 0;
}
.container {
text-align: center;
width: 100%;
height: 100%;
background-color: blue;
}
.inner {
display: inline-block;
vertical-align: middle;
width: 200px;
height: 300px;
background-color: red;
margin: 4em;
}
<div class="container">
<div class="inner"></div>
</div>

Nested divs. Autoset bottom div height according to top div size

I have a parent div with fixed height. Inside it I have two divs aligned to top and bottom. Top div has max-height and min-height. When it is a lot of text inside div in grows until max-height.
In this case bottom div should fill rest spaces of parent div when there is few data inside top div.
.div1 {
border: 1px solid blue;
top: 0;
position: absolute;
width: 100%;
overflow: auto;
max-height: 384px;
min-height: 160px;
}
.div2 {
border: 1px solid red;
bottom: 0;
position: absolute;
height: auto;
min-height: 202px;
}
.parent_el {
height: 586px !important;
border: 1px solid black;
position: relative;
}
<div class="parent_el">
<div class="div1" id=div1>
Text. Here can be huge text also
</div>
<div id="map" class="div2">
Here would be picture or map so it must grow in height when top div is small
</div>
</div>
This is a perfect case for a flexbox:
.parent_el {
display: flex; /*make parent a flexbox*/
flex-direction: column; /*children should go down the page*/
}
.div2 {
flex: 1; /*fill the rest of the container*/
}
Remove position: absolute and width: 100% as I've done in my Snippets.
Snippet demonstrating min-height:
.parent_el {
display: flex; /*make parent a flexbox*/
flex-direction: column; /*children should go down the page*/
height: 586px;
border: 1px solid black;
}
.div1 {
border: 1px solid blue;
max-height: 384px;
min-height: 160px;
overflow: auto;
}
.div2 {
flex: 1; /*fill the rest of the container*/
border: 1px solid red;
}
<div class="parent_el">
<div class="div1">
Text. Here can be huge text also
</div>
<div class="div2">
Here would be picture or map so it must grow in height when top div is small
</div>
</div>
Snippet demonstrating max-height:
.parent_el {
display: flex; /*make parent a flexbox*/
flex-direction: column; /*children should go down the page*/
height: 586px;
border: 1px solid black;
}
.div1 {
border: 1px solid blue;
max-height: 384px;
min-height: 160px;
font: 50px arial;
overflow: auto;
}
.div2 {
flex: 1; /*fill the rest of the container*/
border: 1px solid red;
}
<div class="parent_el">
<div class="div1">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
<div class="div2">
Here would be picture or map so it must grow in height when top div is small
</div>
</div>