Why is text content making a column wider? - html

I am setting up a video player in CSS Grid and for the life of me can't figure out why the width of the right most grid column (one with three multi-colored rows) increases when I add text content.
I have tried setting the overflow property to hidden but the width still changes.
If I remove the following code from the html markup, the column goes back to the desired width:
<div id="title">This Text</div>
<div id="location">is making this 3 row div</div>
<div id="date">wider for some reason</div>
I want to add text to the column without the width changing. Probably an easy fix. Thanks for any help!
https://codepen.io/Wcomp/pen/LKMrRK?editors=1100
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
*:focus {
outline: 0;
outline: none;
user-select: none;
}
* {
margin: 0;
padding: 0;
user-select: none;
}
body {
display: block;
overflow: hidden;
height: 100vh;
background-color: darkblue;
}
.middle {
display: grid;
grid-template-areas: 'item1 item1 item1 item1 item2';
grid-column-gap: 3vh;
position: absolute;
width: 100%;
top: 23.3333666667%;
height: 53.3332667%;
border-left: 3vh solid transparent;
border-right: 3vh solid transparent;
}
.vid_player {
display: grid;
background-color: green;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr;
grid-column-gap: 3vh;
left: 0%;
height: 100%;
width: 100%;
grid-area: item1;
}
.item {
background-color: white;
height: 100%;
width: 100%;
border-radius: 10px;
}
.container {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr 1fr;
height: 100%;
width: 100%;
background-color: grey;
grid-area: item2;
}
#one {
background-color: aqua;
}
#two {
background-color: red;
}
#three {
background-color: yellow;
}
#title {
color: white;
font-family: arial;
font-size: 50px;
text-align: center;
}
#location {
color: white;
font-family: arial;
font-size: 30px;
text-align: center;
}
#date {
color: white;
font-family: arial;
font-size: 30px;
text-align: center;
}
<div class="middle">
<div class="vid_player">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="container">
<div id="one">
<div id="title">This Text</div>
<div id="location">is making this 3 row div</div>
<div id="date">wider for some reason</div>
</div>
<div id="two"></div>
<div id="three"></div>
</div>
</div>

Does it give the expected result if you add grid-template-columns: 1fr 1fr 1fr 1fr 1fr; to your .middle class?

By making all of the columns 1fr wide, you are telling the browser to make all of them take up the same amount of remaining space left on the page. That is, the space left after your content-filled columns have taken up what they need.
If you want the columns to take up the same amount of space no matter what try giving them widths in vw units to make their width a fraction of the screen, or percents to make their width a fraction of their parent's width.

Here's how you define your primary grid container:
.middle {
display: grid;
grid-template-areas: 'item1 item1 item1 item1 item2';
}
You've created a grid with five columns.
However, you haven't specified a width for these columns. In other words, you haven't defined any values for grid-template-columns.
As a result, each column defaults to the width of its content.
Because the column in question has text content, unlike the other columns, it is wider.
Set a rule for equal widths. Add this to your code:
.middle {
display: grid;
grid-template-areas: 'item1 item1 item1 item1 item2';
grid-template-columns: repeat(5, 1fr); /* new */
}
revised codepen
.middle {
display: grid;
grid-template-areas: "item1 item1 item1 item1 item2";
grid-template-columns: repeat(5, 1fr); /* new */
grid-column-gap: 3vh;
position: absolute;
width: 100%;
top: 23.3333666667%;
height: 53.3332667%;
border-left: 3vh solid transparent;
border-right: 3vh solid transparent;
}
.vid_player {
display: grid;
background-color: green;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr;
grid-column-gap: 3vh;
left: 0%;
height: 100%;
width: 100%;
grid-area: item1;
}
.item {
background-color: white;
height: 100%;
width: 100%;
border-radius: 10px;
}
.container {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr 1fr;
height: 100%;
width: 100%;
background-color: grey;
grid-area: item2;
}
#one {
background-color: aqua;
}
#two {
background-color: red;
}
#three {
background-color: yellow;
}
#title {
color: white;
font-family: arial;
font-size: 50px;
text-align: center;
}
#location {
color: white;
font-family: arial;
font-size: 30px;
text-align: center;
}
#date {
color: white;
font-family: arial;
font-size: 30px;
text-align: center;
}
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
*:focus {
outline: 0;
outline: none;
user-select: none;
}
* {
margin: 0;
padding: 0;
user-select: none;
}
body {
display: block;
overflow: hidden;
height: 100vh;
background-color: darkblue;
}
<div class="middle">
<div class="vid_player">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="container">
<div id="one">
<div id="title">This Text</div>
<div id="location">is making this 3 row div</div>
<div id="date">wider for some reason</div>
</div>
<div id="two"></div>
<div id="three"></div>
</div>
</div>

