How to fix display flex with percent width columns 1px gap? - html

On specific width display flex columns with percent width leave one 1px gap
http://prntscr.com/gyhatt
html,
body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
.wrapper {
max-width: 1200px;
padding: 30px;
}
.container {
display: flex;
flex-wrap: wrap;
background: red;
}
.g {
padding: 30px;
}
.grid-33 {
width: 33.3333%;
}
.grid-50 {
width: 50%;
}
.grid-66 {
width: 66.6666%;
}
.grid-100 {
width: 100%;
}
.white {
background: #fff;
}
.yellow {
background: #ffb401;
}
<div class="wrapper">
<div class="container">
<div class="g white grid-66">
<p>Test</p>
</div>
<div class="g yellow grid-33">
<p>Test</p>
</div>
</div>
</div>
fiddle
I have already tried setting the grid-33 at 33.3334% and it does not work plus it is not useful since I am working with a framework and cant "nudge" specific columns to fix an actual layout issue. I was hoping that flex box dimensions would be like display table where px are rounded up but seems like that is not the case.
Any help is appreciated.

That issue is a bug (or rounding issue) that among other Chrome and Edge have, but not Firefox.
https://lists.webkit.org/pipermail/webkit-unassigned/2006-January/002684.html
http://cruft.io/posts/percentage-calculations-in-ie/
https://johnresig.com/blog/sub-pixel-problems-in-css/
I found 2 workarounds, one where you add justify-content: space-between; to the flex container (still it appears that at some screen width's Chrome still has that 1px issue)
Stack snippet
html,
body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
.wrapper {
max-width: 1200px;
padding: 30px;
}
.container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
background: red;
}
.g {
padding: 30px;
}
.grid-33 {
width: 33.3333%;
}
.grid-50 {
width: 50%;
}
.grid-66 {
width: 66.6666%;
}
.grid-100 {
width: 100%;
}
.white {
background: #fff;
}
.yellow {
background: #ffb401;
}
<div class="wrapper">
<div class="container">
<div class="g white grid-66">
<p>Test</p>
</div>
<div class="g yellow grid-33">
<p>Test</p>
</div>
</div>
</div>
And the other is to use flex: 1 1 0/flex: 2 2 0, where the flex-grow/flex-shrink is 1 of 3 and 2 of 3, so they both grow and shrink equally.
Note, is is important to use it like this, where its flex-basis is set to 0, or else the content will be taken into account before the available space will be distributed between the items.
html,
body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
.wrapper {
max-width: 1200px;
padding: 30px;
}
.container {
display: flex;
flex-wrap: wrap;
background: red;
}
.g {
padding: 30px;
}
.grid-33 {
width: 33.3333%;
flex: 1 1 0;
}
.grid-50 {
width: 50%;
}
.grid-66 {
width: 66.6666%;
flex: 2 2 0;
}
.grid-100 {
width: 100%;
}
.white {
background: #fff;
}
.yellow {
background: #ffb401;
}
<div class="wrapper">
<div class="container">
<div class="g white grid-66">
<p>Test</p>
</div>
<div class="g yellow grid-33">
<p>Test</p>
</div>
</div>
</div>

If you want you can leave the width attribute and go with flex-grow it's an attribute of flex:
In your case, I tried using -
.grid-33 {
flex-grow: 3;
-webkit-flex-grow: 3;
}
.grid-66 {
flex-grow: 7;
-webkit-flex-grow: 7;
}
and in my view, it looks same if there is any change you can adjust it with flex-grow value.
html,
body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
.wrapper {
max-width: 1200px;
padding: 30px;
}
.container {
display: flex;
flex-wrap: wrap;
background: red;
}
.g {
padding: 30px;
}
.grid-33 {
flex-grow: 3;
-webkit-flex-grow: 3;
}
.grid-50 {
width: 50%;
}
.grid-66 {
flex-grow: 7;
-webkit-flex-grow: 7;
}
.grid-100 {
width: 100%;
}
.white {
background: #fff;
}
.yellow {
background: #ffb401;
}
<div class="wrapper">
<div class="container">
<div class="g white grid-66">
<p>Test</p>
</div>
<div class="g yellow grid-33">
<p>Test</p>
</div>
</div>
</div>

Related

Child of a "flex: 1" parent and a "min-height" grand-parent not taking "width: 100%"

I need to have a footer hidden just after the bottom of the screen, and be able to use the entire flex-grown remaining height for the content children, without inheriting max-height all the way down, is it possible?
Here "Grand child" isn't taking the entire height :
body {
margin: 0;
}
header {
height: 60px;
background-color: lightseagreen;
}
main {
/* pushes the footer just after the bottom */
min-height: calc(100vh - 60px);
display: flex;
flex-direction: column;
}
.content-child {
flex: 1;
}
.content-grand-child {
height: 100%;
}
footer {
height: 100px;
background-color: darkslategray;
}
/* added by editor for demonstration purpose */
.content-child,
.content-grand-child {
box-sizing: border-box;
border: 4px solid;
}
.content-child {
border-color: red;
}
.content-grand-child {
border-color: green;
}
<header>Header</header>
<main>
<div class="content-child">
<div class="content-grand-child">Grand child</div>
</div>
</main>
<footer>Footer</footer>
Is there a better solution to achieve this?
Just wrap the <header> and <main> in a container and apply the same flex-rules to it with a min-height: 100vh; that way, the header's height can be responsive/have an unknown height:
body {
margin: 0;
}
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
}
header {
height: 60px;
background-color: lightseagreen;
}
main {
display: flex;
flex-direction: column;
flex: 1;
}
.content-child {
flex: 1;
}
.content-grand-child {
height: 100%;
}
footer {
height: 100px;
background-color: darkslategray;
}
/* added by editor for demonstration purpose */
.content-child,
.content-grand-child {
box-sizing: border-box;
border: 3px solid;
}
.content-child {
border-color: red;
}
.content-grand-child {
border-color: green;
}
<div class="container">
<header>Header</header>
<main>
<div class="content-child">
<div class="content-grand-child">Grand child</div>
</div>
</main>
</div>
<footer>Footer</footer>

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>

