我的基本html结构如下
我成功地使用grid-template-areals
创建了基本结构。 我面临的问题是我不能根据需要旋转每一行的瓷砖。
我已经创建了一个基本的片段,每行只有3个瓷砖。 第一行是直角,其他行的角度都不对。 90deg
用于第二行。 第三行180deg
。 第四行为270deg
。
我试过使用writing-mode
和transform:rotote()
,但都不起作用,或者我使用的方式不对。 请帮我找到正确的方法。 我会非常感激
null
*{
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>
null
这里有一个方法可以做到这一点。
我已经更改了HTML标记,并且没有使用grid-template-areals
属性。 每个网格项都按照它们在HTML标记中的顺序自动放置在网格中。
它是一个4x4
网格,第一列和最后一列的大小为120px,中间两列的大小为75px。 类似地,第一行和最后一行的大小为120px,中间2行的大小为75px。
为了旋转网格项目,我已经创建了单独的类,并在需要旋转的单独网格项目上应用了适当的旋转类。
null
* {
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>
我喜欢你的问题,为了解决这个问题,我结合了“transform:rotote()”和“writing-mode:vertical-rl”,我旋转了角的标题以保持对角线!
我刚刚更改了CSS中最后两条注释下面的内容:
null
*{
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>
由于这个问题是用#JavaScript标记的,而且目前没有使用它的答案,所以我决定尝试一下。
我假设你的目标是做一个交互式棋盘游戏,所以没有回避JS。
如果您的目标只是呈现这样的网格,我还尝试了几乎完全在CSS中实现它--这意味着只有一堆没有任何类或ID的div,然后主要基于:nth-child()伪类来设置网格。
null
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>