Stop CSS grid contents from expanding to fill cell - html

I'm programming a web application with collapsible sidebar inside a CSS grid. The CSS grid divides the whole UI into sections, and the sidebar panel is a sub-component of one of those sections.
The issue I am running into is that I want the side panel to automatically shrink to the minimum size of it's contents, which it does fine until it's added to a CSS grid cell, at which point it expands to fill the entire cell.
Here is a quick example of the issue:
<style>
#myGrid{
display: grid;
grid-template-areas:
"g1 g2";
}
#panel{
grid-area: g2;
display: inline-block;
background: #FFAAAA;
height: 100%;
width: auto;
min-width: minmax(0, 1fr);
}
#panelContents{
display: flex;
flex-direction: row;
height: 100%;
}
#collapseArrow{
align-self: center;
right: 0;
top: 50%;
}
#block{
grid-area: g1;
width: 200px;
height: 100%;
background: #AAAAFF;
}
</style>
<body>
<div id="myGrid">
<div id="block">
Contents
</div>
<div id="panel">
<div id="panelContents">
<div id="collapseContents">
<div class="item">
Item1
</div>
<div class="item">
Item2
</div>
<div class="item">
Item3
</div>
<div class="item">
Item4
</div>
<div class="item">
Item5
</div>
</div>
<div id="collapseArrow"><</div>
</div>
</div>
</div>
</body>
Any idea how to solve this? I am trying to get the red panel to shrink to fit it's contents. I tried changing the min-width to 0, but that didn't seem to help.
EDIT: This is a more complex UI for an HTML5 game engine. The left grid cell is an asset browser, and the red panel is a simple properties panel for the right editor window (right grid cell), which I'm trying to display only on the left portion of the cell, so the rest of the right cell can be the editor window.

Use the other column to squeeze the panel down to its content width.
#myGrid {
display: grid;
grid-template-columns: 1fr auto; /* 1fr consumes all free space on the row */
grid-template-areas: "g1 g2";
}
#block {
grid-area: g1;
background: #AAAAFF;
}
#panel {
grid-area: g2;
background: #FFAAAA;
}
#panelContents {
display: flex;
}
#collapseArrow {
align-self: center;
}
<div id="myGrid">
<div id="block">
Contents
</div>
<div id="panel">
<div id="panelContents">
<div id="collapseContents">
<div class="item">Item1</div>
<div class="item">Item2</div>
<div class="item">Item3</div>
<div class="item">Item4</div>
<div class="item">Item5</div>
</div>
<div id="collapseArrow"><</div>
</div>
</div>
</div>

Related

Text always in Middle of screen dynamically

I have 2 divs. In the div on the right has a text. This text has to to be allways in the middle of the screen. Also the text is never allowed to leave the box. I want it responsive. So it works on pc / tablet / phone, etc.
Here my jsfiddle:
https://jsfiddle.net/ourn15f8/106/
.screen-1 {
width: 500px;
display: flex;
}
.div-1 {
background-color: green;
width: 100px;
}
.div-2 {
background-color: red;
width: 400px;
text-align: center;
}
Total Width = Screen Width
<br><br>
Situation:
<div class="screen-1">
<div class="div-1">logo</div>
<div class="div-2">text</div>
</div>
Wanted:
<div class="screen-1">
<div class="div-1" style="position: absolute">logo</div>
<div class="div-2" style="width: 500px">text</div>
</div>
<div class="screen-1" style="width: 400px">
<div class="div-1" style="position: absolute">logo</div>
<div class="div-2" style="width: 300px">text</div>
</div>
<div class="screen-1" style="width: 300px">
<div class="div-1" style="position: absolute">logo</div>
<div class="div-2" style="width: 200px">text</div>
</div>
Text in the middle of screen
<br><br>
Also when screen to small, I want this:
<div class="screen-1" style="width: 150px">
<div class="div-1">logo</div>
<div class="div-2" style="width: 50px">text</div>
</div>
"text" is never allowed to leave the div
<br><br>
Info:<br>
I dont want to use position absolute. The divs have to by dynamic so it works on pc and phone.
You can use grid to make 3 boxes, each 1fr so they're evenly spaced then put your logo in the left one and the content in the middle one. You can then use flexbox to put the text div in to the middle of the centre div which is essentially the centre of the screen.
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
background-color: red;
}
.logo {
background-color: green;
width: 200px;
margin-left: 0;
margin-right: auto;
}
.textcontainer {
display: flex;
justify-content: center;
}
.container>div>div {
padding: 0.5rem 0.25rem;
}
<div class='container'>
<div class='logocontainer'>
<div class='logo'>
Logo
</div>
</div>
<div class='textcontainer'>
<div>
<!-- Put your text here -->
Text
</div>
</div>
<div></div>
<!-- this is a dummy container to push the text container to the middle of the screen -->
</div>

