Переместить div на 50% своей высоты - PullRequest
2 голосов
/ 21 февраля 2020

TL; DR: Вы можете переместить деление на 50% от его собственной высоты и при этом остальная часть потока документов будет находиться прямо под ним?


Я должен сделать макет, в котором есть серия изображений (фиксированное соотношение ширины и высоты) с подписями (переменная длина текста).

Я Я уверен, что мне нужно использовать flex или grid . Вот ограничения, которые указывают на контейнер display: flex с display: flex||grid дочерними элементами:

  1. Фиксированное количество элементов в строке, даже если ширина экрана может варьироваться
  2. Ящики, содержащие заголовок тексты одной и той же строки должны иметь одинаковую высоту, даже если текст имеет переменную длину.
  3. Если строка не заполнена изображениями, меньшее количество изображений должно быть отцентрировано (т. е. родитель может t be grid).

Вот кикер :

Подписи должны быть вертикально центрированы вокруг нижней части соответствующих изображений. (Точно так же, как в приведенном ниже фрагменте, когда включен transform.)

Почему translateY не может работать : это было бы легко сделать с translateY(-50%) (см. Фрагмент ниже), но тогда я не могу контролировать вертикальный интервал между двумя строками изображений. Если из-за переменной длины заголовков поля заголовков в строке имеют высоту 100px, у меня будет поле в 50px ниже этой строки, если в следующем ряду поля заголовков будут иметь высоту только 80px, поле ниже этого будет 40px. .. Я пытаюсь получить постоянный запас ниже каждого ряда.

Фрагмент : макет правильный. Когда translateY имеет значение , разрешено , подписи должным образом располагаются относительно их соответствующих изображений. Когда translateY равно отключено , можно определить расстояние по вертикали между рядами изображений. Я буду sh делать оба.

