I want to create a simple isometric tilemap with HTML and CSS.
The tiles are 128px wide and 64px high, but some of them, like the one below, contains graphical elements that gives them a total height of 128px.
In this simplified example, the isometric tilemap is only 2x2 tiles and should look like this:
How do I display these tiles correctly with HTML and CSS, so that they have the right placement and proportions?
Please note that the 2x2 tilemap is just an example. The solution needs to work just as well (or just about) if the map is 5x5 tiles or 25x75 tiles. It also needs to work regardless of tile order.
So far, my idea has been to rotate the container to make it isometric, and then rotate the tiles in the opposite direction to "compensate" for the rotation of the container (I'd prefer to display the tiles the way they are drawn). But I'm not sure this is the right approach. The placement is not correct and the images are distorted.
Can you tell what I'm doing wrong?
.container {
width: 256px;
height: 256px;
transform: rotateX(60deg) rotateZ(45deg);
display: flex;
flex-wrap: wrap;
background-color: blue;
}
.tile {
width: 128px;
transform: rotateX(0deg) rotateZ(-45deg);
}
.grass {
height: 64px;
background-image: url("https://i.stack.imgur.com/39MxJ.png");
}
.bush {
height: 128px;
background-image: url("https://i.stack.imgur.com/GpNEI.png");
}
<div class="container">
<div class="tile grass"></div>
<div class="tile grass"></div>
<div class="tile bush"></div>
<div class="tile bush"></div>
</div>
CodePudding user response:
With the current structure, just change some CSS properties.
I don't think there is any need to use the "transform" property, this can be achieved by the display: grid
property also.
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
grid-row: span 2;
grid-auto-flow: dense;
width: 258px;
grid-auto-rows: 32px;
min-height: 140px;
}
.tile {
width: 128px;
height: 87px;
}
.tile:first-child,
.bush:last-child {
grid-column-start: 1;
grid-column-end: 3;
width: 100%;
}
.grass {
background-image: url("https://i.stack.imgur.com/39MxJ.png");
background-position: center center;
background-repeat: no-repeat;
background-size: auto;
}
.bush {
height: 128px;
background-image: url("https://i.stack.imgur.com/GpNEI.png");
background-position: center center;
background-repeat: no-repeat;
background-size: auto;
margin-top: -52px;
}
<div class="container">
<div class="tile grass"></div>
<div class="tile bush"></div>
<div class="tile grass"></div>
<div class="tile bush"></div>
</div>
CodePudding user response:
You have to reposition each tile separately with a hit and trial method like in below snippet: Below snippet is for demo only you can reposition according to need and wherever you want in blue are
.container {
width: 256px;
height: 256px;
transform: rotateX(60deg) rotateZ(45deg);
display: flex;
flex-wrap: wrap;
background-color: blue;
}
.tile {
width: 128px;
}
.tile:nth-child(1) {
transform: translateX(64px) translateY(64px) rotateX(0deg) rotateZ(-45deg);
}
.tile:nth-child(2) {
transform: translateX(0) translateY(42px) rotateX(0deg) rotateZ(-45deg);
}
.tile:nth-child(3) {
transform: translateX(16px) translateY(-18px) rotateX(0deg) rotateZ(-45deg);
}
.tile:nth-child(4) {
transform: translateX(-45px) translateY(-42px) rotateX(0deg) rotateZ(-45deg);
}
.grass {
height: 64px;
background-image: url("https://i.stack.imgur.com/39MxJ.png");
}
.bush {
height: 128px;
background-image: url("https://i.stack.imgur.com/GpNEI.png");
}
<div class="container">
<div class="tile grass"></div>
<div class="tile grass"></div>
<div class="tile bush"></div>
<div class="tile bush"></div>
</div>