Make parent expand to the width of child with "display: grid" [duplicate] - html

This question already has answers here:
Make background color extend into overflow area
(4 answers)
Closed 3 years ago.
edit: Not sure this is a duplicate? I don want the background color to extend past the width of the container, I want the container to expand to the size of its display: grid child. Updated the example to better explain my problem.
I am building a table where each row is a css grid. I have done this to leverage the minmax() of each cell, to make the whole table scrollable when its cells can't shrink anymore, while allowing the table to grow if more space is available.
This works fine besides the fact that the styling for the rows only apply to the width of the container.
Please see this example:
.container {
width: 430px;
background: grey;
overflow-x: scroll;
}
.row {
display: grid;
grid-template-columns: minmax(200px, 1fr) minmax(200px, 1fr) minmax(200px, 1fr) minmax(100px, 1fr);
background: red;
height: 3rem;
margin: 0.5rem;
}
.cell {
border: 1px solid black;
}
Scroll to the right inside the box:
<div class="container">
<div class="row">
<span class="cell">cell 1</span>
<span class="cell">cell 2</span>
<span class="cell">cell 3</span>
<span class="cell">cell 4</span>
</div>
<div class="row">
<span class="cell">cell 1</span>
<span class="cell">cell 2</span>
<span class="cell">cell 3</span>
<span class="cell">cell 4</span>
</div>
</div>
Elements with the <code>.row</code> class should expand to fit all the cells.
Is there any way to solve this? I'm fine with adding extra elements if need be!

Changing the display of the rows to inline-grid seems to help:
.container {
width: 430px;
background: grey;
overflow-x: scroll;
}
.row {
display: inline-grid;
grid-template-columns: minmax(200px, 1fr) minmax(200px, 1fr) minmax(200px, 1fr) minmax(100px, 1fr);
background: red;
height: 3rem;
}
.cell {
border: 1px solid black;
}
Scroll to the right inside the box:
<div class="container">
<div class="row">
<span class="cell">cell 1</span>
<span class="cell">cell 2</span>
<span class="cell">cell 3</span>
<span class="cell">cell 4</span>
</div>
<div class="row">
<span class="cell">cell 1</span>
<span class="cell">cell 2</span>
<span class="cell">cell 3</span>
<span class="cell">cell 4</span>
</div>
</div>
The red background should cover the whole row.
Update 1
To avoid problems with wide container/narrow children getting in one line (as with the solution above), you can use a more convoluted solution, which uses a display: flex; flex-direction: column on the parent, with additional align-items: start that forces the row items to have full width (as opposed to default stretch, which makes the row width no wider than the container).
.container {
width: 430px;
background: grey;
overflow-x: scroll;
display: flex;
flex-direction: column;
align-items: start;
}
.container.container-wide{
width: 1000px;
}
.row {
display: grid;
grid-template-columns: minmax(200px, 1fr) minmax(200px, 1fr) minmax(200px, 1fr) minmax(100px, 1fr);
background: red;
height: 3rem;
}
.cell {
border: 1px solid black;
}
Scroll to the right inside the box:
<div class="container">
<div class="row">
<span class="cell">cell 1</span>
<span class="cell">cell 2</span>
<span class="cell">cell 3</span>
<span class="cell">cell 4</span>
</div>
<div class="row">
<span class="cell">cell 1</span>
<span class="cell">cell 2</span>
<span class="cell">cell 3</span>
<span class="cell">cell 4</span>
</div>
</div>
Wide container:
<div class="container container-wide">
<div class="row">
<span class="cell">cell 1</span>
<span class="cell">cell 2</span>
<span class="cell">cell 3</span>
<span class="cell">cell 4</span>
</div>
<div class="row">
<span class="cell">cell 1</span>
<span class="cell">cell 2</span>
<span class="cell">cell 3</span>
<span class="cell">cell 4</span>
</div>
</div>
The red background should cover the whole row.
Update 2
To allow for stretch of the row to the full width of the container in case it is wider than the sum of all columns, it is possible to adjust the solution from Update 1 by replacing the display: flex with display: grid, see example below:
.container {
width: 430px;
background: grey;
overflow-x: scroll;
display: grid;
}
.container.container-wide{
width: 1000px;
}
.row {
display: grid;
grid-template-columns: minmax(200px, 1fr) minmax(200px, 1fr) minmax(200px, 1fr) minmax(100px, 1fr);
background: red;
height: 3rem;
}
.cell {
border: 1px solid black;
}
Scroll to the right inside the box:
<div class="container">
<div class="row">
<span class="cell">cell 1</span>
<span class="cell">cell 2</span>
<span class="cell">cell 3</span>
<span class="cell">cell 4</span>
</div>
<div class="row">
<span class="cell">cell 1</span>
<span class="cell">cell 2</span>
<span class="cell">cell 3</span>
<span class="cell">cell 4</span>
</div>
</div>
Wide container:
<div class="container container-wide">
<div class="row">
<span class="cell">cell 1</span>
<span class="cell">cell 2</span>
<span class="cell">cell 3</span>
<span class="cell">cell 4</span>
</div>
<div class="row">
<span class="cell">cell 1</span>
<span class="cell">cell 2</span>
<span class="cell">cell 3</span>
<span class="cell">cell 4</span>
</div>
</div>
The red background should cover the whole row.

If you need to fill grid-template-columns with cell width, you should try:
.row {
display: grid;
grid-template-columns: auto auto auto auto;
background: red;
height: 3rem;
}
For 200px width on each cell, just add:
.cell {
min-width: 200px;
border: 1px solid black;
}