Related

how to use css grid to display components at particular area

here's my html code
<div>
<div id="navbar" class="box">Navbar</div>
<div id="sidenav " class="box">Side Navbar</div>
<div id="main " class="box">Main</div>
<div id="footer " class="box">Footer</div>
</div>
and here's my scss code
div{
display: grid;
width:100%;
height: 100%;
grid-template-columns: 25% 75% 25%;
grid-gap: 15px;
grid-template-rows:25% 50% 25% ;
// grid-gap: 15px;
grid-template-areas:
"hd hd hd "
"sd ma ma "
"ft ft ft ";
.box{
display: flex;
// text-align: center;
border: 3px solid red;
/* width:150px;
height: 150px; */
margin: auto;
align-items: center;
justify-content: center;
}
#navbar{
grid-area: hd;
}
#sidenav{
grid-area: sd;
}
#main{
grid-area: ma;
}
#footer{
grid-area: ft;
}
}
the problem is the footer div doesn't display in the bottom here's a screenshot
what i want is to make the footer display at the bottom so what seems to be the problem here
There are some issues that I found in your code which makes the layout little wonky.
grid-template-columns: 25% 75% 25%;
The column total is more than 100%, so it will not work perfectly.
I would highly recommend you to use a CSS grid generator online like https://grid.layoutit.com/
For your layout, I would also not recommend structure 3x3 (columns and rows) - As from the image you shared above it looks like the following
1 row - For "Navbar" (this doesnt need any sub columns)
1 row - For Content -> this has 2 columns 1 for "SideNav" and 1 for "Main"
1 row - For "Footer" (again you dont need sub columns)
Based on this your HTML structure will end up looking like
<div class="container">
<div class="navbar">Navbar</div>
<div class="Content">
<div class="SideNav">Side Nav</div>
<div class="Main">Main</div>
</div>
<div class="Footer">Footer</div>
</div>
And your CSS will look like this
body{
padding: 0;
margin: 0;
}
.container {
width: 100vw;
height: 100vh;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 25% 50% 25%;
gap: 0px 0px;
grid-template-areas:
"navbar"
"Content"
"Footer";
}
.navbar {
grid-area: navbar;
background-color: #f5f5f5;
padding: 16px;
text-align: center;
}
.Content {
display: grid;
grid-template-columns: 360px 1fr;
grid-template-rows: 1fr;
gap: 0px 0px;
grid-template-areas:
"SideNav Main";
grid-area: Content;
}
.SideNav {
grid-area: SideNav;
background-color: #e5e5e5;
padding: 16px;
}
.Main {
grid-area: Main;
background-color: salmon;
padding: 16px;
}
.Footer {
grid-area: Footer;
background-color: #d5d5d5;
padding: 16px;
text-align: center;
}
Here, if you check the code well, the container has 3 rows (25% - navbar, 50% - content, 25% - footer)
And then content has 2 columns (360px - Sidenav, 1fr - Main)
Hope this helps :)
You can also see the code live on my codepen : https://codepen.io/raunaqpatel/pen/WNyQqmm
Or here:
body{
padding: 0;
margin: 0;
}
.container {
width: 100vw;
height: 100vh;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 25% 50% 25%;
gap: 0px 0px;
grid-template-areas:
"navbar"
"Content"
"Footer";
}
.navbar {
grid-area: navbar;
background-color: #f5f5f5;
padding: 16px;
text-align: center;
}
.Content {
display: grid;
grid-template-columns: 360px 1fr;
grid-template-rows: 1fr;
gap: 0px 0px;
grid-template-areas:
"SideNav Main";
grid-area: Content;
}
.SideNav {
grid-area: SideNav;
background-color: #e5e5e5;
padding: 16px;
}
.Main {
grid-area: Main;
background-color: salmon;
padding: 16px;
}
.Footer {
grid-area: Footer;
background-color: #d5d5d5;
padding: 16px;
text-align: center;
}
<div class="container">
<div class="navbar">Navbar</div>
<div class="Content">
<div class="SideNav">Side Nav</div>
<div class="Main">Main</div>
</div>
<div class="Footer">Footer</div>
</div>

horizontal scroll with 100% width on grid cell

