I would really appreciate it if someone can enlighten me with my css layout issue. On my localhost, I am using Firefox's responsive design mode tool to check my layout in iPhoneX and everything seems to be going according to plan. However, when I deploy it to Heroku, and open the page, everything goes haywire. Here is what it looks like:
*EDIT: The one on the left is from Firefox's Responsive Design Mode, the one on the right is the from iOs' Safari.
First of all, forgive my naivete but I was thinking that the simulation in Firefox should match the actual output in iOs Safari otherwise it would be difficult to test layouts. :) So the code snippet can verify this when you run the snippet on mobile it replicates my exact issue.
Secondly, I can't for the life of me, see what actually I am doing wrong with my CSS. (facepalm). Again, any help is appreciated.
#splash-bg {
height: 150px;
width: 100vw;
background: url("https://images.unsplash.com/photo-1425326452142-67c31f601d2f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2982&q=80") no-repeat center 50px fixed;
background-size: contain;
border: 1px solid black;
}
#brand-info {
width: 100%;
display: flex;
flex-direction: column-reverse;
}
#brand-info #desc {
padding: 20px;
background-color: #ffd400;
}
#brand-info #desc img {
width: 100%;
max-height: 50px;
margin: 20px 0 10px 0;
border: 1px solid black;
}
#brand-info #desc p {
text-align: justify;
font-size: 0.8em;
line-height: 1.2em;
color: #000;
}
#brand-info #desc .social {
display: flex;
flex-direction: columns;
justify-content: space-evenly;
margin-top: 50px;
}
#brand-info .store-slides {
grid-column: 1 / 11;
grid-row: 1 / 4;
display: grid;
grid-template-columns: repeat(10, 1fr);
grid-template-rows: repeat(10, 1fr);
background-color: #ffd400;
// width: 100vw;
}
#brand-info .store-slides .brand-stores {
grid-column: 1 / 11;
grid-row: 1 / 11;
width: 100%;
display: grid;
grid-template-columns: repeat(10, 1fr);
grid-template-rows: repeat(10, 1fr);
}
#brand-info .store-slides .brand-stores img {
width: 100%;
height: 100%;
object-fit: contain;
grid-column: 1 / 11;
grid-row: 1 / 11;
border: 1px solid black;
}
#brand-info .store-slides .brand-stores .label {
grid-column: 4 / 11;
grid-row: 6 / 7;
font-size: 0.8em;
background-color: rgba(255, 212, 0, 0.5);
display: flex;
align-items: center;
padding: 0 0 0 20px;
color: #000;
font-weight: bold;
}
#brand-info .store-slides #left {
grid-column: 1 / 2;
grid-row: 5 / 7;
transform: rotate(90deg);
align-self: center;
justify-self: center;
}
#brand-info .store-slides #right {
grid-column: 10 / 11;
grid-row: 5 / 7;
transform: rotate(-90deg);
align-self: center;
justify-self: center;
}
<div id="fp-container">
<div id="splash-bg">
</div>
<div id="brand-info">
<div id="desc">
Brand Logo
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed malesuada ex eget enim lobortis dictum pharetra vel odio. Integer vulputate, ligula at placerat accumsan, nibh lectus consectetur metus, in consectetur nulla nunc at ante. Morbi felis leo, pellentesque
sit amet enim sit amet, blandit malesuada lacus.
</p>
<div class="social">
instagram
<router-link to="/locator">facebook</router-link>
</div>
</div>
<div class="store-slides">
<div class="brand-stores">
<img src="https://images.unsplash.com/photo-1425326452142-67c31f601d2f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2982&q=80" alt="" />
<div class="label">Store Name 1</div>
</div>
<div id="left" class="arrows">left arrow</div>
<div id="right" class="arrows">right arrow</div>
</div>
</div>
</div>
Related
As the title says, here's my example
I've already tried doing this using flex with position absolute but the problem is the responsiveness. How do I make this better? Is there a way that I could do this with just flexbox and not use position absolute while making the first row of the first and last column have equal height?
Here's my initial code:
<div class="block uk-width-1-1">
<div class="content-wrapper">
<div class="content uk-position-relative">
<div>
<div class="uk-grid uk-child-width-1-4 uk-flex-between">
<div class="card--wrapper">
<div class="card">
<h3>Lorem Ipsum</h3>
<p class="description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam quis tortor ut ante rhoncus placerat. Nam at placerat tellus, a accumsan nisi.</p>
</div>
</div>
<div class="card--wrapper">
<div class="card">
<h3>Lorem Ipsum</h3>
<p class="description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam quis tortor ut ante rhoncus placerat. Nam at placerat tellus, a accumsan nisi.</p>
</div>
</div>
</div>
<div class="uk-grid uk-child-width-1-4 uk-flex-between">
<div class="card--wrapper">
<div class="card">
<h3>Lorem Ipsum</h3>
<p class="description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam quis tortor ut ante rhoncus placerat. Nam at placerat tellus, a accumsan nisi.</p>
</div>
</div>
<div class="card--wrapper">
<div class="card">
<h3>Lorem Ipsum</h3>
<p class="description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam quis tortor ut ante rhoncus placerat. Nam at placerat tellus, a accumsan nisi.</p>
</div>
</div>
</div>
</div>
<div class="image--wrapper uk-position-absolute uk-width-1-3">
<div class="image">
<!-- Image here (middle column)-->
<img src="/../images/hero-sample.png" alt="image">
</div>
</div>
</div>
</div>
</div>
CSS
.image--wrapper {
position: absolute;
left: 50%;
transform: translateX(-50%);
top: 0;
}
.block {
background: green;
}
h3, p.description {
color: white;
font-family: 'Poppins';
}
p.description {
font-weight: 400;
font-size: 14px;
line-height: 21px;
color: rgba(255,255,255,0.7);
margin-bottom: 0;
}
h3 {
font-weight: 600;
font-size: 16px;
line-height: 28px;
}
.card {
max-width: 240px;
padding: 20px;
box-sizing: border-box;
border: 1px solid rgba(255,255,255, 0.3);
}
.child-width-1-4 > div {
width: 25%;
}
.width-1-3 {
width: 33%;
}
.grid {
display: flex;
flex-wrap: wrap;
margin: 18.12px 0 0 0;
padding: 0;
}
.flex-between {
justify-content: space-between;
}
.position-absolute {
position: absolute !important;
}
.position-relative {
position: relative !important;
}
#media screen and (max-width: 1200px) {
.content-wrapper {
padding: 60px 25px
}
}
In this solution, the outer container is a grid with 12 columns. The middle column (.col2) takes up twice the space of col1 and col3. The -1 in grid-column: 10 / -1 means to span to the end of the grid, wherever it is.
Inside, I make the first and last columns into flexboxes, so that their children can take up an even amount of space in their respective containers. All spacing between columns and rows is accomplished using gap.
.container {
display: grid;
grid-template-columns: repeat(12, 1fr);
min-height: 100vh;
min-height: 100dvh;
gap: 1rem;
padding: 1rem;
}
/* 3 columns */
.col1 {
grid-column: 1 / 4;
}
/* 6 columns */
.col2 {
grid-column: 4 / 10;
}
/* 3 columns */
.col3 {
grid-column: 10 / -1;
}
.col1,
.col3 {
display: flex;
flex-direction: column;
gap: 1rem;
}
.col1 > *,
.col3 > * {
flex: 1;
}
body { margin: 0; }
* { box-sizing: border-box; }
.col2, .container > * > * { border: 1px solid; }
<div class="container">
<div class="col1">
<div></div>
<div></div>
</div>
<div class="col2"></div>
<div class="col3">
<div></div>
<div></div>
</div>
</div>
jsFiddle
there is more than one way to do that. I personally prefer using flex for such situations because it's more flexible for adjustment.
so basically, I used three containers in a row flex-direction then in the containers on the sides, I put 2 divs in each with column flex-direction. that's it.
you can control max and min width as you wish.
body {
background: lightgrey;
display: flex;
justify-content: center;
}
#container {
/* background: lightcoral; */
width: 100%;
height: 400px;
display: flex;
flex-direction: row;
}
.middle {
width: 60%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.left, .right{
width: 20%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.left div,
.right div {
border: 1px solid;
width: 100%;
height: 50%;
margin: 10px;
}
.middle div {
border: 1px solid;
width: 95%;
height: 100%;
margin: 10px;
}
<body>
<div class="container" id="container">
<div class="left">
<div></div>
<div></div>
</div>
<div class="middle">
<div></div>
</div>
<div class="right">
<div></div>
<div></div>
</div>
</div>
</body>
In your problem its better to display grid instead of flex
div1: middle
div2: left-top
div3: left-bottom
div4: right-top
div5: right-bottom
.parent {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(2, 1fr);
grid-column-gap: 0px;
grid-row-gap: 0px;
}
.div1 { grid-area: 1 / 2 / 3 / 5; }
.div2 { grid-area: 1 / 1 / 2 / 2; }
.div3 { grid-area: 2 / 1 / 3 / 2; }
.div4 { grid-area: 1 / 5 / 2 / 6; }
.div5 { grid-area: 2 / 5 / 3 / 6; }
This is my first time ever using grid layout, and I'm having trouble having my p tags fill the content of the cell they occupy. So, I do not need help making the grid. I need help expanding the text of the p tag to fill the cell of which the p tag occupies.
Here is the code: NOTE: The first half consists of Andy Bell's Modern CSS Reset. I modified only parts of it which would've been overwritten later.
*, *::before, *::after {
box-sizing: border-box;
}
body, p {
margin: 0;
}
html:focus-within {
scroll-behavior: smooth;
}
html::-webkit-scrollbar {
display: none;
}
html, body {
width: 100%;
height: 100%;
}
body {
font-size: 1rem;
height: 100%;
overflow: hidden;
min-height: 100vh;
text-rendering: optimizeSpeed;
line-height: 1;
}
a:not([class]) {
text-decoration-skip-ink: auto;
}
img,
picture {
max-width: 100%;
display: block;
}
#media (prefers-reduced-motion: reduce) {
html:focus-within {
scroll-behavior: auto;
}
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
.container {
width: 100%;
height: 100%;
}
.typography-grid {
width: 100%;
height: 100%;
display: grid;
grid-auto-columns: 1fr;
grid-auto-rows: 1fr;
grid-template-areas:
'text-section-one text-section-one . . . . .'
'. . image image image . .'
'small-text . . . . text-section-two text-section-two';
}
img {
grid-area: image;
aspect-ratio: 1;
width: 65%;
margin: 0 auto;
z-index: 1;
box-shadow: 0px 0px 10px 0px black;
}
/* p {
width: 100%;
font-size: 2rem;
font-size: 5vw;
} */
.text--small {
font-style: italic;
width: 80%;
text-align: left;
grid-area: small-text;
}
#large1 {
grid-area: text-section-one;
}
#large2 {
letter-spacing: 1rem;
grid-column: 2 / 7;
grid-row: 2;
}
#large3 {
grid-area: text-section-two;
}
<!DOCTYPE html>
<html>
<head>
<!--
<script>
textFit(document.querySelector("p"), 0.5);
fitText(document.querySelector("p"), 0.5);
fitty('p');
</script>
-->
</head>
<body>
<div class="container">
<div class="typography-grid">
<p class="text text--large" id="large1">TEXT</p>
<p class="text text--large" id="large2">TEXT</p>
<img src="https://andyspizzaandsubs.com/wp-content/uploads/2018/11/blog-ph.jpg" alt="sample image">
<p class="text text--small">SAMPLE TEXT SAMPLE TEXT SAMPLE TEXT SAMPLE TEXT SAMPLE TEXT SAMPLE TEXT SAMPLE TEXT SAMPLE TEXT</p>
<p class="text text--large" id="large3">TEXT</p>
</div>
</div>
</body>
</html>
I've tried the items commented out under the p tag selector, but there doesn't seem to be a perfect magic number where everything doesn't get pushed out of frame. I've also tried width: fit-content; to see if that would change anything, but nothing did.
Last thing I tried was following this previous SO post: Font scaling based on width of container
I used script tags in the head of my HTML (which didn't work), and the relative units didn't work for reasons mentioned before.
Is this possible? I'm aiming for a large-typography-style website, so I need the p tags to fill the grid cells they occupy, or sort of stretch to fill the cells they occupy. Is there a workaround? Any help is appreciated! Thank you.
.container {
display: grid;
grid-template-columns: repeat(8, 1fr);
gap: 5px;
}
.container div {
border: 1px solid red;
}
.item1 {
grid-column: 1 / span 2;
}
.item2 {
grid-column: 3 / span 6;
}
.item3 {
grid-column: 1 / span 1;
}
.item4 {
grid-column: 2 / span 6;
place-self: center;
}
.item5 {
grid-column: 8 / span 1;
}
.item6 {
grid-column: 1 / span 1;
}
.item7 {
grid-column: 2 / span 5;
}
.item8 {
grid-column: 7 / span 2;
}
<div class="container">
<div class="item1">text-selection-one - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pellentesque risus libero. Integer nec maximus mi. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</div>
<div class="item2">item2</div>
<div class="item3">item3</div>
<div class="item4"><img src="https://andyspizzaandsubs.com/wp-content/uploads/2018/11/blog-ph.jpg" style="width:100px; height:auto" alt="Sample image"></div>
<div class="item5">item5</div>
<div class="item6">small-text - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pellentesque risus libero. Integer nec maximus mi. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</div>
<div class="item7">item7</div>
<div class="item8">text-selection-three</div>
</div>
I am having a problem understanding how CSS grid works.
I want 3 columns side by side with a specific width and height, but there's a gap between each columns.
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr;
grid-column-gap: 0px;
}
.left {
grid-column: 1;
border: 1px solid red;
height: 500px;
width: 300px;
}
.middle {
grid-column: 2;
border: 1px solid red;
height: 500px;
width: 300px;
}
.right {
grid-column: 3;
border: 1px solid red;
height: 500px;
width: 300px;
}
<div class="grid-container">
<div class="left">1</div>
<div class="middle">2</div>
<div class="right">3</div>
</div>
In which way I can put away this gap? And if anyone can explain me how to reduce the line of code in css I would be grateful, thanks!
EDIT
I solved in this way
.wrapper{
display: grid;
place-items: center;
min-height: 100vh;
}
.grid-container{
margin: 0 auto;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr;
grid-column-gap: 0px;
width: 60vw;
height: 450px;
}
.left{
background-color: hsl(31, 77%, 52%);
grid-column: 1;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
}
.middle{
background-color: hsl(184, 100%, 22%);
grid-column: 2;
}
.right{
background-color: hsl(179, 100%, 13%);
grid-column: 3;
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
}
<div class="wrapper">
<div class="grid-container">
<div class="left">
<img src="images/icon-sedans.svg" alt="sedans" class="logo">
<h2 class="text-title">Sedans</h2>
<div class="main-text">
Choose a sedan for its affordability and excellent fuel economy. Ideal for cruising in the city
or on your next road trip.
</div>
<button class="btn">Learn More</button>
</div>
<div class="middle">
<img src="images/icon-suvs.svg" alt="sedans" class="logo">
<h2 class="text-title">Suvs</h2>
<div class="main-text">
Take an SUV for its spacious interior, power, and versatility. Perfect for your next family vacation
and off-road adventures.
</div>
<button class="btn">Learn More</button>
</div>
<div class="right">
<img src="images/icon-luxury.svg" alt="sedans" class="logo">
<h2 class="text-title">Luxury</h2>
<div class="main-text">
Cruise in the best car brands without the bloated prices. Enjoy the enhanced comfort of a luxury
rental and arrive in style.
</div>
<button class="btn">Learn More</button>
</div>
</div>
</div>
But now what I want to do is to make all of this to be responsive
Specify your width on your grid parent, remove any static width on your child elements. With the fraction set in grid-template-columns: 1fr 1fr 1fr; each column will take up a third of the parents width. So if your parent is set to say 80 view width => 80% of the view port, then your columns will spread out over a third of that width each.
If you have had 4 items each set to 1fr, then they would take up 25%, 5 would take up 20%, basically => number of children elements/parents width.
.grid-container {
margin: auto;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr;
grid-column-gap: 0;
width: 80vw;
}
.left>ul {
height: 80%;
background: pink;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: space-between;
}
.left {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border: 1px solid red;
grid-column: 1;
}
.middle {
padding: 5px;
grid-column: 2;
border: red solid 1px;
}
.middle span {
display: flex;
flex-direction: column;
justify-content: start;
padding: 5px;
grid-column: 2;
background: lightblue;
border-bottom: 1px solid black;
}
.right {
grid-column: 3;
border: 1px solid red;
padding: .2rem;
display: flex;
flex-direction: column;
justify-content: space-around;
}
.row {
padding: 0 1rem;
display: flex;
justify-content: space-between;
align-items: start;
background: #EEE;
}
.right div:nth-of-type(2) {
color: #a2a2a2;
text-align: center;
}
<div class="grid-container">
<div class="left">Here is some content for column 1 with list items
<ul>
<li>
display: flex
</li>
<li>
flex-direction: column
</li>
<li>
justify-content: space-around
</li>
<li>
align-items: flex-start
</li>
</ul>
</div>
<div class="middle">
<span>This is inside a span tag</span>
<span>Parent has flex direction of column</span>
<span>Justify Content set at start</span>
<span>this is inside a span tag</span> More content for column 2. it is a bit longer than the first textual content. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum viverra pulvinar tincidunt. Nam consequat metus et cursus auctor.
Suspendisse posuere sem ut tortor lacinia, nec tempor turpis ultrices. Sed vitae gravida orci.</div>
<div class="right">
<div class="row">
<h3>Row</h3>
<h3>Space</h3>
<h3>Between</h3>
</div>
<span>Parents flex <span style="background: pink;">flex-direction </span> and <span style="background: pink;">display-flex</span> <b>flex</b> and <b>column</b></span></span>
<span>Parents flex <span style="background: pink;">justify-content</span> is set to <b>space-around</b></span>
<div>Good ole text-align: center... Vestibulum viverra pulvinar tincidunt. Nam consequat metus et cursus auctor. Suspendisse posuere sem ut tortor lacinia, nec tempor turpis ultrices.
</div>
</div>
</div>
Example of vertically centering text with flex-direction set to column.
body {
margin: 0;
padding: 0;
}
.parent {
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
height: 100vh;
}
.child {
margin: 0 auto;
height: 200px;
width: calc(200px - 1rem);
background: lightblue;
display: flex;
flex-direction: column;
justify-content: center;
padding: .5rem;
}
<div class="parent">
<div class="child">Vertically centering using flex.
<br><br> Justify content when parents flex-direction is set to column, will center content vertically.</div>
</div>
You can simply specify the widths that you need in the grid-template-columns property. There is no gap visible between columns.
If you want the red borders you can specify a common class for those divs and just do it once.
.grid-container{
display: grid;
grid-template-columns: 300px 300px 300px;
grid-template-rows: 1fr;
column-gap: 0;
height: 500px;
}
.left{
border: 1px solid red;
}
.middle{
border: 1px solid red;
}
.right{
border: 1px solid red;
}
<div class="grid-container">
<div class="left">1</div>
<div class="middle">2</div>
<div class="right">3</div>
</div>
I am trying to create a webpage with a vertically and horizontally centred div, with defined height and width, split down the middle. Almost like an open book.
I have no problems with achieving this in Chrome/Firefox/Safari but cannot get this to reflect in IE11 as half of the 'book' has a greater height than the other half, which leads me to believe the 'height: 863px' property in .loginContainer is causing the issue as it looks marginally better once I move this.
Not totally sure but I think I need to specify an explicit height for the container to stop the content inside becoming squashed - simply removing this property allows the container to be too small so content looks cramped once I put text in there.
I have tried to remove the property and use padding on the content inside to create a bit of space but I don't feel this is the right approach and makes it appear totally different to the mock ups I'm following.
I have created a JSFiddle found here;
https://jsfiddle.net/e02cqdr6/2/
and think the issue lies at;
.loginContainer {
display: flex;
justify-content: flex-start;
flex-grow: 0;
flex-shrink: 1;
margin: 0 auto;
width: 1338px;
height: 863px;
border-radius: 15px;}
html,
body {
background-color: rgb(27, 27, 27);
height: 100%;
min-height: 100%;
/* for firefox */
}
.pageContainer {
display: flex;
flex-direction: column;
justify-content: center;
height: 100%;
}
.loginContainer {
display: flex;
justify-content: flex-start;
flex-grow: 0;
flex-shrink: 1;
margin: 0 auto;
width: 1338px;
height: 863px;
border-radius: 15px;
}
.leftContainer {
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
text-align: center;
background-color: green;
width: 621px;
border-radius: 15px 0 0 15px;
}
.rightContainer {
display: flex;
flex-direction: column;
background-color: #ffffff;
align-items: center;
width: 717px;
border-radius: 0 15px 15px 0;
}
.titleContainer {
display: flex;
flex-direction: column;
width: 100%;
}
input {
height: 30px;
width: 220px;
padding: 0 10px 0 10px;
box-shadow: none !important;
border: 1px solid rgb(243, 241, 241);
border-radius: 15px;
background-color: rgb(243, 241, 241);
color: grey;
}
a {
font-size: 0.7rem;
color: orange;
text-decoration: none;
}
.nextBtn {
margin-top: 10px;
background-color: rgb(134, 200, 223);
color: #ffffff;
}
.assetContainer {
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
}
.descContainer {
display: flex;
flex-direction: column;
text-align: center;
width: 100%;
}
.descHeading {
margin: 0 auto;
color: #fff;
font-family: Arial, Helvetica, sans-serif;
font-size: 36px;
font-style: normal;
font-weight: 100;
padding-bottom: 5px;
}
.productDesc {
margin: 0 auto;
color: #fff;
font-family: Arial, Helvetica, sans-serif;
font-size: 17px;
font-style: normal;
font-weight: 100;
width: 440px;
}
.assetLogoBlack {
width: 100%;
height: 100%;
}
.logoContainer {
width: 100%;
}
.servicesLogo {
width: 30%;
}
<div class="pageContainer">
<div class="loginContainer">
<div class="leftContainer">
<div class="assetContainer">
<div class="logoContainer">
<img src="/assets/ilogo.svg" class="servicesLogo">
<img src="/assets/cslogo.svg" class="servicesLogo">
</div>
<div class="descContainer">
<p class="descHeading">Lorem ipsum dolor sit amet</p>
<p class="productDesc">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi volutpat sodales arcu id tincidunt. Ut a laoreet risus. Suspendisse potenti. Curabitur in ultricies risus. Vivamus convallis non libero commodo malesuada. Cras eu neque vulputate
lectus sagittis ullamcorper sit amet vitae ante. Integer pellentesque neque eget molestie vehicula. </p>
</div>
</div>
</div>
<div class="rightContainer">
</div>
</div>
</div>
So I expect it to look like this: https://ibb.co/T2Cc59V
but instead it looks like this: https://ibb.co/M8zZ9rs
To reiterate, the problem only exists in IE11.
Nothing stands out as obvious and I have no errors thrown so am totally stumped as to how to resolve this.
Thank you for all the input, I have ended up stripping this back to bare bones to see what is causing the issue as it does work fine on the jsfiddle. It turns out it is the white space around the asset I need to use for the background makes it appear as though it doesn't fill the parent div.
This question already has answers here:
How to stretch children to fill cross-axis?
(3 answers)
Closed 4 years ago.
I feel a little silly asking this, but I've sort of exhausted my knowledge of Flexboxes, so I'm hoping maybe someone else can come in and help me out here.
My overall goal is to just have the two items in the middle row stretch to fill the space between the header and the items, and I have searched around and honestly can't figure out what it is that I should do. I forked the code from the CSS Tricks Guide, the one at the very bottom, and I've made some alterations. The code I currently have is (open it in full screen mode to make it more clear):
body,
html {
height: 100%;
}
.wrapper {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
justify-content: flex-start;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
height: 100%;
font-weight: bold;
text-align: center;
}
.wrapper > * {
padding: 10px;
flex: 1 1 100%;
}
.header {
background: tomato;
height: 50px;
flex: 1 1 100%;
}
.footer {
background: lightgreen;
height: 50px;
}
.main {
text-align: left;
align-self: stretch;
background: deepskyblue;
}
.aside-1 {
background: gold;
}
.aside-2 {
background: hotpink;
}
#media all and (min-width: 600px) {
.aside {
flex: 1 auto;
}
}
#media all and (min-width: 800px) {
.main {
flex: 3 0px;
}
.aside-1 {
order: 1;
}
.main {
order: 2;
}
.aside-2 {
order: 3;
}
.footer {
order: 4;
}
}
body {
padding: 2em;
}
<div class="wrapper">
<header class="header">Header</header>
<article class="main">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.
Mauris placerat eleifend leo.</p>
</article>
<aside class="aside aside-1">Aside 1</aside>
<footer class="footer">Footer</footer>
</div>
Is it possible in flexbox to achieve this without changing the HTML, or should I just look for another way to accomplish this goal?
While people are telling you how to resolve the issue, they are not telling you why you don't have the result you expected. I think it's partly because most of them missed the actual question. Which I found really interesting.
Let me get some things out of the way first :
Flex-direction:: For practical purpose it means the direction in which the items are displayed. However it's not accurate.
For now let's say that if the direction is set to row, it means that each item must have the height of the container and they should be put next to each other. In other words the container has to be considered a row and the item are the columns.
.c{
display: flex;
width: 400px;
height:100px;
}
.c1{
flex-grow: 1;
background:gold;
}
.c2{
flex-grow: 1;
background:red;
}
<div class="c">
<div class="c1"></div>
<div class="c2"></div>
</div>
I didn't specify an height, the items filled the height of the row and stacked against each others like columns.
When you specify an height the item will take the height you defined but that does not change the height of the row :
.c{
display: flex;
width: 400px;
height: 100px;
}
.c1{
flex-grow: 1;
height: 40px;
background:gold;
}
.c2{
flex-grow: 1;
background:red;
}
<div class="c">
<div class="c1"></div>
<div class="c2"></div>
</div>
The red cube still spawn the vertical space because the height of the row hasn't changed.
flex grow: the amount of free space distributed to the different items.
.c{
display: flex;
width: 400px;
}
.c1{
flex-grow: 1;
background:gold;
}
.c2{
flex-grow: 1;
background:red;
}
<div class="c">
<div class="c1">AAAAAAAAAAAAA</div>
<div class="c2"></div>
</div>
Despite having the same flex-grow value, those two items aren't the same size, that is because the free space is distributed among them but the yellow rectangle was bigger to begin with.
First let's use flex-wrap : wrap:
.c{
display: flex;
flex-wrap: wrap;
border: 1px solid black;
width: 400px;
height:100px;
}
.c1{
width:200px;
background:gold;
}
.c2{
width:200px;
background:red;
}
.c3{
width:100px;
background:orange;
}
.c4{
width:300px;
background:green;
}
<div class="c">
<div class="c1"></div>
<div class="c2"></div>
<div class="c3"></div>
<div class="c4"></div>
</div>
As we can see when we go beyond the amount of width available the items start under, effectively creating another row.
Now to address your question:
What if we took the example above and set the height of the first item ? Let's see:
.c{
display: flex;
flex-wrap: wrap;
border: 1px solid black;
width: 400px;
height:100px;
}
.c1{
width:200px;
height: 30px;
background:gold;
}
.c2{
width:200px;
background:red;
}
.c3{
width:200px;
background:orange;
}
.c4{
width:200px;
background:green;
}
<div class="c">
<div class="c1"></div>
<div class="c2"></div>
<div class="c3"></div>
<div class="c4"></div>
</div>
Like in your snippet.
Let's see another example:
.c{
display: flex;
flex-wrap: wrap;
border: 1px solid black;
width: 600px;
height:100px;
}
.c1{
width:400px;
height: 35px;
background:gold;
}
.c2{
width:200px;
background:red;
}
.c3{
width:200px;
background:orange;
}
.c4{
width:200px;
background:green;
}
.c5{
width:200px;
background:purple;
}
<div class="c">
<div class="c1"></div>
<div class="c2"></div>
<div class="c3"></div>
<div class="c4"></div>
<div class="c5"></div>
</div>
yellow cube of 400px X 35px is put and spans 2 columns, then red cube of 200px is put and spans 1 column.
At this point all the rectangles have 0 height except the first one which has 35px.
The remaining vertical space is divided between the rows as to spawn the whole vertical space. Thus the remaining vertical space is 100-35 = 65px.
divided in 2 rows = 32.5. The first row gets 35 + 32.5 and the second row gets 32.5px height.
Another example to make things clearer:
.c, .d{
display: flex;
flex-wrap: wrap;
border: 1px solid black;
width: 600px;
height:100px;
}
.c1{
flex-shrink: 0;
width:400px;
height: 0px;
background:gold;
}
.c2{
width:200px;
background:red;
}
.c3{
width:200px;
background:orange;
}
.c4{
width:200px;
background:green;
}
.c5{
width:200px;
background:purple;
}
.d1{
width:400px;
height: 50px;
background:gold;
}
.d2{
width:200px;
background:red;
}
.d3{
width:200px;
background:orange;
}
.d4{
width:200px;
background:green;
}
.d5{
width:200px;
background:purple;
}
First item has 0px height, the vertical space remaining (100px) is divided between the 2 rows. Both row have 50px height
<div class="c">
<div class="c1"></div>
<div class="c2"></div>
<div class="c3"></div>
<div class="c4"></div>
<div class="c5"></div>
</div>
First item has 35px height, the vertical space remaining (65px) is divided between the 2 rows.
<div class="d">
<div class="d1"></div>
<div class="d2"></div>
<div class="d3"></div>
<div class="d4"></div>
<div class="d5"></div>
</div>
To resolve this you can use calc() to calculate the other rows height like others suggested. The reason is that there is no more free vertical space to be shared.
.c{
display: flex;
flex-wrap: wrap;
border: 1px solid black;
width: 600px;
height:100px;
}
.c1{
width:400px;
height: 35px;
background:gold;
}
.c2{
width:200px;
background:red;
}
.c3{
height:calc(100% - 35px);
width:600px;
background:green;
}
<div class="c">
<div class="c1"></div>
<div class="c2"></div>
<div class="c3"></div>
</div>
The idea is to wrap them around a container and use flex-grow:1; on that container, this will make the container fill the space between the header and footer..
Then in the #media query, change the flex-direction of this container to row. This will make the .main and aside to come side by side on big screens.
body,
html {
height: 100%;
}
.wrapper {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
justify-content: flex-start;
flex-direction:column;
height: 100%;
font-weight: bold;
text-align: center;
}
.wrapper > * {
padding: 10px;
}
.header {
background: tomato;
height: 50px;
flex-shrink:0;
}
.footer {
background: lightgreen;
height: 50px;
flex-shrink:0;
}
.main {
text-align: left;
//align-self: stretch;
background: deepskyblue;
padding:10px;
}
.main p{
margin:0;
padding:0;
}
.aside-1 {
background: gold;
}
.aside-2 {
background: hotpink;
}
.container{
width:100%;
margin:0;
padding:0;
flex-grow:1;
flex-shrink:0;
}
#media all and (min-width: 600px) {
.aside {
flex: 1 auto;
}
}
#media all and (min-width: 800px) {
.container{
display:flex;
flex-direction:row;
}
.main {
flex: 3 0px;
flex-grow:1;
flex-shrink:0;
}
.aside-1 {
order: 1;
flex-grow:1;
flex-shrink:0;
}
.main {
order: 2;
}
.aside-2 {
order: 3;
}
.footer {
order: 4;
}
}
body {
padding: 2em;
}
<div class="wrapper">
<header class="header">Header</header>
<div class="container">
<article class="main">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.
Mauris placerat eleifend leo.</p>
</article>
<aside class="aside aside-1">Aside 1</aside>
</div>
<footer class="footer">Footer</footer>
</div>
You can't fill the remaining space in the cross-axis direction when you are using a wrapping flexbox - I guess you need a column flexbox for that.
But you can do this as a quick fix:
Add align-content: center to the flexbox (for resetting the default stretch value)
Adjust the heights using calc (have removed the body padding and margin for illustration)
See demo below:
body,
html {
height: 100%;
}
.wrapper {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
justify-content: flex-start;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
height: 100%;
font-weight: bold;
text-align: center;
align-content: center; /* ADDED THIS */
}
.wrapper > * {
padding: 10px;
flex: 1 1 100%;
}
.header {
background: tomato;
height: 50px;
flex: 1 1 100%;
}
.footer {
background: lightgreen;
height: 50px;
}
.main {
text-align: left;
align-self: stretch;
background: deepskyblue;
height: calc(50vh - 90px); /* ADDED THIS */
}
.aside-1 {
background: gold;
height: calc(50vh - 90px); /* ADDED THIS */
}
.aside-2 {
background: hotpink;
}
#media all and (min-width: 600px) {
.aside {
flex: 1 auto;
}
}
#media all and (min-width: 800px) {
.main {
flex: 3 0px;
}
.aside-1 {
order: 1;
height: calc(100vh - 160px); /* ADDED THIS */
}
.main {
order: 2;
height: calc(100vh - 160px); /* ADDED THIS */
}
.aside-2 {
order: 3;
}
.footer {
order: 4;
}
}
body {
/* padding: 2em;*/
margin: 0; /* ADDED THIS */
}
<div class="wrapper">
<header class="header">Header</header>
<article class="main">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.
Mauris placerat eleifend leo.</p>
</article>
<aside class="aside aside-1">Aside 1</aside>
<footer class="footer">Footer</footer>
</div>
Using calc is not very tidy and you would want to use a nested flexbox here (if it is ok to change the html):
Add a wrapper for the main and aside-1 and make it a wrapping flexbox in row direction
Add flex: 1 to this wrapper to fill the vertical space between the header and footer
See demo below:
body,
html {
height: 100%;
}
.wrapper {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
/*-webkit-flex-flow: row wrap;*/
/*flex-flow: row wrap;*/
flex-direction: column;
height: 100%;
font-weight: bold;
text-align: center;
}
.wrapper > * {
padding: 10px;
/*flex: 1 1 100%;*/
}
.header {
background: tomato;
height: 50px;
/*flex: 1 1 100%;*/
}
.footer {
background: lightgreen;
height: 50px;
}
.main {
text-align: left;
align-self: stretch;
background: deepskyblue;
}
.aside-1 {
background: gold;
flex: 1 auto;/* ADDED THIS */
}
.aside-2 {
background: hotpink;
}
.wrapper > section { /* ADDED THIS */
display: flex;
flex-flow:row wrap;
flex: 1;
padding: 0;
overflow: auto;
}
#media all and (min-width: 600px) {
.aside {
flex: 1 auto;
}
}
#media all and (min-width: 800px) {
.main {
flex: 3 0px;
}
.aside-1 {
order: 1;
}
.main {
order: 2;
}
.aside-2 {
order: 3;
}
.footer {
order: 4;
}
}
body {
/*padding: 2em;*/
margin: 0;
}
<div class="wrapper">
<header class="header">Header</header>
<section>
<article class="main">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.
Mauris placerat eleifend leo.</p>
</article>
<aside class="aside aside-1">Aside 1</aside>
</section>
<footer class="footer">Footer</footer>
</div>
After reading all the other answers, I decided to post my own.
I might have missed something already posted or misunderstood the question, though for me this should be the simplest solution, without any markup changed.
If this answers your question, I will add a short explanation why/how it works.
html, body {
margin: 0;
}
.wrapper {
display: flex;
flex-direction: column;
height: 100vh;
}
.header {
height: 50px;
}
.footer {
height: 50px;
}
.main {
text-align: left;
flex: 1;
}
#media (min-width: 600px) {
.aside {
flex: 1;
}
}
#media (min-width: 800px) {
.wrapper {
flex-direction: row;
flex-wrap: wrap;
}
.header {
flex-basis: 100%;
order: -1;
}
.main {
flex: 2;
}
.aside-1 {
order: -1;
height: calc(100% - 100px);
}
.footer {
flex-basis: 100%;
}
}
/* for styling */
.wrapper {
font-weight: bold;
text-align: center;
}
.wrapper > * {
padding: 10px;
box-sizing: border-box;
}
.header {
background: tomato;
}
.footer {
background: lightgreen;
}
.main {
background: deepskyblue;
}
.aside-1 {
background: gold;
}
<div class="wrapper">
<header class="header">Header</header>
<article class="main">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.
Mauris placerat eleifend leo.</p>
</article>
<aside class="aside aside-1">Aside 1</aside>
<footer class="footer">Footer</footer>
</div>
If you were able to change the markup, here is a version of mine, with a much simpler code base than others have given, and also the header and footer is without a fixed height.
html, body {
margin: 0;
}
.wrapper {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.innerwrapper {
flex: 1;
display: flex;
flex-direction: column;
}
.main {
flex: 1;
text-align: left;
}
#media (min-width: 600px) {
.aside {
flex: 1;
}
}
#media (min-width: 800px) {
.innerwrapper {
flex-direction: row;
}
.aside-1 {
order: -1;
}
}
/* for styling */
.wrapper {
font-weight: bold;
text-align: center;
}
.wrapper > *:not(.innerwrapper),
.wrapper .innerwrapper > * {
padding: 10px;
box-sizing: border-box;
}
.header {
background: tomato;
}
.footer {
background: lightgreen;
}
.main {
background: deepskyblue;
}
.aside-1 {
background: gold;
}
<div class="wrapper">
<header class="header">Header</header>
<div class="innerwrapper">
<article class="main">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.
Mauris placerat eleifend leo.</p>
</article>
<aside class="aside aside-1">Aside 1</aside>
</div>
<footer class="footer">Footer</footer>
</div>