Related

Aligning elements of various widths to a grid without affecting the width of the entire column

I am trying to align items with various widths to a grid.
Using a min-width attribute, short elements can be aligned like that, but if an element is too wide, it will disrupt the alignment of the following elements in that row:
(apparently I'm not allowed to embed pictures. https://i.stack.imgur.com/YF2Mg.png)
What I would like to accomplish, is that after a long item, the following one will snap to the next "grid position", as I've mocked up here:
(https://i.stack.imgur.com/1tFr5.png)
I do not want there to be line-breaks in an item, and if at all possible, I'd like to avoid using JS.
Using a simple flexbox will of course not accomplish that, but it's the closest I've gotten to what I want.
#content {
color: black;
}
.container {
width: 275px;
background: gray;
border: 1px solid black;
display: flex;
flex-wrap: wrap;
}
.item {
border: 1px solid black;
background: white;
min-width: 55px;
margin: 2.5px;
padding: 2px;
}
<div id="content">
<div class="container">
<div class="item">
<span>Item 1</span>
</div>
<div class="item">
<span>Item 2a</span>
</div>
<div class="item">
<span>Item 2b</span>
</div>
<div class="item">
<span>Item 3</span>
</div>
<div class="item">
<span>Item 4 with a long name</span>
</div>
<div class="item">
<span>Item 5</span>
</div>
<div class="item">
<span>Item 6a</span>
</div>
<div class="item">
<span>Item 6b</span>
</div>
<div class="item">
<span>Item 7</span>
</div>
<div class="item">
<span>Item 8</span>
</div>
</div>
</div>
I have also looked into using grids or tables, but could not find a way for an element to span as many columns as are needed to fit its width.
This is not a fully dynamic solution, as you will have to do some styling on the specific item that is wider than the other items.
Transform the layout into a grid-layout, apply grid-template-columns: repeat(4, minmax(55px, 1fr)); which will make it a 4 column layout, where each item is at least 55px wide (better layout control than applying min-width on each item, IMO).
Target the item that is wider than the rest with nth-child or give it a specific class and use that instead, apply grid-column: span 3 which will make the item span into 3 columns inside a single row, and then give it max-width: fit-content. This way, the specific item's width will only be as wide as it has content to fill it up.
#content {
color: black;
}
.container {
width: 275px;
background: gray;
border: 1px solid black;
/* minmax 55px instead of min-width 55px on each item */
display: grid;
grid-template-columns: repeat(4, minmax(55px, 1fr));
}
.item {
border: 1px solid black;
background: white;
margin: 2.5px;
padding: 2px;
}
.item:nth-child(5) {
grid-column: span 3;
max-width: fit-content;
}
<div id="content">
<div class="container">
<div class="item">
<span>Item 1</span>
</div>
<div class="item">
<span>Item 2a</span>
</div>
<div class="item">
<span>Item 2b</span>
</div>
<div class="item">
<span>Item 3</span>
</div>
<div class="item">
<span>Item 4 with a long name</span>
</div>
<div class="item">
<span>Item 5</span>
</div>
<div class="item">
<span>Item 6a</span>
</div>
<div class="item">
<span>Item 6b</span>
</div>
<div class="item">
<span>Item 7</span>
</div>
<div class="item">
<span>Item 8</span>
</div>
</div>
</div>

How to make a monopoly board using css grid?