I want to have a css grid, inside each cell of the grid, I want a title with a maximum size of 100% of the width of the cell. If title is too long, i want to scroll.
This is how it looks currently with the correct scrolling behavior but with a fixed width on the long title. Instead of a fixed width, i want a width of 100% of the cell width (so the grey block should be as long as red box)
codePen: https://codepen.io/vincent2303/pen/ExwZEpW
* {
margin: 0;
padding: 0;
}
body {
padding: 50px;
}
h2 {
font-size: 2em;
white-space: nowrap;
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
width: 800px;
gap: 20px;
}
.box {
background-color: #e74c3c;
height: 30vh;
}
.title-wrapper {
background-color: #bdc3c7;
width: 300px;
overflow-x: scroll;
}
<div class=grid>
<div>
<div class="title-wrapper">
<h2>long title, i can scroll---------</h2>
</div>
<div class="box"></div>
</div>
<div>
<h2>Short title</h2>
<div class="box"></div>
</div>
</div>
Does anyone have an idea to do that ?
NOTE: To make the code example simple, the .grid class has a width of 800px but in reality, it's width is defined by its parent on which i can not predict the width (i'm working on a react app and this code will implement a component used in multiple places with different sizes).
If your grid potentially contains overflowing content, you cannot work with 1fr, here's why:
1fr is just short for minmax(auto, 1fr).
minmax(a, b) becomes a (without any minmax) when a >= b is true.
So in your case your grid behaves as if you had defined it as grid-template-columns: auto 1fr;, because auto is larger than 1fr for your first column.
To fix that, you need to tell your grid that it isn't allowed to extend the cells when content becomes too wide.
Use minmax(0, 1fr) instead of 1fr:
* {
margin: 0;
padding: 0;
}
body {
padding: 50px;
}
h2 {
font-size: 2em;
white-space: nowrap;
}
.grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
width: 800px;
gap: 20px;
}
.box {
background-color: #e74c3c;
height: 30vh;
}
h2 {
background-color: #bdc3c7;
overflow-x: scroll;
}
<div class=grid>
<div>
<h2>long title, i can scroll------------------ - - - - ----</h2>
<div class="box"></div>
</div>
<div>
<h2>Short title</h2>
<div class="box"></div>
</div>
</div>
As commented heres a possibility:
* {
margin: 0;
padding: 0;
}
body {
padding: 50px;
}
h2 {
font-size: 2em;
white-space: nowrap;
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
width: 800px;
gap: 20px;
}
.box {
background-color: #e74c3c;
height: 50vh;
max-width: 400px;
}
.title-wrapper {
background-color: #bdc3c7;
width: 100%;
overflow-x: scroll;
}
<div class=grid >
<div>
<div class="box" >
<div class="title-wrapper" >
<h2>long title, i can scroll---------------------------------</h2>
</div>
</div>
</div>
<div>
<div class="box" >
<h2>Short title</h2>
</div>
</div>
</div>
Seems to be hard without JavaScript, Dev his answers works, but it involves a fixed max-width.
I've got a solution with JavaScript that seems to work.
/* Execute when the DOM is loaded, because otherwise the HTML elements might nog be in the DOM. */
window.addEventListener( 'DOMContentLoaded', () => {
generateGridItemsWidthVariable()
} )
/* Execute when the window is resized, because the width of the boxes might change. */
window.addEventListener( 'resize', () => {
generateGridItemsWidthVariable()
} )
/* Generate the variable for the grid items. */
function generateGridItemsWidthVariable() {
/* Select all the grid items and create an array to loop trough. */
let gridItems = Array.from( document.getElementsByClassName( 'grid__item' ) )
/* Loop trough the grid items. */
gridItems.forEach( gridItem => {
/* Reset the grid item width, because otherwise the item won't resize. */
gridItem.style.setProperty( '--grid-item--width', '' )
/* Get the width of the grid item. */
let gridItemWidth = gridItem.clientWidth.toString()
/* Set the width of the grid item as a CSS variable. */
gridItem.style.setProperty( '--grid-item--width', gridItemWidth + 'px' )
} )
}
* {
margin: 0;
padding: 0;
}
body {
padding: 50px;
}
h2 {
font-size: 2em;
white-space: nowrap;
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
width: 100%;
max-width: 800px;
gap: 20px;
}
.grid__item {
--grid-item--width: 10px;
}
.box {
background-color: #e74c3c;
height: 30vh;
}
.title-wrapper {
background-color: #bdc3c7;
width: 100%;
}
.title-wrapper h2 {
max-width: var(--grid-item--width);
overflow-x: scroll;
}
<div class=grid >
<div class="grid__item">
<div class="title-wrapper" >
<h2>long title, i can scroll-----------------------</h2>
</div>
<div class="box" ></div>
</div>
<div class="grid__item">
<h2>Short title</h2>
<div class="box" ></div>
</div>
</div>
Well 1fr resolves to minmax(auto, 1fr) and this means that the minimum width of the grid column is min-content, that is more then 1fr. There is a quick solution to this issue just replacing 1fr by minmax(0px, 1fr), by this, parent's width is devided between 2 columns, and this way you have the scroll bar as you wish.
* {
margin: 0;
padding: 0;
}
body {
padding: 50px;
}
h2 {
font-size: 2em;
white-space: nowrap;
}
.grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 20px;
}
.box {
background-color: #e74c3c;
height: 30vh;
}
h2 {
background-color: #bdc3c7;
overflow-x: auto;
}
<div class=grid>
<div>
<h2>long title, i can scroll----------------------------</h2>
<div class="box"></div>
</div>
<div>
<h2>Short title</h2>
<div class="box"></div>
</div>
</div>

