Hoe een monopoly board te maken met CSS-raster?

Ik wil een monopoly bord maken zoals . Er zijn de volgende functies in het bord

  • De hoek is vierkant gevormd en groter dan andere dozen
  • De tekst van elke rij is geconfronteerd met een specfic-hoek.

Mijn standaard HTML-structuur is lager dan

  • bord
    • rij 1
      • tegel 1
      • tegel 2

Ik ben succesvol in het maken van de basisstructuur met behulp van grid-template-areas. Het probleem waarmee ik tegenkom is dat ik de tegels van elke rij niet kan draaien volgens de behoefte.

Ik heb een basisfragment gemaakt met slechts 3 tegels per rij. De eerste rij wordt geconfronteerd met de rechthoekige hoek Alle andere rijen zijn in een verkeerde hoek. 90degvoor de tweede rij. 180degvoor de derde rij. en 270degvoor vierde rij.

Ik heb geprobeerd met writing-modeen transform:rotate()maar het werkt niet of misschien gebruik ik het verkeerd. Help me alsjeblieft om de juiste manier te vinden. Ik zal heel dankbaar zijn

*{
  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>

Antwoord 1, autoriteit 100%

Hier is een manier om dit te doen.

Ik heb de HTML-opmaak gewijzigd en heb de eigenschap grid-template-areasniet gebruikt. Elk rasteritem wordt automatisch in het raster geplaatst in de volgorde waarin ze in de HTML-opmaak zijn geplaatst.

het is een 4 x 4raster waarbij eerste en laatste kolommen 120px in grootte en middelste 2 kolommen zijn, zijn elk 75px. Evenzo zijn de eerste en laatste rijen 120px in grootte en midden 2 rijen zijn elk 75px.

Om rasteritems te draaien, heb ik afzonderlijke klassen gemaakt en geschikte rotatieklasse toegepast op individuele rasterartikelen die moeten worden geroteerd.


Antwoord 2, Autoriteit 28%

Aangezien deze vraag is getagd met #javascript en momenteel is er geen antwoord met behulp van het dat ik besloot .
Ik neem aan dat je doel is om een ​​interactief bordspel te maken, dus er is geen vermeden JS.

Als je doel is om gewoon een dergelijk raster te renderen, heb ik ook een poging gedaan om het bijna uitsluitend in CSS te doen – het betekent gewoon een stel dia’s zonder klassen of ID’s en vervolgens het raster instellen, meestal op basis van: nth-kind ( ) Pseudo-klasse.

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>

Antwoord 3, autoriteit 22%

Ik vond je vraag leuk, om op te lossen heb ik zowel “transform:rotate()” als “writing-mode:vertical-rl” gecombineerd en ik heb de titels van de hoeken gedraaid om diagonaal te blijven!

Ik heb zojuist gewijzigd wat onder de laatste 2 opmerkingen in CSS staat:

*{
  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>

Other episodes