I want to create a monopoly board like . There are following features in the board
The corner are square shaped and bigger than other boxes
The text of each row is facing a specfic angle.
My basic html structure is below
Board
Row 1
Tile 1
Tile 2
...
I am successful in creating the basic structure using grid-template-areas. The problem I am facing is that I can't rotate the tiles of each row according to the need.
I have created a basic snippet which have only 3 tiles per row. The first row is facing right angle all other rows are at wrong angle. 90deg for second row. 180deg for third row. and 270deg for fourth row.
I have tried using writing-mode and transform:rotate() but it doesn't work or maybe I am using it wrong way. Please help me to find the correct way. I will be really thankful
*{
box-sizing: border-box;
}
#board {
display: grid;
/*first and last row and column are bigger than others*/
grid-template-columns: 100px repeat(2, 70px) 100px;
grid-template-rows: 100px repeat(2, 70px) 100px;
/*a, b, c, d are 4 rows and o is center*/
grid-template-areas:
"c c c d"
"b o o d"
"b o o d"
"b a a a";
}
#center {
grid-area: o;
}
.row {
display: flex;
}
.tile {
display: flex;
flex-direction: column;
border: 1px solid;
height: 100%;
width: 100%;
}
.tile-color {
flex: 3;
background: red;
border: 1px solid;
}
.tile-name {
flex: 6;
}
.tile-price {
flex: 3;
}
/*Flex directions are used to give the tiles correct order*/
#row-0 {
grid-area: a;
flex-direction: row-reverse;
}
#row-1 {
grid-area: b;
flex-direction: column-reverse;
}
#row-2 {
grid-area: c;
flex-direction: row;
}
#row-3 {
grid-area: d;
flex-direction: column;
}
/*To make the corner tiles bigger and square*/
.row > .tile:nth-child(1){
flex: 0 0 100px;
}
<div id="board">
<div id="center"></div>
<!--Row 1-->
<div class="row" id="row-0">
<div class="tile">
<div class="tile-name">Go</div>
</div>
<div class="tile">
<div class="tile-color"></div>
<div class="tile-name">Tile 1</div>
<div class="tile-price">Price 1</div>
</div>
<div class="tile">
<div class="tile-color"></div>
<div class="tile-name">Tile 2</div>
<div class="tile-price">Price 2</div>
</div>
</div>
<!--Row 2-->
<div class="row" id="row-1">
<div class="tile">
<div class="tile-name">Just visiting</div>
</div>
<div class="tile">
<div class="tile-color"></div>
<div class="tile-name">Tile 3</div>
<div class="tile-price">Price 3</div>
</div>
<div class="tile">
<div class="tile-color"></div>
<div class="tile-name">Tile 4</div>
<div class="tile-price">Price 4</div>
</div>
</div>
<!--Row 3-->
<div class="row" id="row-2">
<div class="tile">
<div class="tile-name">Free Parking</div>
</div>
<div class="tile">
<div class="tile-color"></div>
<div class="tile-name">Tile 4</div>
<div class="tile-price">Price 4</div>
</div>
<div class="tile">
<div class="tile-color"></div>
<div class="tile-name">Tile 5</div>
<div class="tile-price">Price 5</div>
</div>
</div>
<!--Row 4-->
<div class="row" id="row-3">
<div class="tile">
<div class="tile-name">Jail</div>
</div>
<div class="tile">
<div class="tile-color"></div>
<div class="tile-name">Tile 6</div>
<div class="tile-price">Price 6</div>
</div>
<div class="tile">
<div class="tile-color"></div>
<div class="tile-name">Tile 7</div>
<div class="tile-price">Price 7</div>
</div>
</div>
</div>
Here's one way to do this.
I have changed the HTML markup and haven't used grid-template-areas property. Each grid item is placed in the grid automatically in the order they are placed in the HTML markup.
Its a 4 x 4 grid where first and last columns are 120px in size and middle 2 columns are 75px each. Similarly first and last rows are 120px in size and middle 2 rows are 75px each.
To rotate grid items, i have created individual classes and applied appropriate rotation class on individual grid items which need to be rotated.
* {
box-sizing: border-box;
}
.board {
display: grid;
grid-template-columns: 120px repeat(2, 75px) 120px;
grid-template-rows: 120px repeat(2, 75px) 120px;
justify-content: center;
}
.lg-box {
text-align: center;
background: #999;
border: 1px solid;
overflow: hidden;
}
.sm-box {
width: 100%;
background: blue;
background: red;
height: 100%;
position: relative;
border: 1px solid;
overflow: hidden;
}
.sm-box div {
background: #fff;
height: 85%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
text-align: center;
position: absolute;
bottom: 0;
padding: 5px;
}
.lg-box-centered {
background: #fff;
grid-row: 2 / span 2;
grid-column: 2 / span 2;
}
.rot-180 {
transform: rotate(180deg);
}
.lg-rot,
.lg-box-centered {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.rot-135 {
transform: rotate(135deg);
}
.rot-45-reverse {
transform: rotate(-45deg);
}
.rot-45 {
transform: rotate(45deg);
}
.rot-135-reverse {
transform: rotate(-135deg);
}
.rot-90 {
transform: rotate(90deg);
}
.rot-90-reverse {
transform: rotate(-90deg);
}
.sm-box .rot-90,
.sm-box .rot-90-reverse {
position: absolute;
left: 12px;
top: -12px;
width: 75px;
height: 100px;
}
.sm-box .rot-90-reverse {
left: initial;
right: 12px;
}
<div class="board">
<div class="lg-box">
<div class="lg-rot rot-135">Just Visiting</div>
</div>
<div class="sm-box rot-180">
<div>
<span class="title">Title 5</span>
<span class="price">Price 5</span>
</div>
</div>
<div class="sm-box rot-180">
<div>
<span class="title">Title 6</span>
<span class="price">Price 6</span>
</div>
</div>
<div class="lg-box">
<div class="lg-rot rot-135-reverse">Jail</div>
</div>
<div class="sm-box">
<div class="rot-90">
<span class="title">Title 4</span>
<span class="price">Price 4</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90-reverse">
<span class="title">Title 7</span>
<span class="price">Price 7</span>
</div>
</div>
<div class="lg-box-centered">center</div>
<div class="sm-box">
<div class="rot-90">
<span class="title">Title 3</span>
<span class="price">Price 3</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90-reverse">
<span class="title">Title 8</span>
<span class="price">Price 8</span>
</div>
</div>
<div class="lg-box">
<div class="lg-rot rot-45">Just Visiting</div>
</div>
<div class="sm-box">
<div>
<span class="title">Title 2</span>
<span class="price">Price 2</span>
</div>
</div>
<div class="sm-box">
<div>
<span class="title">Title 1</span>
<span class="price">Price 1</span>
</div>
</div>
<div class="lg-box">
<div class="lg-rot rot-45-reverse">Go</div>
</div>
</div>
Here's an alternative approach with 7 x 7 grid and uses writing-mode property. Only difference between this approach and the previous one is that it uses writing-mode property to properly align text within small boxes from row number 2 to row number 6.
* {
box-sizing: border-box;
}
.board {
display: grid;
grid-template-columns: 120px repeat(5, 75px) 120px;
grid-template-rows: 120px repeat(5, 75px) 120px;
justify-content: center;
}
.lg-box {
text-align: center;
background: #999;
border: 1px solid;
overflow: hidden;
}
.sm-box {
width: 100%;
background: blue;
background: red;
height: 100%;
position: relative;
border: 1px solid;
overflow: hidden;
}
.sm-box div {
background: #fff;
height: 85%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
text-align: center;
position: absolute;
bottom: 0;
padding: 5px;
}
.lg-box-centered {
background: #fff;
grid-row: 2 / span 5;
grid-column: 2 / span 5;
}
.rot-180 {
transform: rotate(180deg);
}
.lg-rot,
.lg-box-centered {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.rot-135 {
transform: rotate(135deg);
}
.rot-45-reverse {
transform: rotate(-45deg);
}
.rot-45 {
transform: rotate(45deg);
}
.rot-135-reverse {
transform: rotate(-135deg);
}
.sm-box .rot-90,
.sm-box .rot-90-reverse {
height: 75px;
width: 85%;
writing-mode: vertical-rl;
position: absolute;
left: -10px;
}
.sm-box .rot-90-reverse {
transform: rotate(180deg);
right: 10px;
}
<div class="board">
<div class="lg-box">
<div class="lg-rot rot-135">Just Visiting</div>
</div>
<div class="sm-box rot-180">
<div>
<span class="title">Title 11</span>
<span class="price">Price 11</span>
</div>
</div>
<div class="sm-box rot-180">
<div>
<span class="title">Title 12</span>
<span class="price">Price 12</span>
</div>
</div>
<div class="sm-box rot-180">
<div>
<span class="title">Title 13</span>
<span class="price">Price 13</span>
</div>
</div>
<div class="sm-box rot-180">
<div>
<span class="title">Title 14</span>
<span class="price">Price 14</span>
</div>
</div>
<div class="sm-box rot-180">
<div>
<span class="title">Title 15</span>
<span class="price">Price 15</span>
</div>
</div>
<div class="lg-box">
<div class="lg-rot rot-135-reverse">Jail</div>
</div>
<div class="sm-box">
<div class="rot-90">
<span class="title">Title 10</span>
<span class="price">Price 10</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90-reverse">
<span class="title">Title 16</span>
<span class="price">Price 16</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90">
<span class="title">Title 9</span>
<span class="price">Price 9</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90-reverse">
<span class="title">Title 17</span>
<span class="price">Price 17</span>
</div>
</div>
<div class="lg-box-centered">center</div>
<div class="sm-box">
<div class="rot-90">
<span class="title">Title 8</span>
<span class="price">Price 8</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90-reverse">
<span class="title">Title 18</span>
<span class="price">Price 18</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90">
<span class="title">Title 7</span>
<span class="price">Price 7</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90-reverse">
<span class="title">Title 19</span>
<span class="price">Price 19</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90">
<span class="title">Title 6</span>
<span class="price">Price 6</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90-reverse">
<span class="title">Title 20</span>
<span class="price">Price 20</span>
</div>
</div>
<div class="lg-box">
<div class="lg-rot rot-45">Just Visiting</div>
</div>
<div class="sm-box">
<div>
<span class="title">Title 5</span>
<span class="price">Price 5</span>
</div>
</div>
<div class="sm-box">
<div>
<span class="title">Title 4</span>
<span class="price">Price 4</span>
</div>
</div>
<div class="sm-box">
<div>
<span class="title">Title 3</span>
<span class="price">Price 3</span>
</div>
</div>
<div class="sm-box">
<div>
<span class="title">Title 2</span>
<span class="price">Price 2</span>
</div>
</div>
<div class="sm-box">
<div>
<span class="title">Title 1</span>
<span class="price">Price 1</span>
</div>
</div>
<div class="lg-box">
<div class="lg-rot rot-45-reverse">Go</div>
</div>
</div>
Here's a 7 x 7 board using first approach
* {
box-sizing: border-box;
}
.board {
display: grid;
grid-template-columns: 120px repeat(5, 75px) 120px;
grid-template-rows: 120px repeat(5, 75px) 120px;
justify-content: center;
}
.lg-box {
text-align: center;
background: #999;
border: 1px solid;
overflow: hidden;
}
.sm-box {
width: 100%;
background: blue;
background: red;
height: 100%;
position: relative;
border: 1px solid;
overflow: hidden;
}
.sm-box div {
background: #fff;
height: 85%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
text-align: center;
position: absolute;
bottom: 0;
padding: 5px;
}
.lg-box-centered {
background: #fff;
grid-row: 2 / span 5;
grid-column: 2 / span 5;
}
.rot-180 {
transform: rotate(180deg);
}
.lg-rot,
.lg-box-centered {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.rot-135 {
transform: rotate(135deg);
}
.rot-45-reverse {
transform: rotate(-45deg);
}
.rot-45 {
transform: rotate(45deg);
}
.rot-135-reverse {
transform: rotate(-135deg);
}
.rot-90 {
transform: rotate(90deg);
}
.rot-90-reverse {
transform: rotate(-90deg);
}
.sm-box .rot-90,
.sm-box .rot-90-reverse {
position: absolute;
left: 12px;
top: -12px;
width: 75px;
height: 100px;
}
.sm-box .rot-90-reverse {
left: initial;
right: 12px;
}
<div class="board">
<div class="lg-box">
<div class="lg-rot rot-135">Just Visiting</div>
</div>
<div class="sm-box rot-180">
<div>
<span class="title">Title 11</span>
<span class="price">Price 11</span>
</div>
</div>
<div class="sm-box rot-180">
<div>
<span class="title">Title 12</span>
<span class="price">Price 12</span>
</div>
</div>
<div class="sm-box rot-180">
<div>
<span class="title">Title 13</span>
<span class="price">Price 13</span>
</div>
</div>
<div class="sm-box rot-180">
<div>
<span class="title">Title 14</span>
<span class="price">Price 14</span>
</div>
</div>
<div class="sm-box rot-180">
<div>
<span class="title">Title 15</span>
<span class="price">Price 15</span>
</div>
</div>
<div class="lg-box">
<div class="lg-rot rot-135-reverse">Jail</div>
</div>
<div class="sm-box">
<div class="rot-90">
<span class="title">Title 10</span>
<span class="price">Price 10</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90-reverse">
<span class="title">Title 16</span>
<span class="price">Price 16</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90">
<span class="title">Title 9</span>
<span class="price">Price 9</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90-reverse">
<span class="title">Title 17</span>
<span class="price">Price 17</span>
</div>
</div>
<div class="lg-box-centered">center</div>
<div class="sm-box">
<div class="rot-90">
<span class="title">Title 8</span>
<span class="price">Price 8</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90-reverse">
<span class="title">Title 18</span>
<span class="price">Price 18</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90">
<span class="title">Title 7</span>
<span class="price">Price 7</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90-reverse">
<span class="title">Title 19</span>
<span class="price">Price 19</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90">
<span class="title">Title 6</span>
<span class="price">Price 6</span>
</div>
</div>
<div class="sm-box">
<div class="rot-90-reverse">
<span class="title">Title 20</span>
<span class="price">Price 20</span>
</div>
</div>
<div class="lg-box">
<div class="lg-rot rot-45">Just Visiting</div>
</div>
<div class="sm-box">
<div>
<span class="title">Title 5</span>
<span class="price">Price 5</span>
</div>
</div>
<div class="sm-box">
<div>
<span class="title">Title 4</span>
<span class="price">Price 4</span>
</div>
</div>
<div class="sm-box">
<div>
<span class="title">Title 3</span>
<span class="price">Price 3</span>
</div>
</div>
<div class="sm-box">
<div>
<span class="title">Title 2</span>
<span class="price">Price 2</span>
</div>
</div>
<div class="sm-box">
<div>
<span class="title">Title 1</span>
<span class="price">Price 1</span>
</div>
</div>
<div class="lg-box">
<div class="lg-rot rot-45-reverse">Go</div>
</div>
</div>
I liked your question, to solve I combined both "transform:rotate()" and "writing-mode:vertical-rl", and I rotated the titles of the corners to stay diagonal!
I just changed what is below the last 2 comments in CSS:
*{
box-sizing: border-box;
}
#board {
display: grid;
/*first and last row and column are bigger than others*/
grid-template-columns: 100px repeat(2, 70px) 100px;
grid-template-rows: 100px repeat(2, 70px) 100px;
/*a, b, c, d are 4 rows and o is center*/
grid-template-areas:
"c c c d"
"b o o d"
"b o o d"
"b a a a";
}
#center {
grid-area: o;
}
.row {
display: flex;
}
.tile {
display: flex;
flex-direction: column;
border: 1px solid;
height: 100%;
width: 100%;
}
.tile-color {
flex: 3;
background: red;
border: 1px solid;
}
.tile-name {
flex: 6;
}
.tile-price {
flex: 3;
}
/*Flex directions are used to give the tiles correct order*/
#row-0 {
grid-area: a;
flex-direction: row-reverse;
}
#row-1 {
grid-area: b;
flex-direction: column-reverse;
}
#row-2 {
grid-area: c;
flex-direction: row;
}
#row-3 {
grid-area: d;
flex-direction: column;
}
/*To make the corner tiles bigger and square*/
.row > .tile:nth-child(1){
flex: 0 0 100px;
}
/*Turn tiles*/
#row-1 .tile{
writing-mode: vertical-rl;
}
#row-2 .tile{
transform: rotate(180deg);
}
#row-3 .tile{
writing-mode: vertical-rl;
transform: rotate(180deg);
}
/*Turn corners*/
.row > .tile:first-child{
text-align: center;
}
#row-0 > .tile:first-child .tile-name{
transform: rotate(-45deg) translateY(38px);
}
#row-1 > .tile:first-child .tile-name{
transform: rotate(-45deg) translateX(-38px);
}
#row-2 > .tile:first-child .tile-name{
transform: rotate(-45deg) translateY(38px);
}
#row-3 > .tile:first-child .tile-name{
transform: rotate(-45deg) translateX(-38px);
}
<div id="board">
<div id="center"></div>
<!--Row 1-->
<div class="row" id="row-0">
<div class="tile">
<div class="tile-name">Go</div>
</div>
<div class="tile">
<div class="tile-color"></div>
<div class="tile-name">Tile 1</div>
<div class="tile-price">Price 1</div>
</div>
<div class="tile">
<div class="tile-color"></div>
<div class="tile-name">Tile 2</div>
<div class="tile-price">Price 2</div>
</div>
</div>
<!--Row 2-->
<div class="row" id="row-1">
<div class="tile">
<div class="tile-name">Just visiting</div>
</div>
<div class="tile">
<div class="tile-color"></div>
<div class="tile-name">Tile 3</div>
<div class="tile-price">Price 3</div>
</div>
<div class="tile">
<div class="tile-color"></div>
<div class="tile-name">Tile 4</div>
<div class="tile-price">Price 4</div>
</div>
</div>
<!--Row 3-->
<div class="row" id="row-2">
<div class="tile">
<div class="tile-name">Free Parking</div>
</div>
<div class="tile">
<div class="tile-color"></div>
<div class="tile-name">Tile 4</div>
<div class="tile-price">Price 4</div>
</div>
<div class="tile">
<div class="tile-color"></div>
<div class="tile-name">Tile 5</div>
<div class="tile-price">Price 5</div>
</div>
</div>
<!--Row 4-->
<div class="row" id="row-3">
<div class="tile">
<div class="tile-name">Jail</div>
</div>
<div class="tile">
<div class="tile-color"></div>
<div class="tile-name">Tile 6</div>
<div class="tile-price">Price 6</div>
</div>
<div class="tile">
<div class="tile-color"></div>
<div class="tile-name">Tile 7</div>
<div class="tile-price">Price 7</div>
</div>
</div>
</div>
I noticed that the "writing-mode" didn’t turn to the other horizontal, so I turned it to the same horizontal and rotated 180º, so it stays in exactly the same position.
I hope I helped you!
Since this question is tagged with #javascript and currently there is no answer using it I decided to give it a go.
I assume that your goal is to make an interactive board game, so there is no avoiding JS.
If your goal is to just render such grid, I also made an attempt to do it almost exclusively in CSS - it means just bunch of divs without any classes or ids and then setting up grid mostly based on :nth-child() pseudo-class.
const TileType = {
TECHNOLOGY: 'technology',
CHANCE: 'chance',
START: 'start',
STACKOVERFLOW: 'stackoverflow',
GO_TO_STACKOVERFLOW: 'goToStackoverflow',
DEBUGGING: 'debugging',
}
const TechnologyType = {
BACKEND: 'backend',
FRONTEND: 'frontend',
MOBILE: 'mobile',
NATIVE: 'native',
}
const ChanceType = {
RED: 'red',
BLUE: 'blue',
}
class Tile {
constructor(title, type, value = null) {
this.title = title;
this.type = type;
this.value = value;
}
toHTML() {
const card = document.createElement('div');
if ( this.title) {
const title = document.createElement('p');
title.classList.add('title');
title.innerText = this.title;
card.appendChild(title);
}
card.addEventListener('click', () => console.log(this));
return card;
}
}
// Still no static props in JS
const technologyColorMap = {
[TechnologyType.BACKEND]: '#2ab7ca',
[TechnologyType.FRONTEND]: '#fed766',
[TechnologyType.MOBILE]: '#7bc043',
[TechnologyType.NATIVE]: '#63ace5',
};
class TechnologyTile extends Tile {
constructor(title, subType, value = null) {
super(title, TileType.TECHNOLOGY, value);
this.technologyType = subType;
}
toHTML() {
const card = super.toHTML();
card.classList.add('technology');
const colorBox = document.createElement('div');
colorBox.classList.add('colorBox');
colorBox.style.backgroundColor = technologyColorMap[this.technologyType];
card.prepend(colorBox);
return card;
}
}
const chanceTypeColorMap = {
[ChanceType.RED]: '#fe4a49',
[ChanceType.BLUE]: '#005b96',
};
class ChanceTile extends Tile {
constructor(title, subType, value = null) {
super(title, TileType.CHANCE, value);
this.chanceType = subType;
}
toHTML() {
const card = super.toHTML();
card.classList.add('chance');
//card.appendChild(this.getIcon());
return card;
}
getIcon() {
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.classList.add('chance');
svg.setAttributeNS(null,"width","180");
svg.setAttributeNS(null,"height","180");
const path = document.createElementNS('http://www.w3.org/2000/svg',"path");
path.setAttributeNS(null,"d","M60,67c0-13 1-19 8-26c7-9 18-10 28-8c10,2 22,12 22,26c0,14-11,19-15,22c-7,2-10,6-11,11v20m0,12v16");
path.setAttributeNS(null,"fill", "none");
path.setAttributeNS(null,"stroke", chanceTypeColorMap[this.chanceType]);
path.setAttributeNS(null,"stroke-width","6");
svg.appendChild(path);
return svg;
}
}
const tiles = [
new Tile('Start', TileType.START),
new TechnologyTile('Java Spring', TechnologyType.BACKEND, 10),
new ChanceTile('Chance', ChanceType.RED),
new TechnologyTile('NodeJS', TechnologyType.BACKEND, 15),
new Tile('StackOverflow', TileType.STACKOVERFLOW),
new TechnologyTile('Angular', TechnologyType.FRONTEND, 20),
new TechnologyTile('iOS', TechnologyType.MOBILE, 30),
new TechnologyTile('React', TechnologyType.FRONTEND, 25),
new ChanceTile('Chance', ChanceType.BLUE),
new ChanceTile('Chance', ChanceType.RED),
new TechnologyTile('Android', TechnologyType.MOBILE, 35),
new Tile('Go To StackOverlfow', TileType.GO_TO_STACKOVERFLOW),
new TechnologyTile('Swing', TechnologyType.NATIVE, 40),
new ChanceTile('Chance', ChanceType.BLUE),
new TechnologyTile('Qt', TechnologyType.NATIVE, 45),
new Tile('Free Debugging', TileType.DEBUGGING),
]
class Board {
constructor(tiles, root) {
this.tiles = tiles;
this.root = root;
}
render() {
this.root.innerHTML = '';
for (let i = 0; i < this.tiles.length; ++i) {
const tile = this.tiles[i].toHTML();
if (i == 0 || i == this.tiles.length - 5) {
tile.classList.add('big-square-left');
} else if ( i == 4 || i == this.tiles.length - 1) {
tile.classList.add('big-square-right');
}
if (i < 5) {
tile.classList.add('top-row');
} else if (i < this.tiles.length - 5) {
tile.classList.add(i % 2 == 0 ? 'right' : 'left');
} else {
tile.classList.add('bottom-row');
}
this.root.appendChild(tile);
}
}
}
const board = new Board(tiles, document.getElementById('root'));
board.render();
#root {
width: 80vw;
height: 80vw;
display: grid;
grid-template-rows: 2fr repeat(3, 1fr) 2fr;
grid-template-columns: repeat(7, 1fr);
}
#root > div {
border: 1px solid black;
position:relative;
}
#root div:nth-child(2n + 6) {
grid-column: 1 / span 2;
}
#root div:nth-child(2n + 7) {
grid-column: 6 / span 2;
}
#root div:nth-child(2n + 7) {
grid-column: 6 / span 2;
}
/*#root div:nth-child(n + 12) {*/
#root div.bottom-row {
grid-column: auto;
}
#root div.big-square-left {
grid-column: 1 / span 2;
}
#root div.big-square-right {
grid-column: 6 / span 2;
}
#root div p.title {
text-align: center;
position:relative;
}
#root div.top-row p.title {
transform: rotate(180deg);
top: 10%;
}
#root div.left p.title {
transform: rotate(90deg);
top: 10%;
}
#root div.left.technology p.title {
top: -85%;
}
#root div.right p.title {
transform: rotate(270deg);
}
#root div.right.technology p.title {
top: -85%;
}
#root div.right p.title {
transform: rotate(270deg);
}
#root div.big-square-right.top-row p.title {
transform: rotate(225deg);
top: 25%
}
#root div.big-square-right.bottom-row p.title {
transform: rotate(315deg);
top: 25%
}
#root div.big-square-left.bottom-row p.title {
transform: rotate(45deg);
top: 25%
}
div.colorBox {
position: relative;
}
#root > div.right > div.colorBox {
width: 20%;
height: 100%;
}
#root > div.left > div.colorBox {
width: 20%;
height: 100%;
right: -80%;
}
#root > div.top-row > div.colorBox {
height: 20%;
top: 80%;
}
#root > div.bottom-row > div.colorBox {
height: 20%;
}
svg.chance {
position: absolute;
}
#root > div.bottom-row > svg.chance
{
transform: scale(0.75);
left: -86%;
top: -5%;
}
#root > div.top-row > svg.chance
{
transform: scale(-0.75);
left: -86%;
top: -36%;
}
#root > div.left > svg.chance
{
transform: scale(0.75) rotate(90deg);
left: -36%;
top: -88%;
}
#root > div.right > svg.chance
{
transform: scale(0.75) rotate(270deg);
left: -5%;
top: -89%;
}
#root > div.chance.top-row > p.title
{
top: 68%;
}
#root > div.chance.right > p.title
{
left: -38%;
top: 10%;
}
#root > div.chance.left > p.title
{
right: -40%;
}
#root > div.chance.bottom-row > p.title
{
top: -8%;
}
<div id="root"></div>