Convert template to pure css grid

I am trying to build a minor template, more specific this is what I am trying to do in css grid layout:
I am not convinced that my way is the modern approach, and would like to know if there is a pure way of doing this in only css grid, instead of mixing it with hights?
This is my fiddle of what I have tried:
https://jsfiddle.net/uwbsd2g6/
.wrapper {
display: grid;
grid-template-columns: 50% 50%;
}
.wrapper .col {
border: 1px solid blue;
min-height: 500px;
}
.wrapper .col-v-1 {
height: 50%;
}
.wrapper .col-v-2 {
height: 50%;
color: #fff;
background-color: blue;
}
<div class="wrapper">
<div class="col">
<div class="col-v-1">Here is some text</div>
<div class="col-v-2">Heres is another text</div>
</div>
<div class="col">
This is a third text
</div>
</div>
You can do this purely with css grid (assuming that you have an element with 100% height of the container as the parent) by using grid-template-column and grid-template-row as seen below
<style>
.wrapper {
height:100vh;
}
.outline{
outline: 1px red solid;
}
.grid {
display:grid
}
.grid-cols-2 {
grid-template-columns: 1fr 1fr;
}
.grid-rows-2 {
grid-template-rows: 1fr 1fr;
}
</style>
<div class="wrapper outline grid grid-cols-2">
<div class="grid grid-rows-2 outline">
<div class="outline">Here is some text</div>
<div class="outline">Heres is another text</div>
</div>
<div class="outline">
This is a third text
</div>
</div>
You can do it with grid template column and row

How to display container inside two columns?

I would like to display the content of these two columns only inside the container and the columns take the full width of the page like this image down bellow.
Is this possible by using css grid?
Thank you for your help and your support.
<div class="columns">
<div class="columns--container">
<div class="column">
<!-- Content -->
</div>
<div class="column">
<!-- Content -->
</div>
</div>
</div>
Ok, I'm new to grids, but this should work:
.columns {
height: 400px;
background: whitesmoke;
display: grid;
grid-template-columns: auto auto auto auto;
grid-gap: 10px;
}
.columns-container {
grid-column-start: 2;
grid-column-end: 4;
display: inherit;
grid-template-columns: auto auto;
flex-direction: row;
}
.column {
background: green;
}
<div class="columns">
<div class="columns-container">
<div class="column">
<!-- Content -->
</div>
<div class="column">
<!-- Content -->
</div>
</div>
</div>

Is it possible to put buttons under each element in a grid?

