Методы выравнивания дивов после их преобразования? - PullRequest
0 голосов
/ 23 февраля 2020

У меня есть куча <div> s, служащих панелями обзора windows для пользователей на выбор. Они должны быть выровнены и должны оставаться в определенном промежутке между собой.

Я пытался использовать следующие методы для достижения этой цели:

1) установить значение perspective для их общего родителя , а затем используйте transform: translateZ, чтобы они выглядели меньше, и отправьте их назад. Только выбранный div будет преобразован обратно в 0 и будет выглядеть в нормальном размере, а остальные останутся преобразованными.

проблема: невозможно автоматически выровнять после преобразования.

2) установить display значение их общего родителя для flex, таким образом выровняйте все div. Выбранный div масштабируется до большего размера.

проблема: не выглядит 3d. визуально некрасиво и не помогает с когнитивной нагрузкой.

Я все еще предпочитаю метод 1), но как я могу выровнять эти элементы после их преобразования?

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>

1 Ответ

2 голосов
/ 24 февраля 2020

Вам не нужно go 3D, чтобы получить хороший эффект. Использование макета flexbox для удобного размещения и позиционирования дочерних элементов и простого transform: scale(...) уже сделает большую разницу без JS. Добавьте немного конфет, и вы получите что-то вроде сниппета (действительно нужно go полная страница).

ОБНОВЛЕНИЕ Моя мотивация к go 'flexbox' в любом случае является фактом что вы на самом деле дали маленький код для начала. Кроме того, хотя у меня есть быстрый P C, быстрый GPU и стекловолокно 200-500 Мбит, это не так для многих других людей. Создание веб-страницы с интенсивным использованием CPU / GPU может в конечном итоге откусить вас за хвост, поскольку они имеют тенденцию к медлительности sh, дрожанию или слишком медленному (не говоря уже, чрезмерно сложному).

Я предпочитаю выбирать самый короткий маршрут от A до B, компактный код и только минимально необходимый (и совместимый с IE11. Если он работает на IE11, он работает где угодно).

Итак, посмотрите на этот ответ как на отправную точку и настройте базовый механизм так, чтобы удовлетворить ваши потребности и изменить глаз конфеты так же. Вы всегда можете прибегнуть к JS, когда вам нужно.

ОБНОВЛЕНИЕ 2

Модифицированный код, теперь включает 3D-макет с некоторым эффектом 3D-наведения. Родители и дети являются контейнерами Flexbox, поэтому вы можете делать что угодно внутри FBL. 3D-макет остается.

ЗАМЕЧАНИЕ: пропущен ваш первый комментарий: добавлено transform: scale(0.5) к дочерним элементам ...

Pro TIPS

1) В результате трехмерного эффекта может случиться так, что дочерние элементы получат зубчатые (не сглаженные) края. Если это так, попробуйте добавить прозрачный контур к дочерним элементам, например .container>* { ... outline: 1px solid transparent ... }. Это как-то заставляет сглаживать края. Осторожно: обычный контур не будет виден, «слабовидящих» может не позабавить ...

2) Добавлено несколько кнопок, вызывающих простой однострочный JS для переключения «пользовательских атрибутов» для цели тестирования.

Также добавлен общий c отзывчивый запас страницы с использованием «линейного уравнения y = mx + b»

  • для точек p1 (320,64) p2 (1920) , 144) (расстояние сверху / снизу) и
  • для точек p1 (320,8) p2 (1920,320) (расстояние слева / справа).

3) Наверх выключено: отзывчивый html размер шрифта варьируется от 14 до 20 пикселей, а также 'y = mx + b' для точек p1 (320,14) p2 (1280,20).

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>
...