Using flex to align items that have flex already?

I am trying to have a container with many child tiles of content inside. Each child tile contains data that I want centered so that is why flex is on the child -- so that I can align the tile content.
I want to align 3 to a line evenly so I put flex on the parent class and wanted to space-evenly but that doesn't seem to work. Any ideas on what I am doing wrong?
<div class="container">
<div class="child">
<img src="">
<span>TITLE</span>
</div>
<div class="child">
<img src="">
<span>TITLE</span>
</div>
<div class="child">
<img src="">
<span>TITLE</span>
</div>
<div class="child">
<img src="">
<span>TITLE</span>
</div>
<div class="child">
<img src="">
<span>TITLE</span>
</div>
<div class="child">
<img src="">
<span>TITLE</span>
</div>
<div class="child">
<img src="">
<span>TITLE</span>
</div>
</div>
CSS
.parent {
display: flex;
max-width: 1200px;
}
.child {
display: inline-flex;
margin-bottom: 26px;
flex-direction: column;
justify-content: center;
align-items: center;
width: 396px;
height:396px;
}
You had a few key things missing. Number one, your parent container was missing the class parent so that CSS never hit its target. Opening tag is now:
<div class="container parent">
Next I added an important flex property to the .parent CSS rule, allowing the items to wrap, otherwise theres no way you can get 3-across with more than 3 items:
flex-wrap: wrap;
Adding space-between to .parent makes sure the items go edge to edge regardless of the width and space between items:
justify-content: space-between;
Then I added a width to the .child elements that is flexible that creates the 3-across layout. I used calc as a quick way to get some space between the elements instead of them touching horizontally:
width: calc(33.333% - 20px);
Also threw little images in there to see more of the inner flex effect too. Hope this helps!
.parent {
display: flex;
max-width: 1200px;
justify-content: space-between;
flex-wrap: wrap;
}
.child {
display: flex;
margin-bottom: 26px;
flex-direction: column;
justify-content: center;
align-items: center;
width: calc(33.333% - 20px);
background-color: #ccc;
}
<div class="container parent">
<div class="child">
<img src="https://picsum.photos/40">
<span>TITLE 1</span>
</div>
<div class="child">
<img src="https://picsum.photos/40">
<span>TITLE 2</span>
</div>
<div class="child">
<img src="https://picsum.photos/40">
<span>TITLE 3</span>
</div>
<div class="child">
<img src="https://picsum.photos/40">
<span>TITLE 4</span>
</div>
<div class="child">
<img src="https://picsum.photos/40">
<span>TITLE 5</span>
</div>
<div class="child">
<img src="https://picsum.photos/40">
<span>TITLE 6</span>
</div>
<div class="child">
<img src="https://picsum.photos/40">
<span>TITLE 7</span>
</div>
</div>