Fitting everything within a static flex column

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>

Flex box layout,adjusting height of a block

How can I adjust height of .half-containers1 and .half-containers2?
And what's the best way to get that triangle I've marked in the image? is it possible with css only? or i must use image?
Here is my fiddle and the
Image of layout I'm trying to do
html,
body {
margin: 0;
height: 100%;
}
div {
box-sizing: border-box;
border: 0.5px solid red;
}
.main-container {
height: 100%;
display: flex;
}
.left-container {
flex: 1 1 0;
}
.center-container {
flex: 1 1 0;
display: flex;
flex-direction: column;
}
.right-container {
flex: 1 1 0;
display: flex;
flex-direction: column;
}
.half-containers1 {
flex: 1;
height: 400px;
}
.half-containers2 {
flex: 1;
height:100px;
background-image: url("https://upload.wikimedia.org/wikipedia/en/7/78/Small_scream.png")
}
<div class="main-container">
<div class="left-container">Left container</div>
<div class="center-container">
<div class="half-containers1">
<p>Center</p>
</div>
<div class="half-containers2">Center2</div>
</div>
<div class="right-container">
Right container
</div>
</div>
use flex-basis (flex: 0 X shorthand) in your halfcontainers and use ::after for doing the triangle
html,
body {
margin: 0;
height: 100%;
}
div {
box-sizing: border-box;
border: 1px solid red;
}
.main-container {
height: 100%;
display: flex;
}
.left-container {
flex: 1;
}
.center-container, .right-container {
flex: 1;
display: flex;
flex-direction: column;
}
.half-containers1 {
flex: 0 70% /*400px*/;
position: relative;
}
.half-containers1::after {
content: '';
position: absolute;
top: 100%;
left: 0;
right: 0;
margin: 0 auto;
width: 0;
height: 0;
border-top: solid 10px white;
border-left: solid 10px transparent;
border-right: solid 10px transparent;
}
.half-containers2 {
flex: 0 30%/*100px*/;
background: url("https://upload.wikimedia.org/wikipedia/en/7/78/Small_scream.png") no-repeat center / cover
}
<div class="main-container">
<div class="left-container">Left container</div>
<div class="center-container">
<div class="half-containers1">
<p>Center</p>
</div>
<div class="half-containers2">Center2</div>
</div>
<div class="right-container">
Right container
</div>
</div>

Flexbox Layout Query, Rows to Columns

I am trying to achieve a flexbox based transition from this (mobile):
To this (desktop):
However I am struggling to stack the two side panels vertically, my own code generates the main, search and other in a single row. I have not inserted webkit code for the sake of brevity.
Code:
p {
padding: 10px;
}
.flex-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.header {
flex: 1 0 100%;
background-color: pink;
}
.search {
flex: 1 100%;
background-color: yellow;
}
.main {
flex: 1 100%;
background-color: lightblue;
}
.other {
flex: 1;
background-color: Red;
}
#media (min-width: 600px) {
.flex-container {} .search {
flex: 1 0;
order: 2
}
.main {
flex: 3 0;
order: 1;
}
.other {
flex: 1 0;
order: 3
}
}
<div class="flex-container">
<div class="header">
<p>header</p>
</div>
<div class="search">
<p>search</p>
</div>
<div class="main">
<p>main</p>
</div>
<div class="other">
<p>other</p>
</div>
</div>
jsFiddle: https://jsfiddle.net/azizn/d2pmdvc4/
The problem here is that you can't really do that with Flexbox if your main elements (#main, #search and #other) are siblings unless you know the fixed height value of #search (hacky solution with position: absolute):
#header, .flex div {
padding: 1em;
box-sizing: border-box;
border: 1px solid red;
margin-bottom: 1em; }
.flex {
display: flex;
flex-direction: column;
position: relative; }
#main { min-height: 300px; order: 2; }
#other { order: 3; }
/* desktop version */
#media (min-width:768px) {
.flex { flex-direction: row; flex-wrap: wrap; }
#main { width: 60%; }
#search { order: 2; width: 40%; height: 100px }
#other { width: 40%; position: absolute; top: 100px; right: 0; }
}
<div id="header">header</div>
<div class="flex">
<div id="main">main</div>
<div id="search">search</div>
<div id="other">other</div>
</div>
jsFiddle: https://jsfiddle.net/azizn/uhwzyr9b/
So logically you could try to wrap #search and #other inside another container but then you couldn't position #content between them because Flexbox can alter order of siblings only... The only workaround for that is probably JavaScript.
Edit: You can achieve your layout by using good old floats instead of Flexbox:
#header, #main, #search, #other {
padding:1em;
box-sizing:border-box;
border:1px solid red;
margin-bottom:1em;
}
#main { min-height: 300px; }
#media (min-width:768px) {
.container { overflow: auto; }
#main { width: 60%; float: left; }
#search { width:40%; float: right; }
#other { width:40%; float: right; }
}
<div id="header">header</div>
<div class="container">
<div id="search">search</div>
<div id="main">main</div>
<div id="other">other</div>
</div>
jsFiddle: https://jsfiddle.net/azizn/g5vxtbed/