For the following code, I'm trying to make it so that whatever doesn't fully fit inside the magenta square (.body), it will overflow (with scrollbar) and still produce a neat layout.
However, when I try to throw something really large into that box, it just overflow (without scrollbar) and messes up the design. How can i solve this?
* {
box-sizing: border-box;
}
.grid-test {
display: grid;
grid-template-rows: 1fr 9fr;
height: 100%;
width: 100%;
max-height: 100%;
max-width: 100%;
}
.first {
border: 10px solid blue;
}
.second {
border: 10px solid red;
}
.wrapper {
display: grid;
grid-template-rows: 1fr 9fr;
height: 100%;
border: 10px solid orange;
max-height: 100%;
max-width: 100%;
}
.sub-header {
border: 10px solid lightblue;
}
.body {
// background-color: magenta;
border: 10px solid magenta;
overflow: hidden;
max-height: 100%;
max-width: 100%;
}
.canvas {
//width: 2000px;
//height: 1500px;
background-color: purple;
overflow: auto;
}
<div style="height: 100vh; width: 100vw; position: fixed; left: 0; top: 0; max-width: 100vw">
<div class="grid-test">
<div class="first">
</div>
<div
class="second"
>
<div
class="wrapper"
>
<div class="sub-header"></div>
<div class="body">
<div class="canvas"></div>
</div>
</div>
</div>
</div>
</div>
After placing a large element into it
* {
box-sizing: border-box;
}
.grid-test {
display: grid;
grid-template-rows: 1fr 9fr;
height: 100%;
width: 100%;
max-height: 100%;
max-width: 100%;
}
.first {
border: 10px solid blue;
}
.second {
border: 10px solid red;
}
.wrapper {
display: grid;
grid-template-rows: 1fr 9fr;
height: 100%;
border: 10px solid orange;
max-height: 100%;
max-width: 100%;
}
.sub-header {
border: 10px solid lightblue;
}
.body {
// background-color: magenta;
border: 10px solid magenta;
overflow: hidden;
max-height: 100%;
max-width: 100%;
}
.canvas {
width: 2000px;
height: 1500px;
background-color: purple;
overflow: auto;
}
<div style="height: 100vh; width: 100vw; position: fixed; left: 0; top: 0; max-width: 100vw">
<div class="grid-test">
<div class="first">
</div>
<div
class="second"
>
<div
class="wrapper"
>
<div class="sub-header"></div>
<div class="body">
<div class="canvas"></div>
</div>
</div>
</div>
</div>
</div>
I found another answer, although it wasn't related to grid, it helped me do what I wanted to achieve
nested flexbox height vs max-height
Related
I have 2 parent containers in my code below. The first one is just for reference for what I want my second container to look like. The difference between the two is the first one I used absolute positioning and flex display but the second one is grid display. What I'm stuck on is understanding how to center class .item1 and position class .item2 all the way to the right just how it's like on the first parent container i.e class .topAdCon. My specific questions are 1) how to center .item1
2) how to set .item2's position all the way to the right (right: 0%)
3) on the first parent container I just set top: 0% to align it all the way to the top because it has absolute positioning how can I set the positioning of the second parent container where ever I want currently I'm using margin-top for top positioning is that the way to go or what is the right way?
4) Lastly how do I set the height for the second container because height isn't responding as it does on the first container?
Note: I commented out things I tried in order to achieve these things but they aren't working.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.topAdCon {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 0%;
width: 100%;
height: 18%;
background-color: pink;
}
.topAdCon .adCon {
width: 40%;
height: 100%;
}
.topAdCon .adCon img {
width: 100%;
height: 100%;
}
.topAdCon .sideInfo {
display: flex;
text-align: center;
width: 17%;
height: 100%;
position: absolute;
right: 0%;
border: 1.5px solid #000000;
}
.topAdCon .sideInfo p {
font-size: 0.9vw;
margin: auto;
}
.wrapper {
display: grid;
align-items: center;
justify-content: center;
/*position: relative;
top: 20%;*/
margin-top: 20%;
grid-template-columns: 40% 17%;
width: 100%;
height: 18%;
/*height not responding*/
background-color: gold;
}
.item1 {
/*align-self: center;*/
width: 100%;
height: 100%;
}
.item1 img {
width: 100%;
height: 100%;
}
.item2 {
display: flex;
text-align: center;
/*align-self: flex-end*/
width: 100%;
height: 100%;
border: 1.5px solid #000000;
}
.item2 p {
font-size: 1.5vw;
margin: auto;
}
<div class="topAdCon">
<div class="adCon">
<img src="https://images.pexels.com/photos/356830/pexels-photo-356830.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2" />
</div>
<div class="sideInfo">
<p>this is test statement 1</p>
</div>
</div>
<div class="wrapper">
<div class="item1">
<img src="https://images.pexels.com/photos/356830/pexels-photo-356830.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2" />
</div>
<div class="item2">
<p>this is test statement 2</p>
</div>
</div>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.topAdCon {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 0%;
width: 100%;
height: 18%;
background-color: pink;
}
.topAdCon .adCon {
width: 40%;
height: 100%;
}
.topAdCon .adCon img {
width: 100%;
height: 100%;
}
.topAdCon .sideInfo {
display: flex;
text-align: center;
width: 17%;
height: 100%;
position: absolute;
right: 0%;
border: 1.5px solid #000000;
}
.topAdCon .sideInfo p {
font-size: 0.9vw;
margin: auto;
}
.wrapper {
display: grid;
margin-top: 20%;
grid-template-columns: 30% 40% 12% 18%;
grid-template-areas: 'item item1 item2 item3';
width: 100%;
height: 18vh;
background-color: gold;
}
.item1 {
width: 100%;
height: inherit;
}
.item1 img {
width: 100%;
height: 100%;
}
.item3 {
display: flex;
text-align: center;
justify-content: end;
width: 100%;
height: inherit;
border: 1.5px solid #000000;
}
.item3 p {
font-size: 1.5vw;
margin: auto;
}
<div class="topAdCon">
<div class="adCon">
<img src="https://images.pexels.com/photos/356830/pexels-photo-356830.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2" />
</div>
<div class="sideInfo">
<p>this is test statement 1</p>
</div>
</div>
<div class="wrapper">
<div class="item"></div>
<div class="item1">
<img src="https://images.pexels.com/photos/356830/pexels-photo-356830.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2" />
</div>
<div class="item2"></div>
<div class="item3">
<p>this is test statement 2</p>
</div>
</div>
I have the following layout (see snippet below).
This is the expected behavior.
The problem is:
Once the extra-large-content is simulated (by removing the comment on the extra-large-content CSS rule), it breaks the layout.
I would like the extra-large-content to scroll horizontally while staying inside column-3.
Is this even possible?
(the code is also available here https://codepen.io/Ploddy/pen/NWXOgMG?editors=1100)
body {
height: 1920px;
margin: 0;
}
.container {
display: flex;
border: 1px solid #ccc;
margin: 1rem;
}
.container > * {
border: 1px solid #ccc;
position: sticky;
top: 0;
align-self: flex-start;
flex-grow: 1;
margin: 1rem;
}
#column-3 {
height: 300px;
}
#extra-large-content {
background-color: lightgreen;
/*width: 3000px;*/
}
<div class="container">
<div>
column-1
</div>
<div class="container">
<div>
column-2
</div>
<div id="column-3">
column-3
<div id="extra-large-content">
extra-large content
</div>
</div>
</div>
</div>
This should work nicely for you. Essentially, I just specified width's on the .container elements. In theory, you could put overflow-x: scroll; on the .container, however, this would break your sticky positioning.
Edit ~ OP wants the extra-large content to scroll horizontally, not the entire column-3.
Set overflow-x: scroll; on the new parent wrapper of the div that has the 3000px static width.
body {
height: 1920px;
margin: 0;
}
.container:first-child {
max-width: 100%;
}
.container:first-child > div:first-child {
width: 40%;
}
.container:nth-child(2) {
width: 60%;
}
.container:nth-child(2) > div:first-child {
margin: 1em 0em 1em 1em;
}
.container {
display: flex;
border: 1px solid #ccc;
margin: 1rem;
}
.container>* {
border: 1px solid #ccc;
position: sticky;
top: 0;
align-self: flex-start;
flex-grow: 1;
margin: 1rem;
}
.wrapper {
display: flex;
flex-direction: column;
width: 40%;
}
#column-3 {
background-color: salmon;
}
#extra-large-content {
height: 300px;
width: 3000px;
background-color: lightgreen;
}
.xl-content-wrapper {
overflow-x: scroll;
}
<div class="container">
<div>column-1</div>
<div class="container">
<div>column-2</div>
<div class="wrapper">
<div id="column-3">column-3</div>
<div class="xl-content-wrapper">
<div id="extra-large-content">extra-large content</div>
</div>
</div>
</div>
</div>
The issue comes from using flexbox.
Switching to grid fixes the problem.
body {
height: 1920px;
margin: 0;
}
#primary-container {
position: relative;
display: flex;
margin: 1rem;
}
#secondary-container {
position: relative;
display: grid;
grid-template-columns: max-content 1fr;
align-items: start;
}
#column-3 {
display: grid;
grid-auto-rows: min-content;
height: 200px;
}
#content-wrapper {
overflow: auto;
}
#extra-large-content {
width: 3000px;
background-color: lightgreen;
}
.sticky {
position: sticky;
top: 0;
align-self: flex-start;
}
.border {
border: 1px solid #ccc;
}
<div id="primary-container" class="border">
<div class="sticky">
column1
</div>
<div id="secondary-container" class="border">
<div class="sticky">
column2
</div>
<div id="column-3" class="sticky border">
column3
<div id="content-wrapper">
<div id="extra-large-content">
extra-large content
</div>
</div>
...
</div>
</div>
</div>
I am trying to create a modal that has a footer and an header. The content has two columns: LeftSection and RightSection. I want to have the second column fill the height of the content depending on what the first columns height is (which can differ based on content). From the snippet, this means to have the black div go down as much as the red one does.
.Container {
margin: auto auto;
width: 80vw;
height: 250px;
background-color: #8080801a;
flex: 1;
display: flex;
flex-direction: column;
}
.Header {
height: 50px;
width: 100%;
background-color: #61dafb;
}
.FlexContainer {
flex: 1;
display: flex;
overflow: auto;
}
.LeftSection {
width: 200px;
height: 400px;
background: red;
}
.RightSection {
width: 100%;
background-color: black;
}
.Footer {
height: 50px;
background-color: blue;
width: 100%;
}
<div class="Container">
<div class="Header"></div>
<div class="FlexContainer">
<div class="LeftSection" ></div>
<div class='RightSection' ></div>
</div>
<div class='Footer' />
</div>
Do you want this?
.Container {
margin: auto auto;
width: 80vw;
height: 250px;
background-color: #8080801a;
flex: 1;
display: flex;
flex-direction: column;
}
.Header {
height: 50px;
width: 100%;
background-color: #61dafb;
}
.FlexContainer {
flex: 1;
display: flex;
overflow: auto;
}
.LeftSection {
width: 200px;
height: 400px;
background: red;
position: sticky;
top: 0;
}
.RightSection {
width: 100%;
background-color: black;
position: sticky;
top: 0;
}
.Footer {
height: 50px;
background-color: blue;
width: 100%;
}
<div class="Container">
<div class="Header"></div>
<div class="FlexContainer">
<div class="LeftSection" ></div>
<div class='RightSection' ></div>
</div>
<div class='Footer' />
</div>
I'm trying to create the following layout using only regular CSS display properties (block, inline..) not using flex or grid.
The top thing(bandeau) should have a height of 100px and horizontal margins that are 50px.
Both the left and right columns should have a width of 100px.
The footer thingy(pied) should have a height of 80px and horizontal margins of 75px.
body {
margin: 0;
padding: 0;
background: black;
min-height: 100%;
}
.bandeau {
height: 100px;
background: white;
margin: 0 50px;
}
.menuGauche {
width: 50px;
background: lightblue;
height: calc(100% - 80px);
margin: 0 0 80px 0;
position: absolute;
}
.ecran {
background: lightgreen;
width: calc(100% - 100px);
height: calc(100% - 80px);
position: absolute;
margin: 0 50px;
}
.menuDroite {
width: 50px;
background: lightblue;
height: calc(100% - 80px);
margin: 0 0 80px 0;
position: absolute;
left: calc(100% - 50px);
}
.pied {
height: 80px;
background: white;
margin: 0 75px;
width: 100%;
position: absolute;
bottom: 0;
}
<div class="bandeau"></div>
<div class="menuGauche"></div>
<div class="ecran"></div>
<div class="menuDroite"></div>
<div class="pied"></div>
When I am doing this kind of layout, I try to group them horizontally, so the two columns will be wrapped in another div. similar to this:
<!DOCTYPE html>
<html>
<head>
<style>
.main {
background-color: black;
}
.top {
margin: 0 50px;
height: 100px;
background-color: white;
}
.mid {
height: 500px;
background-color: green;
}
.left-col,
.right-col {
height: 100%;
width: 100px;
background-color: blue;
}
.left-col {
float: left;
}
.right-col {
float: right;
}
.bottom {
margin: 0 75px;
height: 80px;
background-color: white;
}
</style>
</head>
<body>
<div class="main">
<div class="top"></div>
<div class="mid">
<div class="left-col"> </div>
<div class="right-col"> </div>
</div>
<div class="bottom"> </div>
</div>
</body>
</html>
I've used float and assume a height for the middle section as it was not specified. Here is a plunk. Hope this helps!
As a beginner, you should avoid using absolute positionning and learn display , then float.
Nowdays display flex makes it easier.
You may also use tags which can be meaningfull for the contents they hold.
Here an example via flex:
html {
height: 100%;
}
body {
margin: 0;
padding: 0;
background: black;
min-height: 100%;
display: flex;
flex-direction: column;
}
main {
flex: 1;
display: flex;
}
.bandeau {
height: 100px;
background: white;
margin: 0 50px;
}
.menuGauche {
width: 50px;
background: lightblue;
}
.ecran {
background: lightgreen;
flex: 1;
}
.menuDroite {
width: 50px;
background: lightblue;
}
.pied {
height: 80px;
background: white;
margin: 0 75px;
}
<header class="bandeau"></header>
<main>
<div class="menuGauche"></div>
<div class="ecran">Play the snippet full page or play with:https://codepen.io/anon/pen/rJMrgz.</div>
<div class="menuDroite"></div>
</main>
<footer class="pied"></footer>
Here is a tutorial (among others) to start with : https://css-tricks.com/snippets/css/a-guide-to-flexbox/
( 101 advises : for french readers https://www.alsacreations.com/article/lire/53-guide-de-survie-du-positionnement-css.html )
You can use the display:table on some elements to achieve the result. so wrap your main content then display it as table.
html,
body {
height: 100%;
}
body{
margin: 0;
padding: 0;
background: black;
}
.bandeau{
height: 100px;
background: white;
margin: 0 50px;
}
.content-wrapper {
display: table;
height: calc(100% - 180px);
width: 100%;
}
.content-wrapper > div{
display:table-cell;
}
.menuGauche,
.menuDroite{
width: 100px;
background: lightblue;
}
.ecran{
background: lightgreen;
}
.pied{
height: 80px;
background: white;
margin: 0 75px;
}
<body>
<div class="bandeau"></div>
<div class="content-wrapper">
<div class="menuGauche"></div>
<div class="ecran"></div>
<div class="menuDroite"></div>
</div>
<div class="pied"></div>
</body>
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>