Making the height of each cell of a css grid depend on the biggest cell of his row

I'm currently working on making a grid that will contain a different amount of items in each cells, and I am currently facing issues sizing the height of the cells in each rows accordingly :
I would like the height of each cell to be the same height as the biggest cell in each rows, but as it stands, the height of each cells depends on the highest cell in the entire grid.
Here's a mockup of what I currently have, notice how the while the cells in the third row are correct, the cells in the first and second row are too big.
.grid {
background-color: red;
display: grid;
grid-auto-columns: 1fr;
grid-auto-flow: column;
}
.grid-column {
background-color: blue;
display: grid;
grid-auto-rows: 1fr;
grid-auto-flow: row;
margin: 2px;
box-sizing: border-box;
}
.grid-row {
background-color: green;
margin: 2px;
box-sizing: border-box;
}
.item {
background-color: white;
margin: 2px;
box-sizing: border-box;
display: block;
}
<div class="grid">
<div class="grid-column">
<div class="grid-row"></div>
<div class="grid-row"></div>
<div class="grid-row"></div>
</div>
<div class="grid-column">
<div class="grid-row">
<span class="item">item 1</span>
<span class="item">item 2</span>
</div>
<div class="grid-row"></div>
<div class="grid-row"></div>
</div>
<div class="grid-column">
<div class="grid-row"></div>
<div class="grid-row">
<span class="item">item 3</span>
<span class="item">item 4</span>
</div>
<div class="grid-row"></div>
</div>
<div class="grid-column">
<div class="grid-row"></div>
<div class="grid-row"></div>
<div class="grid-row"></div>
</div>
<div class="grid-column">
<div class="grid-row"></div>
<div class="grid-row"></div>
<div class="grid-row">
<span class="item">item 5</span>
<span class="item">item 6</span>
<span class="item">item 7</span>
<span class="item">item 8</span>
</div>
</div>
</div>

