转换后对齐 div 的方法?
Methods to align divs after transforming them?
我有一堆<div>
作为概览图块windows供用户选择。它们需要对齐并在彼此之间保持一定的间隙。
我尝试了以下方法来达到这个目的:
1) 给它们共同的parent设置一个perspective
值,然后用transform: translateZ
让它们看起来更小,向后发送。只有选定的 div
将被转换回 0 并以正常大小显示,其余的保持变形。
问题:变形后无法自动对齐
2) 将它们的公共父级的display
值设置为flex
,从而对齐所有div。所选 div
将缩放到更大的尺寸。
问题:看起来不是 3d。视觉上很丑陋,对认知负荷没有帮助。
我还是比较喜欢 1) 的方法,但是转换后如何对齐这些 div?
div#container {
perspective: 200px;
position: relative;
}
div.window {
transform: translateZ(-150px);
position: absolute;
}
div#window-1 {
left: 10px;
}
div#window-2 {
left: 110px;
}
<div id="container">
<div id="window-1" class="window">test</div>
<div id="window-2" class="window">test2</div>
<div id="window-3" class="window">test3</div>
<div id="window-4" class="window">test4</div>
<div id="window-5" class="window">test5</div>
</div>
你真的不需要去 3D 来获得一些不错的效果。使用 flexbox 布局来轻松布局和定位 child 元素和一个简单的 transform: scale(...)
已经有很大的不同,没有任何 JS。添加一些 eye-candy,您将得到类似代码片段的内容(真的需要整页)。
更新
无论如何,我去 'flexbox' 的动机是你实际上只提供了很少的代码开始。此外,虽然我个人拥有高速 PC、快速 GPU 和 fiber-glass 200-500Mbit 连接,但对很多其他人来说并非如此。创建一个 CPU/GPU 密集型网页最终可能会咬你的尾巴,因为它们往往会变得迟钝、抖动或非常缓慢(更不用说,过于复杂)。
我更喜欢从 A 到 B 的最短路线,紧凑的代码,只需要最低限度的要求(和 IE11 兼容。如果它在 IE11 上运行,它可以在任何地方运行)。
所以,以这个答案为起点,调整基本机制以满足您的需要,并同样修改 eye-candy。当你需要的时候,你可以随时求助于 JS。
更新 2
修改了代码,现在合并了 3D 布局和一些 3D 悬停效果。 parent 和 kids 都是 Flexbox 容器,所以你可以在里面做任何 FBL。保留 3D 布局。
备注:错过了您的第一条评论:已将 transform: scale(0.5)
添加到 child 元素...
专业提示
1) 由于 3D 效果,child 元素可能会出现锯齿状 (non-aliased) 边缘。如果是这样,请尝试向 child 元素添加一个 transparent 轮廓,例如 .container>* { ... outline: 1px solid transparent ... }
。这以某种方式迫使边缘 anti-aliassing 。注意:常规轮廓将不可见,'visually impaired'可能不会被逗乐...
2) 添加了一些按钮调用简单的 one-liner JS 来切换 'custom attributes' 用于测试目的。
还使用 'linear equation y=mx+b'
添加了通用的响应式页边距
- 对于点 p1(320,64) p2(1920,144)(top/bottom 间距)和
- 对于点 p1(320,8) p2(1920,320)(left/right 间距)。
3) 最重要的是:响应式 html 字体大小从 14px 到 20px 不等,对于点 p1(320,14) p2(1280,20).'y=mx+b'。
var body = document.body;
function toggleBodyAttrib(a) { if (body.getAttribute(a)=='1') body.setAttribute(a,'0'); else body.setAttribute(a,'1'); }
html,body { box-sizing: border-box } /* size calculations up to and including border */
*::before,*::after, * { box-sizing: inherit } /* use parental calculation preference */
html,body { width: 100%; max-width: 100%; margin: 0 } /* personal prefs */
body { min-height: 100% } /* fill screen */
/* responsive main fontsize, y=mx+b: for p1(320,14) p2(1280,20) */
html { font-size: calc(0.625vmin + 0.75rem) } /* 14px to 20px */
/*
responsive <body> padding
y=mx+b for points:
T/B: p1(320,64) p2(1920,144) => y = 0.5x + 48 (64px on a 320 display, 144px on 1920)
L/R: p3(320, 8) p4(1920,320) => y = 0.195x - 54.4 ( 8px on a 320 display, 320px on 1920)
*/
[padded="1"] { padding: calc(5vh + 48px) calc(19.5vw - 54.4px) }
[debug="1"] * { outline: 1px dashed purple }
[debug] #buttonList *,
[debug] #buttonList { outline: none } /* exceptions to the rule above */
#buttonList { position: fixed; top: 1rem; left: 1rem } /* keep them in place */
.container {
/* UPDATE: 3D definitions */
position: relative; /* create stacking context */
transform: perspective(400px) rotateX(20deg); /* Starwars */
perspective-origin: center center; /* center looks most straight */
transform-style: preserve-3d; /* Kids must maintain 3D look */
display: flex; /* default Flexbox layout: row of columns */
flex-wrap: wrap; /* wrap to next line when no more space */
justify-content: space-between; /* evenly distribute inside given space */
width : 50%; /* some preferred with */
/* padding: 1rem; /* inner spacing (obsolete: now using <body padded="1">) */
margin : 0 auto; /* center container horizontally */
cursor : default;
}
/* UPDATE 3D hover preps */
.container:hover>* {
perspective: 500px; /* higher value means a `more straight view` */
/* try 200px and 2000px */
transition: all 100ms ease-in-out; /* some delay prevents element jitter/flicker */
/* too slow for IE11 (can see swap from z-index 1 to z-index 2) */
}
.container>* { /* or .container>.window, but this is more generic */
/* UPDATE needs z positioning */
z-index: 1;
display: flex; /* ditto */
justify-content: center; /* fbl center content in window */
align-items: center;
min-width : 5rem; /* preferred size, square */
min-height: 5rem;
margin : -0.75rem; /* some negative margin to compensate 50% scale */
transform: scale(0.5); /* scale down 50% */
/* eye-candy */
background-color: white;
border: 1px solid rgba(0,0,0,.1);
border-radius: 3px;
box-shadow: 0px 2px 1px -1px rgba(0,0,0,.20),
0px 1px 1px 0px rgba(0,0,0,.14),
0px 1px 3px 0px rgba(0,0,0,.12); /* GMC elevation 1dp */
}
.container>:hover {
/* UPDATE added 3D transitions */
z-index: 2;
transform: scale(1.2) rotateX(-20deg) translateZ(50px);
/* eye-candy */
background-color: CornflowerBlue;
box-shadow: 0px 3px 5px -1px rgba(0,0,0,.2),
0px 5px 8px 0px rgba(0,0,0,.14),
0px 1px 14px 0px rgba(0,0,0,.12); /* GMC elevation 5dp */
}
/* back to normal size when 'click and hold' */
.container>:active { transform: scale(1) }
<body padded="1">
<div id="buttonList">
toggles:
<button onclick="toggleBodyAttrib('padded')">padding</button>
<button onclick="toggleBodyAttrib('debug')" >debug </button>
<!-- add your own custom debugging [attribute] toggles -->
</div>
<div class="container">
<div>test1</div>
<div>test2</div>
<div>test3</div>
<div>test4</div>
<div>test5</div>
<div>test6</div>
<div>test7</div>
<div>test8</div>
<div>test9</div>
<div>test10</div>
<div>test11</div>
<div>test12</div>
<div>test13</div>
<div>test14</div>
<div>test15</div>
<div>test16</div>
<div>test17</div>
<div>test18</div>
<div>test19</div>
<div>test20</div>
<div>test21</div>
<div>test22</div>
<div>test23</div>
<div>test24</div>
<div>test25</div>
<div>test26</div>
<div>test27</div>
<div>test28</div>
<div>test29</div>
<div>test30</div>
<div>test31</div>
<div>test32</div>
<div>test33</div>
</div>
</body>
我有一堆<div>
作为概览图块windows供用户选择。它们需要对齐并在彼此之间保持一定的间隙。
我尝试了以下方法来达到这个目的:
1) 给它们共同的parent设置一个perspective
值,然后用transform: translateZ
让它们看起来更小,向后发送。只有选定的 div
将被转换回 0 并以正常大小显示,其余的保持变形。
问题:变形后无法自动对齐
2) 将它们的公共父级的display
值设置为flex
,从而对齐所有div。所选 div
将缩放到更大的尺寸。
问题:看起来不是 3d。视觉上很丑陋,对认知负荷没有帮助。
我还是比较喜欢 1) 的方法,但是转换后如何对齐这些 div?
div#container {
perspective: 200px;
position: relative;
}
div.window {
transform: translateZ(-150px);
position: absolute;
}
div#window-1 {
left: 10px;
}
div#window-2 {
left: 110px;
}
<div id="container">
<div id="window-1" class="window">test</div>
<div id="window-2" class="window">test2</div>
<div id="window-3" class="window">test3</div>
<div id="window-4" class="window">test4</div>
<div id="window-5" class="window">test5</div>
</div>
你真的不需要去 3D 来获得一些不错的效果。使用 flexbox 布局来轻松布局和定位 child 元素和一个简单的 transform: scale(...)
已经有很大的不同,没有任何 JS。添加一些 eye-candy,您将得到类似代码片段的内容(真的需要整页)。
更新 无论如何,我去 'flexbox' 的动机是你实际上只提供了很少的代码开始。此外,虽然我个人拥有高速 PC、快速 GPU 和 fiber-glass 200-500Mbit 连接,但对很多其他人来说并非如此。创建一个 CPU/GPU 密集型网页最终可能会咬你的尾巴,因为它们往往会变得迟钝、抖动或非常缓慢(更不用说,过于复杂)。
我更喜欢从 A 到 B 的最短路线,紧凑的代码,只需要最低限度的要求(和 IE11 兼容。如果它在 IE11 上运行,它可以在任何地方运行)。
所以,以这个答案为起点,调整基本机制以满足您的需要,并同样修改 eye-candy。当你需要的时候,你可以随时求助于 JS。
更新 2
修改了代码,现在合并了 3D 布局和一些 3D 悬停效果。 parent 和 kids 都是 Flexbox 容器,所以你可以在里面做任何 FBL。保留 3D 布局。
备注:错过了您的第一条评论:已将 transform: scale(0.5)
添加到 child 元素...
专业提示
1) 由于 3D 效果,child 元素可能会出现锯齿状 (non-aliased) 边缘。如果是这样,请尝试向 child 元素添加一个 transparent 轮廓,例如 .container>* { ... outline: 1px solid transparent ... }
。这以某种方式迫使边缘 anti-aliassing 。注意:常规轮廓将不可见,'visually impaired'可能不会被逗乐...
2) 添加了一些按钮调用简单的 one-liner JS 来切换 'custom attributes' 用于测试目的。
还使用 'linear equation y=mx+b'
添加了通用的响应式页边距- 对于点 p1(320,64) p2(1920,144)(top/bottom 间距)和
- 对于点 p1(320,8) p2(1920,320)(left/right 间距)。
3) 最重要的是:响应式 html 字体大小从 14px 到 20px 不等,对于点 p1(320,14) p2(1280,20).'y=mx+b'。
var body = document.body;
function toggleBodyAttrib(a) { if (body.getAttribute(a)=='1') body.setAttribute(a,'0'); else body.setAttribute(a,'1'); }
html,body { box-sizing: border-box } /* size calculations up to and including border */
*::before,*::after, * { box-sizing: inherit } /* use parental calculation preference */
html,body { width: 100%; max-width: 100%; margin: 0 } /* personal prefs */
body { min-height: 100% } /* fill screen */
/* responsive main fontsize, y=mx+b: for p1(320,14) p2(1280,20) */
html { font-size: calc(0.625vmin + 0.75rem) } /* 14px to 20px */
/*
responsive <body> padding
y=mx+b for points:
T/B: p1(320,64) p2(1920,144) => y = 0.5x + 48 (64px on a 320 display, 144px on 1920)
L/R: p3(320, 8) p4(1920,320) => y = 0.195x - 54.4 ( 8px on a 320 display, 320px on 1920)
*/
[padded="1"] { padding: calc(5vh + 48px) calc(19.5vw - 54.4px) }
[debug="1"] * { outline: 1px dashed purple }
[debug] #buttonList *,
[debug] #buttonList { outline: none } /* exceptions to the rule above */
#buttonList { position: fixed; top: 1rem; left: 1rem } /* keep them in place */
.container {
/* UPDATE: 3D definitions */
position: relative; /* create stacking context */
transform: perspective(400px) rotateX(20deg); /* Starwars */
perspective-origin: center center; /* center looks most straight */
transform-style: preserve-3d; /* Kids must maintain 3D look */
display: flex; /* default Flexbox layout: row of columns */
flex-wrap: wrap; /* wrap to next line when no more space */
justify-content: space-between; /* evenly distribute inside given space */
width : 50%; /* some preferred with */
/* padding: 1rem; /* inner spacing (obsolete: now using <body padded="1">) */
margin : 0 auto; /* center container horizontally */
cursor : default;
}
/* UPDATE 3D hover preps */
.container:hover>* {
perspective: 500px; /* higher value means a `more straight view` */
/* try 200px and 2000px */
transition: all 100ms ease-in-out; /* some delay prevents element jitter/flicker */
/* too slow for IE11 (can see swap from z-index 1 to z-index 2) */
}
.container>* { /* or .container>.window, but this is more generic */
/* UPDATE needs z positioning */
z-index: 1;
display: flex; /* ditto */
justify-content: center; /* fbl center content in window */
align-items: center;
min-width : 5rem; /* preferred size, square */
min-height: 5rem;
margin : -0.75rem; /* some negative margin to compensate 50% scale */
transform: scale(0.5); /* scale down 50% */
/* eye-candy */
background-color: white;
border: 1px solid rgba(0,0,0,.1);
border-radius: 3px;
box-shadow: 0px 2px 1px -1px rgba(0,0,0,.20),
0px 1px 1px 0px rgba(0,0,0,.14),
0px 1px 3px 0px rgba(0,0,0,.12); /* GMC elevation 1dp */
}
.container>:hover {
/* UPDATE added 3D transitions */
z-index: 2;
transform: scale(1.2) rotateX(-20deg) translateZ(50px);
/* eye-candy */
background-color: CornflowerBlue;
box-shadow: 0px 3px 5px -1px rgba(0,0,0,.2),
0px 5px 8px 0px rgba(0,0,0,.14),
0px 1px 14px 0px rgba(0,0,0,.12); /* GMC elevation 5dp */
}
/* back to normal size when 'click and hold' */
.container>:active { transform: scale(1) }
<body padded="1">
<div id="buttonList">
toggles:
<button onclick="toggleBodyAttrib('padded')">padding</button>
<button onclick="toggleBodyAttrib('debug')" >debug </button>
<!-- add your own custom debugging [attribute] toggles -->
</div>
<div class="container">
<div>test1</div>
<div>test2</div>
<div>test3</div>
<div>test4</div>
<div>test5</div>
<div>test6</div>
<div>test7</div>
<div>test8</div>
<div>test9</div>
<div>test10</div>
<div>test11</div>
<div>test12</div>
<div>test13</div>
<div>test14</div>
<div>test15</div>
<div>test16</div>
<div>test17</div>
<div>test18</div>
<div>test19</div>
<div>test20</div>
<div>test21</div>
<div>test22</div>
<div>test23</div>
<div>test24</div>
<div>test25</div>
<div>test26</div>
<div>test27</div>
<div>test28</div>
<div>test29</div>
<div>test30</div>
<div>test31</div>
<div>test32</div>
<div>test33</div>
</div>
</body>