I have a problem in my project, where the size of the div varies, which shouldn't happen. I#ve put an example which shows it.
html, body, .grid-container { height: 100%; margin: 0; }
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
gap: 1px 1px;
}
._ {
display: grid;
grid-template-columns: 120px 120px;
grid-template-rows: 1fr 1fr;
gap: 1px 1px;
grid-area: 1 / 2 / 4 / 4;
}
.A { grid-area: 1 / 1 / 3 / 2;
align-self: flex-end;
border: 1px solid red;
position: relative;
}
.B { grid-area: 1 / 2 / 3 / 3;
border: 1px solid red;
position: relative;
}
.grid-container *:after {
content:attr(class);
position: absolute;
top: 0;
left: 0;
}
.circle {
width: 115px;
height: 115px;
background: red;
border-radius: 100px;
}
<div class="grid-container">
<div class="_">
<div class="A">
<div class="circle"></div>
</div>
<div class="B"></div>
</div>
</div>
If you do not pu the circle div in, A & B are the same height. But as soon as you put it into the A div, the size changes to perfectly equal the one of the circle, which I totally do not want to happen.
Since I'm building a Connect 4 game and I use the Border for the "GameField" it has to stay the same size.
I've already tried adding the parameter height: 690; to the A div (every circle is 115px->6 circles = 690) but then the align end did not work anymore. I also change between align-self: end; and align-self: flex-end; but that didn't change anything...
If what Im searching for isn't possible, I would love to know how else I can achieve a outline of a specificities set of cells in a css grid.
Thank you so much in advance for helping (or at least trying) me. <3
I didn't understand literally, but you can try and use this instead of above.
I think you can add the features you want (such as height) to this code I wrote.
.grid-container {
display: inline-table;
}
._ {
display: grid;
grid-template-columns: 120px 120px;
grid-template-rows: 1fr 1fr;
gap: 1px 1px;
grid-area: 1 / 2 / 4 / 4;
}
.grid-container *:not(.circle):after {
content: attr(class);
position: absolute;
top: 0;
left: 0;
}
._ > div {
border: 1px solid red;
align-self: end;
position: relative;
display: inline-flex;
}
.circle {
width: 115px;
height: 115px;
background: red;
border-radius: 100px;
align-self: end;
}
.B {
height: 20px;
}
.C {
height: 30px;
}
.D {
height: 40px;
}
<div class="grid-container">
<div class="_">
<div class="A">
<div class="circle"></div>
</div>
<div class="B"></div>
<div class="C"></div><div class="D"></div></div>
</div>
You don't have to use css for .A and .B, you're able to use like code above. Also I added two div to better understand
If I misunderstood, send me message back, I'll check again
Related
I got 2 columns grid with following layout:
My issue is that when I use images inside the right column (1 image inside each box)..Images overflow and whole grid kind of acts weird.
It looks something like this:
Codepen Link: https://codepen.io/kazmi066/pen/MWXGgaL?editors=1100
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.grid {
background: green;
width: 100%;
max-height: 70vh;
display: grid;
gap: 20px;
grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
}
.col1 {
height: 100%;
background: red;
}
.col2 {
height: 100%;
background: orange;
}
.box1 {
width: 100%;
height: 50%;
border: 1px solid black;
}
.box2 {
width: 100%;
height: 50%;
border: 1px solid blue;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="grid">
<div class="col1"></div>
<div class="col2">
<div class="box1"><img src="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8N3x8fGVufDB8fHx8&w=1000&q=80" alt="property"/></div>
<div class="box2"><img src="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8N3x8fGVufDB8fHx8&w=1000&q=80" alt="property" /></div>
</div>
</div>
I want the images to adjust inside the boxes perfectly without the need of custom height and width so that any size of image can work in this scenario.
fit would be object-fit: contain; for the image not cover.
but if the ratio of the image is not the ratio of the box, you'll have blank
you can put the image in background of box1, box2... with a background size cover. It will cover entirely and clipped the overflow. If box ratio "totally" different of the image, lot of image can be clipped, but it's not so often.
I've found a way, only CSS, nothing is changed in your HTML
2 points:
1- it's using clip-path
2- image fill box space, but are clipped otherwise blank space
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.grid {
background: green;
width: 100%;
max-height: 70vh;
display: grid;
gap: 2vh;
grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
grid-template-rows: 100%;
}
.col1 {
background: red;
}
.col2 {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 34vh 34vh;
background: orange;
justify-content: center;
}
.box1 {
width: 100%;
border: 1px solid black;
clip-path: inset(0);
}
.box2 {
width: 100%;
border: 1px solid blue;
clip-path: inset(0);
}
img {
width: 100%;
object-fit: contain;
}
<div class="grid">
<div class="col1"></div>
<div class="col2">
<div class="box1"><img src="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8N3x8fGVufDB8fHx8&w=1000&q=80" alt="property" /></div>
<div class="box2"><img src="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8N3x8fGVufDB8fHx8&w=1000&q=80" alt="property" /></div>
</div>
</div>
based on your grid max-height in vh, I defined all others same kind of values in vh. Lot more consistent and avoid some little strange pixels or lines here or there depending of window size.
I put a nested grid inside col2 where box1 box2 go. box have a clip-path with inset 0, meaning clipping everything out.
The solution that worked for me:
I used grid-auto-rows to create 2 rows with specific height.
Then added span to adjust the column accordingly to cover both rows.
.grid {
width: 100%;
border: 1px solid red;
display: grid;
gap: 14px;
grid-template-columns: repeat(12, 1fr);
grid-auto-rows: 280px 280px;
}
.col1 {
height: 100%;
grid-column: 1/8;
grid-row: span 2;
background: red;
}
.col2 {
grid-column: 8/13;
height: 100%;
background: orange;
}
.col2 img:first-child {
margin-bottom: 11px;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
#media (max-width: 768px) {
.grid {
grid-auto-rows: 220px 120px;
}
.col1 {
grid-column: 1/13;
}
.col2 {
grid-column: 1/13;
grid-row: span 2;
}
}
<div class="grid">
<div class="col1">
<img src="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8N3x8fGVufDB8fHx8&w=1000&q=80" alt="property"/>
</div>
<div class="col2">
<img src="https://images.unsplash.com/photo-1564013799919-ab600027ffc6?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8YmVhdXRpZnVsJTIwaG91c2V8ZW58MHx8MHx8&w=1000&q=80" alt="property"/>
<img src="https://images.pexels.com/photos/186077/pexels-photo-186077.jpeg?cs=srgb&dl=pexels-binyamin-mellish-186077.jpg&fm=jpg" alt="property" />
</div>
</div>
Final output now:
Solution-2: Found Another better solution with Grid-template-areas I guess which looks more cleaner:
.grid {
width: 100%;
border: 1px solid red;
display: grid;
gap: 14px;
grid-template-areas:
"mainImage mainImage otherImage1"
"mainImage mainImage otherImage1"
"mainImage mainImage otherImage2"
"mainImage mainImage otherImage2"
}
.mainImage {
grid-area: mainImage;
}
.otherImage1 {
grid-area: otherImage1;
}
.otherImage2 {
grid-area: otherImage2;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="grid">
<img src="https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxleHBsb3JlLWZlZWR8N3x8fGVufDB8fHx8&w=1000&q=80" alt="property" class="mainImage" />
<img src="https://images.unsplash.com/photo-1564013799919-ab600027ffc6?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8YmVhdXRpZnVsJTIwaG91c2V8ZW58MHx8MHx8&w=1000&q=80" alt="property" class="otherImage1" /> <img src="https://images.pexels.com/photos/186077/pexels-photo-186077.jpeg?cs=srgb&dl=pexels-binyamin-mellish-186077.jpg&fm=jpg" alt="property" class="otherImage2" />
</div>
<h1>something else here</h1>
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>
I have a component with an OK/Cancel button, where I want the buttons both the same width regardless of the text size (eg different cultures)
So, a simplified mockup which is close to what I have is...
<div id="container">
<div class="button">OK</div>
<div class="button">Cancel</div>
</div>
#container {
background: green;
right: 0;
position: absolute;
display: grid;
grid-template-columns: 1fr minmax(0, 1fr)
}
.button {
text-align: center;
padding: 5px;
min-width: 40px;
width: auto;
margin: 5px;
background: yellow;
}
Can also see at this codepen
So, we can see if the OK text is long, then the Cancel button also grows to the same width
However, the component I am using (3rd party) also used the OK for just close
eg
<div id="container">
<div class="button">Close</div>
</div>
and now I have an unwanted gap on the right hand side
I can target the component classes, but not the structure.
So, is there any way via just CSS I can have this grid to act like a grid-template-columns: 1fr 0 if the second div is not there?
You may check if the span is the :only-child and make it span both columns
#container {
background: green;
right: 0;
position: absolute;
display: grid;
grid-template-columns: 1fr minmax(0, 1fr)
}
.button {
text-align: center;
padding: 5px;
min-width: 40px;
width: auto;
margin: 5px;
background: yellow;
}
.button:only-child {
grid-column: span 2;
}
<p>Test :only-child</p>
<div id="container">
<div class="button">Close</div>
</div>
https://developer.mozilla.org/en-US/docs/Web/CSS/:only-child
You can use the 'auto' value like this:
#container {
background: green;
right: 0;
position: absolute;
display: grid;
grid-template-columns: auto minmax(0, 1fr)
}
you can find more info here: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-columns
I'm trying to build a grid where the first-row would have 400px and the second would be something like fit-content, since my first column is dynamically created and it can have an undertemined height.
The idea is, I have three blocks, 1 is dynamic, 2 and 3 are static, where 3 should always be below 2:
However I couldn't find a way to make the first row with a fixed value (400px) and the second auto to fit whatever height the block 1 have. If I set the first one auto and the second row 400px I get this:
.container {
display: grid;
grid-template-columns: auto auto;
grid-template-rows: auto 400px;
width: 400px;
}
.block-1 {
height: 300px;
width: 200px;
background: red;
}
.block-2 {
height: 100px;
width: 150px;
background: blue;
grid-column: 3/5;
}
.block-3 {
height: 100px;
width: 150px;
background: green;
grid-column: 3/5;
grid-row-start: 2;
}
<div class="container">
<div class="block-1"></div>
<div class="block-2"></div>
<div class="block-3"></div>
</div>
Is there a way to do that with grid? I could change the structure of the grid, the way I bult is not a must.
P.S. Changing the HTML is not an option.
Is this what you want?
.container {
display: grid;
grid-template-columns: auto auto;
grid-template-rows: auto 400px;
width: 400px;
}
.block-1 {
height: 300px;
width: 200px;
background: red;
grid-row: 1 / 3;
}
.block-2 {
height: 100px;
width: 150px;
background: blue;
}
.block-3 {
height: 100px;
width: 150px;
background: green;
grid-column: 2/3;
grid-row-start: 2;
}
<div class="container">
<div class="block-1"></div>
<div class="block-2"></div>
<div class="block-3"></div>
</div>
This seems like it will do the trick. I've used named grid-template-areas as shorthand.
.container {
display: grid;
grid-auto-columns: 1fr;
grid-auto-rows: 1fr;
grid-template-columns: 1fr 1fr;
grid-template-rows: min-content;
gap: 0px 0px;
grid-template-areas:
"block-1 block-2"
"block-1 block-3";
width: 400px;
}
.block-1 { grid-area: block-1; background-color: red; height: 300px}
.block-2 { grid-area: block-2; background-color: blue; height: 100px }
.block-3 { grid-area: block-3; background-color: green; height: 100px; }
<div class="container">
<div class="block-1"></div>
<div class="block-2"></div>
<div class="block-3"></div>
</div>
Hopefully that works out for you, but if you need to make any adjustments then I always find using a site with a visual UI for the grid really helps, e.g. https://grid.layoutit.com/
I have a page designed like this:
main {
display: flex;
}
div {
width: 50px;
height: 50px;
margin: 2px;
text-align: center;
}
.div1 {
background-color: green;
}
.div2 {
background-color: red;
}
<main>
<section>
<div class="div1">A</div>
<div class="div1">B</div>
<div class="div1">C</div>
</section>
<section>
<div class="div2">D</div>
<div class="div2">E</div>
<div class="div2">F</div>
</section>
</main>
I am applying responsiveness. I would like to know if it is possible to use only css to organize the divs this:
The only way I see to achieve the layout with a <section> tag present separating each div1 and div2 would be to use positioning each child elements left and top positions relative to the parent. It is very static and likely has a high potential of breaking with content and scrolling, etc...
Not recommended... see the hidden snippit below to see that working
.main section {
position: relative;
}
.one {
position: absolute;
left: 0;
top: 0;
}
.four {
position: absolute;
left: 55px;
top: 0;
}
.two {
position: absolute;
left: 0;
top: 55px;
}
.three {
position: absolute;
left: 55px;
top: 55px;
}
.five {
position: absolute;
left: 0;
top: 110px;
width: 210%;
overflow: auto;
}
.six {
position: absolute;
left: 0;
top: 165px;
width: 210%;
overflow: auto;
}
div {
width: 50px;
height: 50px;
margin: 2px;
text-align: center;
}
.div1 {
background-color: green;
}
.div2 {
background-color: red;
}
<div class="main">
<section>
<div class="div1 one">1</div>
<div class="div1 two">2</div>
<div class="div1 three">3</div>
</section>
<section>
<div class="div2 four">4</div>
<div class="div2 five">5</div>
<div class="div2 six">6</div>
</section>
</div>
A more cohesive approach would be to get rid of the <section> tags and use a grid layout...
You still have the classes div1 and div2 for alternate styling. Using the grid layout you can create a grid-template-area using the grid-area on individual class names for each element.
While you still have your child elements laid out incrementally one, two, three, four, etc... You can move a child element anywhere in the grid pattern using the grid-template-area calling on the elements grid-area value.
In the following example, each div has a class representing its position in the original layout, one, two, three, etc...
Note the column and row fr units... very literal in its approach. Visualize two columns each separated equally per column, then four rows, each separated equally per row, then we add the elements with the grid-template-area...
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
grid-template-area:
"one four"
"two three"
"five five"
"six six";
}
html {
--width: 100%;
--height: 100%;
}
#main {
display: flex;
justify-content: center;
}
div {
display: flex;
align-items: center;
justify-content: center;
}
.grid-container {
height: 400px;
width: 200px;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
grid-gap: 2px 2px;
grid-template-areas: "one four" "two three" "five five" "six six";
}
.one {
grid-area: one;
width: var(--width);
height: var(--height);
}
.two {
grid-area: two;
width: var(--width);
height: var(--height);
}
.three {
grid-area: three;
width: var(--width);
height: var(--height);
}
.four {
grid-area: four;
width: var(--width);
height: var(--height);
}
.five {
grid-area: five;
width: var(--width);
height: var(--height);
}
.six {
grid-area: six;
width: var(--width);
height: var(--height);
}
.div1 {
background-color: green;
}
.div2 {
background-color: red;
}
<div id="main">
<div class="grid-container">
<div class="div1 one box">A</div>
<div class="div1 two box">B</div>
<div class="div1 three box">C</div>
<div class="div2 four box">D</div>
<div class="div2 five box">E</div>
<div class="div2 six box">F</div>
</div>
</div>
yes you could by using orders like this .div1 {order: __}