Maheer Ali
Maheer Ali

Reputation: 36564

How to make a monopoly board using css grid?

I want to create a monopoly board like enter image description here. There are following features in the board

My basic html structure is below

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>

Upvotes: 40

Views: 11052

Answers (3)

matvs
matvs

Reputation: 1873

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>

Upvotes: 5

Yousaf
Yousaf

Reputation: 29282

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>

Upvotes: 18

KevynTD
KevynTD

Reputation: 682

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!

Upvotes: 5

Related Questions