I'm trying to make a grid with items/pizza toppings to order, and I would like an "Add to cart" button under each item in the grid. How would I go about doing that?
So far I've tried simply putting a button with a line break under an element but as assumed, that didn't work.
Here is the relevant code I have in the body:
.wrapper {
width: 90%;
margin: 0 auto;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-auto-rows: 200px;
grid-row-gap: 30px;
grid-column-gap: 10px;
}
.item {
background: firebrick;
color: white;
padding: 10px;
}
.item:nth-child(even) {
background: rgb(139, 19, 19);
}
.add {
margin-bottom: 100px;
}
button {
margin-bottom: 100px;
}
#container {
background-color: maroon;
width: 1500px;
height: 1200px;
margin-left: auto;
margin-right: auto;
border-color: black;
border-width: 10px;
border-style: double;
}
<div id="container">
<div id="header">
<h1> Pizza Planet </h1>
<script src="index.js"></script>
</div>
<div id="content">
<h2>Select your items:</h2>
<div class="wrapper">
<div class="item">1</div>
<div class="add"><button>Add To Cart</button></div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</div>
</div>
All that does is make a huge gap for another cell on the grid with a tiny add to cart button on there. Any help would be appreciated, thank you.
One approach might be to use CSS grid to achieve what you require. A simple grid layout for what you describe above could be done like this:
.item img {
width:100%;
/* Causes the button to sit below the img */
display:block;
}
.item button {
width:100%;
}
.grid {
/* Specifies css grid to be used */
display:grid;
/* Specifies the number of columns and sizes in the grid */
grid-template-columns: 1fr 1fr;
/* Specifies spacing between grid cells */
grid-gap:1rem;
}
<div class="grid">
<div class="item">
<img src="http://wallpapersdsc.net/wp-content/uploads/2015/11/Pizza_Images12.jpg" />
<button>Order</button>
</div>
<div class="item">
<img src="http://wallpapersdsc.net/wp-content/uploads/2015/11/Pizza_Images12.jpg" />
<button>Order</button>
</div>
<div class="item">
<img src="http://wallpapersdsc.net/wp-content/uploads/2015/11/Pizza_Images12.jpg" />
<button>Order</button>
</div>
<div class="item">
<img src="http://wallpapersdsc.net/wp-content/uploads/2015/11/Pizza_Images12.jpg" />
<button>Order</button>
</div>
</div>

Combining the look of flex-start and space-between [duplicate]

This question already has answers here:
Targeting flex items on the last or specific row
(10 answers)
Wrapping flex items in the last row [duplicate]
(1 answer)
Closed 3 years ago.
I have a list of items I want to display with CSS. Originally, it was only two items side-by-side on one line but now I want to make it responsive for larger screens so I want to make it display 3 items on one line instead. My old code looks like this with justify-content:space-between. It looks good with an odd number of items to display.
.flex-container-old{
margin-top: 50px;
background: magenta;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.box-old{
width: 40%;
border: 1px solid black;
margin-bottom: 20px;
height: 300px;
background: orange;
}
.wrapper{
margin: 0 auto;
width: 80%;
}
body{
background:#D3D3D3;
}
<div class="wrapper">
<div class="flex-container-old">
<div class="box-old">
</div>
<div class="box-old">
</div>
<div class="box-old">
</div>
<div class="box-old">
</div>
<div class="box-old">
</div>
</div>
</div>
So naturally I extended it to three items in one row by modifying the width property only to end up with the below.
.flex-container-new{
background: lightblue;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.box {
width: 30%;
border: 1px solid black;
margin-bottom: 20px;
height: 300px;
background: orange;
}
.wrapper{
margin: 0 auto;
width: 80%;
}
<div class="wrapper">
<div class="flex-container-new">
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
</div>
</div>
My problem in the case of the above code with three items on one line is I want the last item in last row to be pushed to the left, aligned with the middle item in the row above it. Sadly bootstrap is not an option. This is for learning purposes. It there a way I can achieve the above with just CSS? Many thanks in advance.
This is easier to control using CSS Grid because we can dictate both the x and y axis. With Flexbox, you can only reliably control the x axis. If you haven't heard about the fr unit, it's defined by Mozilla as follows:
The fr, which is short for “fraction”, is a unit which represents a fraction of the available space in the grid container.
Another nice thing about using Grid is that we can drop the height and margin-bottom set in .box and also the flex-wrap rule. Everything about the layout of this grid, from the height of the cells to the grid-gap spacing between them, is all defined in the parent.
.grid-container-new {
background: lightblue;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 300px);
grid-gap: 20px;
}
.box {
border: 1px solid black;
background: orange;
}
<div class="grid-container-new">
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
</div>
jsFiddle