How to use CSS grid to create 3x3 grid but place items in specific grid columns

I'm trying to create a layout that looks like this:
The blue blocks are divs. It's essentially a 3x3 grid but with gaps in the 3rd and 4th grid column.
How can I create a gap within CSS grid to achieve this layout? I've tried it with flexbox, but couldn't achieve the above, so hoping a grid layout is the answer.
Here's my code:
.container{
border: 1px solid;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 0px 0px;
grid-template-areas:
". . ."
". . .";
}
.item{
border: 1px solid lightgrey;
padding: 10px;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
CSS grid allows you to choose which row and column an element will start in (and indeed, though not needed in your case, how many columns/rows it is to span).
This snippet gives the 3rd and 4th children of the wrapper specific grid positions.
.container {
border: 1px solid;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-gap: 10px;
}
.item {
border: 1px solid lightgrey;
padding: 10px;
}
.item:nth-child(3) {
grid-column: 2;
grid-row: 2;
}
.item:nth-child(4) {
grid-column: 3;
grid-row: 2;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
Note: just for a demo it has also introduced a non-zero grid-gap. The grid-area settings have been removed as not needed if the above method is followed.
A simplified version of the CSS grid solution with only the necessary code:
.container{
border: 1px solid;
display: grid;
grid-auto-columns: 1fr;
grid-auto-rows: 1fr;
grid-gap:5px;
}
.item{
border: 1px solid lightgrey;
padding: 10px;
}
.item:nth-child(3) {
grid-column:2;
}
.item:nth-child(4) {
grid-column:3;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
How about padding/margin?
.container {
border: 1px solid #777;
display: inline-grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 0 0;
grid-template-areas:
". . ."
". . .";
}
.item {
border: 1px solid lightgrey;
padding: 2px 0;
width: 55px !important;
height: 50px !important;
margin: 1px !important;
background: #1657c9;
text-align: center;
font-family: Arial, Helvetica, sans-serif;
color: white;
}
.item-text {
position: relative;
top: 38%;
margin: 0;
font-size: normal;
}
.item-3, .item-4 {
position: relative;
left: 100%;
}
<div class="container">
<div class="item item-1"><span class="item-text">1</span></div>
<div class="item item-2"><span class="item-text">2</span></div><br>
<div class="item item-3"><span class="item-text">3</span></div>
<div class="item item-4"><span class="item-text">4</span></div>
</div>
You can try this:
This is HTML:
<div class="parent">
<div class="div1"> </div>
<div class="div2"> </div>
<div class="div3"> </div>
<div class="div4"> </div>
</div>
and CSS
.parent {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(5, 1fr);
grid-column-gap: 0px;
grid-row-gap: 0px;
}
.div1 {
grid-area: 1 / 1 / 2 / 2;
background: blue;
height: 3rem;
margin: 1rem;
}
.div2 {
grid-area: 1 / 2 / 2 / 3;
background: blue;
height: 3rem;
margin: 1rem;
}
.div3 {
grid-area: 2 / 2 / 3 / 3;
background: blue;
height: 3rem;
margin: 1rem;
}
.div4 {
grid-area: 2 / 3 / 3 / 4;
background: blue;
height: 3rem;
margin: 1rem;
}

resize column across multiple rows using html grid layout

I've got a grid layout with 2 columns and 3 rows.
I want to be able to resize the column widths. I know I can use resize: horizontal but that only changes width for one row.
I'm thinking I can't do what I want and I'll need to use nested grids but I'm not sure so I wanted to check.
<!DOCTYPE html>
<html>
<head>
<style>
.container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
gap: 0px 0px;
grid-auto-flow: row;
grid-template-areas:
"logo search"
"nav main"
"log main";
}
.logo {
grid-area: logo;
}
.search {
grid-area: search;
}
.nav {
grid-area: nav;
overflow: auto;
resize: horizontal;
}
.log {
grid-area: log;
overflow: auto;
resize: horizontal;
}
.main {
grid-area: main;
}
html,
body,
.container {
height: 100%;
margin: 0;
}
/* For presentation only, no need to copy the code below */
.container * {
border: 1px solid red;
position: relative;
}
.container *:after {
content: attr(class);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: grid;
align-items: center;
justify-content: center;
}
</style>
</head>
<body>
<div class="container">
<div class="logo"></div>
<div class="search"></div>
<div class="nav">
</div>
<div class="log"></div>
<div class="main"></div>
</div>
</body>
</html>
You can do it with your structure. The trick is to use auto 1fr on the template columns and set the initial width of the resizable element to be equal to 50vw to simulate the 1fr 1fr initially:
PS: I simplified the code by removing the areas but that's not part of the trick, you can keep it
.container {
display: grid;
height: 100vh;
grid-template-columns: auto 1fr;
grid-template-rows: 1fr 1fr 1fr;
}
.log {
overflow: auto;
resize: horizontal;
width:50vw;
}
.main {
grid-row:2/span 2;
grid-column:2;
}
body{
margin: 0;
}
/* For presentation only, no need to copy the code below */
.container * {
border: 1px solid red;
position: relative;
}
.container *:after {
content: attr(class);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: grid;
align-items: center;
justify-content: center;
}
<div class="container">
<div class="logo"></div>
<div class="search"></div>
<div class="nav">
</div>
<div class="log"></div>
<div class="main"></div>
</div>
If you will have content, you can do it like below:
.container {
display: grid;
height: 100vh;
grid-template-columns: auto 1fr;
grid-template-rows: 1fr 1fr 1fr;
}
.log {
overflow: auto;
resize: horizontal;
width:50vw;
}
/* disable the width contribution so only the log will define the width */
.logo,
.nav {
width:0;
min-width:100%;
}
/**/
.main {
grid-row:2/span 2;
grid-column:2;
}
body{
margin: 0;
}
/* For presentation only, no need to copy the code below */
.container * {
border: 1px solid red;
position: relative;
}
<div class="container">
<div class="logo"> Lorem ipsum dolor sit amet, consectetur .</div>
<div class="search"> </div>
<div class="nav">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
<div class="log"> </div>
<div class="main"></div>
</div>

css - nested div in grid does not respect grid sizes

So I'm trying to display cards within a grid. I would like the card size to be based on the grid size and then to overlay text on top of it that correctly matches the width.
Here's my implementation so far but it seems like the div/img no longer respects the grid's sizes
for (let i = 0; i < 15; i++)
{
$("#grid").append(`
<div class="item">
<div>
<img src="http://via.placeholder.com/250x350" />
<div class="text">
sadfsd
</div>
</div>
</div>
`);
}
.flex {
border: 1px solid black;
display: flex;
flex-direction: column;
height: 100vh;
}
.footer {
height: 20%;
}
.upper {
flex: 1;
overflow: auto;
}
#grid {
border: 1px solid black;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
height: 100%;
position: relative;
max-width: 100%;
box-sizing: border-box;
}
.item {
display: inline-block;
text-align: center;
position: relative;
}
.inner {
border: 1px solid red;
max-height: 100%;
max-width: 100%;
}
.text {
position: absolute;
bottom: 10%;
left: 50%;
transform: translateX(-50%);
height: 30%;
border: 1px solid black;
width: 90%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="flex">
<div class='upper'>
<div id="grid">
</div>
</div>
<div class="footer">
footer
</div>
</div>
What I want is it to look something like this (of course with the text matching the width of the image)
for (let i = 0; i < 15; i++)
{
$("#grid").append(`
<div class="item">
<img src="http://via.placeholder.com/150x350" />
<div class="text">
text
</div>
</div>
`);
}
.flex {
border: 1px solid black;
display: flex;
flex-direction: column;
height: 100vh;
}
.footer {
height: 20%;
}
.upper {
flex: 1;
overflow: auto;
}
#grid {
border: 1px solid black;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
height: 100%;
position: relative;
max-width: 100%;
box-sizing: border-box; /* added */
}
.item {
position: relative;
}
.text {
border: 1px solid black;
position: absolute;
bottom: 10%;
left: 50%;
transform: translateX(-50%);
width: 90%;
height: 30%;
}
img {
display: block;
margin: 0 auto;
max-height: 100%;
max-width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<div class="flex">
<div class='upper'>
<div id="grid">
</div>
</div>
<div class="footer">
footer
</div>
</div>