Используя flexbox, как наложить изображение и развернуть его, чтобы заполнить родительский контейнер - PullRequest
1 голос
/ 07 мая 2020

В следующем html я хочу, чтобы div txt-box был центрирован в контейнере, перекрывал изображение и расширялся, чтобы заполнить контейнер. У него должно быть поле одинаковой ширины со всех сторон, чтобы часть изображения отображалась как толстая граница.

Показанный html подходит для того, что я хочу, за исключением того, что вертикальные и горизонтальные поля всегда немного изменяется при изменении размера окна браузера.

Мне кажется, что у меня есть взлом и что я использую flex-grow неправильно. Я понимаю, что flex-grow позволяет расширять txt-box div, поскольку это единственный элемент с увеличивающимся значением. Если я смогу решить эту проблему, я смогу просто установить маржу на txt-box, и это должно сработать.

Что я не понимаю по поводу flex-grow?

.container {
  display: flex;
  align-items: center;
  justify-content: center;
  border: solid 2px red;
  position: relative;
}

.container img {
  width: 100%;
  flex-grow: 0;
  flex-shrink: 0;
}

.txt-box {
  background-color: white;
  display: flex;
  padding: 5px;
  border: solid 2px blue;
  flex-grow: 1;
  position: absolute;
  width: 90%;
  height: 80%;
}
<div class="container">
  <img src="blocks.png" />
  <div class="txt-box">
    hello world
  </div>
</div>

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Спасибо Майклу Бенджамину за то, что он поставил меня на путь просветления. Я наконец понял это. Мой первоначальный вопрос был частью того, что я пытался выполнить sh. Ответы: используйте background-image:url('...') и убедитесь, что элементы таблицы и строки display:flex.

JSFiddle

<html>
<head>
    <style>

        .flex-table {
            flex-flow:column;
        }

        .flex-row {
            flex-flow:row;
        }

        .container {
            align-items: center;
            justify-content: center;
            padding: 20px;
            border: solid 2px red;
            background-image:url('https://i.imgur.com/BF3ty6o.jpg');
            background-size:cover;
            background-repeat:no-repeat;
            max-width:500px;
        }

        .txt-box {
            justify-self:stretch;
            align-self:stretch;
            border: solid 2px blue;
            background-color: rgba(192,192,192,0.5);
        }


        body, .flex-table, .flex-row, .container, .txt-box  {
            display:flex;
            flex-grow:1;
        }

        @media (max-width: 768px) {
            .flex-row {
                flex-flow:column;
            }
        }

    </style>

</head>
<body>

<div class="flex-table">
    <div class="flex-row">
        <div class="container">
            <div class="txt-box">
                hello world 1
            </div>
        </div>

        <div class="container">
            <div class="txt-box">
                hello world 2
            </div>
        </div>

        <div class="container">
            <div class="txt-box">
                hello world 3
            </div>
        </div>
    </div>


    <div class="flex-row">
        <div class="container">
            <div class="txt-box">
                hello world 4
            </div>
        </div>

        <div class="container">
            <div class="txt-box">
                hello world 5
            </div>
        </div>

        <div class="container">
            <div class="txt-box">
                hello world 6
            </div>
        </div>
    </div>
</div>
</body>

</html>
0 голосов
/ 07 мая 2020

Что я не понимаю в flex-grow?

Свойства Flex не работают с абсолютно позиционированными дочерними элементами гибкого контейнера.

§ 4.1. Абсолютно позиционированные дочерние элементы гибкого контейнера

Поскольку он находится вне потока, абсолютно позиционированный дочерний элемент гибкого контейнера не участвует в гибком макете.

Следовательно, flex-grow: 1 на txt-box ничего не делает. Это просто игнорируется.

Учитывая, что вы хотите, чтобы изображение просто лежало на заднем плане, а к текстовому полю предъявляются дополнительные требования, я бы предложил абсолютно позиционировать изображение и оставить текстовое поле в обычном порядке.

Затем задайте ширину и высоту текстового поля с равным заполнением на основном контейнере, чтобы сохранить одинаковые «поля» для всех размеров экрана.

Вот демонстрация с несколькими дополнительными функциями, помогающими проиллюстрировать задействованные концепции.

 body {
   height: 100vh;   
   display: flex;
   margin: 0;
   padding: 10px;
 }
 
 .container {
   flex-grow: 1;
   display: flex;
   align-items: center;
   justify-content: center;
   padding: 20px;
   position: relative;
   border: solid 2px red;
 }
 
 img {
   position: absolute;
   height: 100%;
   width: 100%;
   object-fit: contain; /* also try 'cover' for demo */
 }

 .txt-box {
   z-index: 1;
   width: 100%;
   height: 100%;
   border: solid 2px blue;
   background-color: rgba(192,192,192,0.5);
 }
  
 * {
   box-sizing: border-box;
 }
<div class="container">
  <img src="http://i.imgur.com/60PVLis.png">
  <div class="txt-box">hello world</div>
</div>

jsFiddle demo

...