Flexboxes overlapping in IE 11

I'm currently debugging a website to make it work on IE 11. Now there is one page, were there are two div tables inside a flexbox container. Under the container, there is another flexbox 'navLine', which should be positioned directly under the container. This works fine in every browser except IE 11. There the container and the navLine seem to overlap. Oddly enough, the navLine sticks to a button within the container. The button is within a cell of the div table, without any additional CSS properties.
Any help?
Here's the simplified code:
#NavLine
{
margin-bottom: 8px;
display: -webkit-flex;
display: -ms-flex;
display: flex;
justify-content: space-between;
align-items: center;
}
.SelectionBox
{
background: #f7f7f7;
border: 1px solid #d9d9d9;
padding: 16px;
margin-bottom: 16px;
min-width: 570px;
min-height: 410px;
}
.Container
{
display: -webkit-flex;
display: -ms-flex;
display: flex;
-webkit-justify-content: space-around;
-ms-justify-content: space-around;
justify-content: space-around;
width: 100%;
flex: 1 1 auto;
}
#Box1, #Box2
{
flex: 1 1 auto;
padding: 16px;
}
.Table
{
display: table;
table-layout: fixed;
overflow: hidden;
height: 100%;
width: 75%;
}
.Title
{
display: table-header-group;
width: 100%;
height: 80px;
}
.Row
{
display: table-row;
}
.Cell
{
display: table-cell;
padding-left: 5px;
padding-right: 5px;
vertical-align: middle;
height: 70px;
}
<div class="Container">
<!-- First Box -->
<div id="Box1">
<div class="Table SelectionBox">
<div class="Title">
<h2>Box One</h2>
</div>
<div class="Row">
<div class="Cell">
<span>Some Item</span>
</div>
<div class="Cell">
<span>Some Value</span>
</div>
</div>
<div class="Row">
<div class="Cell">
<span>Some Item</span>
</div>
<div class="Cell">
<span>Some Value</span>
</div>
</div>
<div class="Row">
<div class="Cell">
<span>Some Item</span>
</div>
<div class="Cell">
<span>Some Value</span>
</div>
</div>
<div class="Row">
<div class="Cell">
<span>Some Item</span>
</div>
<div class="Cell">
<span>Some Value</span>
</div>
</div>
<div class="Row">
<div class="Cell"></div>
<div class="Cell">
<span> ([[result]]) Results</span>
<span>Reset (this is a button)</span>
</div>
</div>
</div>
</div>
<!-- Second Box -->
<div id="Box2">
<div class="Table SelectionBox">
<div class="Title">
<h2>Box Two</h2>
</div>
<div class="Row">
<div class="Cell">
<span>Some Item</span>
</div>
<div class="Cell">
<span>Some Value</span>
</div>
</div>
<div class="Row">
<div class="Cell">
<span>Some Item</span>
</div>
<div class="Cell">
<span>Some Value</span>
</div>
</div>
<div class="Row">
<div class="Cell">
<span>Some Item</span>
</div>
<div class="Cell">
<span>Some Value</span>
</div>
</div>
<div class="Row">
<div class="Cell">
<span>Some Item</span>
</div>
<div class="Cell">
<span>Some Value</span>
</div>
</div>
<div class="Row">
<div class="Cell"></div>
<div class="Cell">
<span> ([[result]]) Results</span>
<span>Reset (this is a button)</span>
</div>
</div>
</div>
</div>
</div>
<div id="NavLine">
<span>Back</span>
<span>Next</span>
</div>
The problem in IE is that height: 100% in .Table.SelectionBox is causing that element to overflow its container (#Box1). It then overlaps the #NavLine element, which is not causing any problem.
One way to fix the problem is to remove that height rule.
"IE 11 requires a unit to be added to the third argument, the flex-basis property" - see "known issues" tab https://caniuse.com/#feat=flexbox
also, a min-height might be required
so, try for example:
#container > div {
flex:1 1 8em;
min-height:8em;
}