body {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
}
section {
    box-sizing: border-box;
    width: calc(100% / 3);
    display: flex;
    flex-direction: column;
}
.img {
    background: center / cover no-repeat url(https://cdn.pixabay.com/photo/2020/02/16/20/29/new-york-4854718_1280.jpg)
}
.img::before {
    content: '';
    display: block;
    padding-bottom: 65%;
}
.text {
    background-color: rgba(255, 255, 255, .8);
    box-shadow: inset 0 0 0 1px red;
    flex: 1;
    transform: translateY(-50%);
}
<section>
    <div class="img"></div>
    <div class="text"><span>Convallis cursus ornare mus luctus varius fusce tempus arcu quisque</span></div>
</section>
<section>
    <div class="img"></div>
    <div class="text"><span>Eleifend lorem facilisis dictumst phasellus aenean conubia libero.</span></div>
</section>
<section>
    <div class="img"></div>
    <div class="text"><span>Nam ut gravida nisi scelerisque</span></div>
</section>
<section>
    <div class="img"></div>
    <div class="text"><span>Ligula quisque nibh class sociosqu netus laoreet interdum volutpat mus</span></div>
</section>
<section>
    <div class="img"></div>
    <div class="text"><span>Duis nec maecenas ultricies ridiculus nascetur nisi rutrum dignissim nam</span></div>
</section>

Ответы [ 2 ]

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

Как я уже говорил, я почти уверен, что это невозможно при использовании какого-либо общего свойства или макета класса c, НО мы можем взломать это.

Вот идея взлома, где Я буду полагаться на дублирование текста. Текст в потоке будет иметь высоту X, а другой текст в потоке будет иметь высоту X * 2. Текст в потоке будет определять наше визуальное расстояние со второй строкой и будет невидимым, в то время как другой будет видимым и ... проверьте приведенный ниже фрагмент, и вы все поймете:

body {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

section {
  box-sizing: border-box;
  width: calc(100% / 3);
  display: flex;
  flex-direction: column;
}

.img {
  background: center / cover no-repeat url(https://cdn.pixabay.com/photo/2020/02/16/20/29/new-york-4854718_1280.jpg)
}

.img::before {
  content: '';
  display: block;
  padding-bottom: 65%;
}

.text {
  background-color: rgba(255, 255, 255, .8);
  flex: 1;
  position: relative; /* here and not inside span !!*/
}


/* The hack start here */

.text span {
  display: block;
  line-height: 0; /* reset line-height here to control it with pseudo element*/
}

.text span::before,
.text span::after {
  content: attr(data-text);
  display: block;
}

.text span::before {
  opacity: 0; /* in flow text invisible*/
  line-height: 0.65; /* will define the height X */
}

.text span::after {
  position: absolute; /* Out of the flow*/
  top: 0;
  left: 0;
  right: 0;
  height: 200%; /* Make it 2*X, where X is the height of .text defined by the content of before*/
  /* put back a normal line-height
     should be twice the one of the before but it can be slightly different to avoid some overflow */
  line-height: 1.2; 
  transform: translateY(-50%); /* Now you can translate it !*/
  /*Move the style here*/
  background-color: rgba(255, 255, 255, .8);
  box-shadow: inset 0 0 0 1px red;
  /**/
}
<section>
  <div class="img"></div>
  <div class="text"><span data-text="Convallis cursus ornare mus luctus varius fusce tempus arcu quisque"></span></div>
</section>
<section>
  <div class="img"></div>
  <div class="text"><span data-text="Eleifend lorem facilisis dictumst phasellus aenean conubia libero."></span></div>
</section>
<section>
  <div class="img"></div>
  <div class="text"><span data-text="Nam ut gravida nisi scelerisque"></span></div>
</section>
<section>
  <div class="img"></div>
  <div class="text"><span data-text="Ligula quisque nibh class sociosqu netus laoreet interdum volutpat mus"></span></div>
</section>
<section>
  <div class="img"></div>
  <div class="text"><span data-text="Duis nec maecenas ultricies ridiculus nascetur nisi rutrum dignissim nam"></span></div>
</section>
0 голосов
/ 21 февраля 2020

Можно ли использовать JavaScript в проекте?

<!DOCTYPE html>
<html>

<head>
  <title>Page Title</title>
</head>

<body>

  <style>
    body {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
    }
    
    section {
      box-sizing: border-box;
      width: calc(100% / 3);
      display: flex;
      flex-direction: column;
    }
    
    .img {
      background: center / cover no-repeat url(https://cdn.pixabay.com/photo/2020/02/16/20/29/new-york-4854718_1280.jpg)
    }
    
    .img::before {
      content: '';
      display: block;
      padding-bottom: 65%;
    }
    
    .text div {
      background-color: rgba(255, 255, 255, .8);
      box-shadow: inset 0 0 0 1px red;
      flex: 1;
    }
  </style>

  <section>
    <div class="img"></div>
    <div class="text">
      <div>Convallis cursus ornare mus luctus varius fusce tempus arcu quisque. Convallis cursus ornare mus luctus varius fusce tempus arcu quisque.</div>
    </div>
  </section>
  <section>
    <div class="img"></div>
    <div class="text">
      <div>Eleifend lorem facilisis dictumst phasellus aenean conubia libero.</div>
    </div>
  </section>
  <section>
    <div class="img"></div>
    <div class="text">
      <div>Nam ut gravida nisi scelerisque</div>
    </div>
  </section>
  <section>
    <div class="img"></div>
    <div class="text">
      <div>Ligula quisque nibh class sociosqu netus laoreet interdum volutpat mus</div>
    </div>
  </section>
  <section>
    <div class="img"></div>
    <div class="text">
      <div>Duis nec maecenas ultricies ridiculus nascetur nisi rutrum dignissim nam</div>
    </div>
  </section>

  <script>
    const text = document.querySelectorAll('.text div');
    const textLen = text.length;

    for (let i = 0; i < textLen; i += 1) {
      text[i].style.marginTop = '-' + (text[i].scrollHeight / 2) + 'px';
    }
  </script>

</body>

</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...