Вертикально центрируйте поле внутри контейнера, пока оно не достигнет предела

#html #css #flexbox #responsive-design #css-grid

#HTML #css #flexbox #адаптивный дизайн #css-сетка

Вопрос:

Вот диаграмма:

диаграмма

Я пытаюсь создать веб-страницу с баннером (серая рамка) высотой 80vh (когда это возможно).

Этот баннер содержит div с текстом внутри (синее поле), который должен быть центрирован по вертикали внутри этого баннера.

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

Как я могу получить макет, в котором синее поле центрировано по вертикали, но оно не может пересекать меню навигации (розовая линия) и в котором баннер (серое поле) не может быть меньше высоты синего поля высоты меню навигации?

Хотел бы я получить этот результат только в CSS.

Вот код с частичным макетом:

 html, body {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.banner {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: url("https://picsum.photos/id/1015/1920/1080");
  height: 80vh;
  min-height: 100px; /*   the box inside :( */
}

nav {
  position: absolute;
  top: 0;
  width: 100%;
  border-bottom: solid 4px #f5989d;
  height: 100px;
}

nav ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

nav li {
  float: left;
}

nav a {
  display: inline-block;
  color: white;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  font-size: 18px;
}

.content {
  font-size: 18px;
  color: white;
  text-align: center;
  max-width: 400px;
  padding: 20px;
  background: #6dcff6dd;
  border: solid 1px black;
}  
 <section class="banner">
  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">Products</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>
  <div class="content">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
  </div>
</section>  

Ответ №1:

Не уверен, возможно ли выполнить все требования только с помощью CSS, поэтому вот попытка с почти всеми требованиями (отсутствует только последнее). Я просто рассмотрю position:sticky

 html, body {
  margin: 0;
  padding: 0;
}
* {
  box-sizing: border-box;
}


.banner {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: url("https://picsum.photos/id/1015/1920/1080");
  height: 80vh;
  min-height: 100px; /*   the box inside :( */
}

nav {
  position: absolute;
  top: 0;
  width: 100%;
  border-bottom: solid 4px #f5989d;
  height: 100px;
}

nav ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

nav li {
  float: left;
}

nav a {
  display: inline-block;
  color: white;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  font-size: 18px;
}

.content {
  font-size: 18px;
  color: white;
  text-align: center;
  max-width: 400px;
  padding: 20px;
  background: #6dcff6dd;
  border: solid 1px black;
  /* the trick start here */
  position:sticky;
  top:100px;
  margin:-100px auto;
}  
 <section class="banner">
  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">Products</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>
  <div class="content">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
  </div>
</section>  

Вы можете визуально взломать последнее требование, как показано ниже:

 html, body {
  margin: 0;
  padding: 0;
}  
* {
  box-sizing: border-box;
}

.banner {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: url("https://picsum.photos/id/1015/1920/1080") fixed;
  height: 80vh; 
  min-height: 100px; /*   the box inside :( */
}

nav {
  position: absolute;
  top: 0;
  width: 100%;
  z-index:2;
  border-bottom: solid 4px #f5989d;
  height: 100px;
}

nav ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

nav li {
  float: left;
}

nav a {
  display: inline-block;
  color: white;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  font-size: 18px;
}

.content {
  font-size: 18px;
  color: white;
  text-align: center;
  max-width: 400px;
  padding: 20px;
  background: #6dcff6dd;
  border: solid 1px black;
  /* the trick start here */
  position:sticky;
  top:100px;
  margin:-100px auto;
  transform-style:preserve-3d;
}

.content::before {
   content:"";
   position:absolute;
   bottom:-2px;
   top:0;
   left:-50vw;
   right:-50vw;
   background: url("https://picsum.photos/id/1015/1920/1080") fixed;
   transform:translateZ(-1px);
}

body  {
  overflow-x:hidden;
}  
 <section class="banner">
  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">Products</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>
  <div class="content">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
  </div>
</section>  

Комментарии:

1. Первое решение работает хорошо, если я не добавляю содержимое после баннера и не прокручиваю. Возможно ли это с .content элементом с position:relative или position:absolute ? Второе решение очень хакерское и ломается в Firefox.