Как избежать перекрытия при назначении двум элементам одной и той же области сетки CSS?

У меня есть разметка со следующей структурой. Я хотел бы иметь адаптивный макет с тремя точками останова, который работает следующим образом:

  • Большое окно просмотра, три столбца:
    ".......  nav      ........"
    "toc-pkg  preamble toc-page"
    "toc-pkg  content  toc-page"
    
  • Среднее окно просмотра, две колонки, в области сетки toc находятся toc-page и toc-pkg. следующие друг за другом:
    " nav      ..." 
    " preamble toc"
    " content  toc"
    
  • Узкая область просмотра, одна колонка:
    " nav      "
    " preamble " 
    " toc-page " 
    " content  " 
    " toc-pkg  " 
    

Хотя легко получить и первую, и третью планировку. Я не могу получить второй. Если я попытаюсь назначить оба toc-page и toc-pkg области сетки toc, они перекроются (как и ожидалось), но я бы хотел, чтобы они складывались друг в друга.

Есть ли какое-либо решение, которое включает единую структуру разметки и только CSS?

.grid>* {
  display: flex;
  justify-content: center;
  align-items: center;
}

.nav {
  height: 1em;
  background: #3C354F;
  color: white;
  grid-area: nav;
}

.toc-page {
  height: 4em;
  width: 100%;
  background: #E0695E;
  grid-area: toc-page;
}

.toc-pkg {
  height: 2em;
  width: 100%;
  background: #E0695E;
  grid-area: toc-pkg;
}

.content {
  height: 10em;
  background: #DFD4C7;
  grid-area: content;
}

.preamble {
  height: 6em;
  background: #F3F3E3;
  grid-area: preamble;
}

.tocs {
  display: flex;
  grid-area: tocs;
  flex-direction: column;
  justify-content: start;
  align-items: center
}

.grid {
  display: grid;
  gap: 1rem;
}

.grid {
  grid-template-rows: auto;
  grid-template-areas: ". nav ." "toc-page preamble toc-pkg" "toc-page content toc-pkg";
}

@media (max-width: 40em) {
  .toc-page {
    grid-area: toc;
  }
  .toc-pkg {
    grid-area: toc;
  }
  .grid {
    grid-template-rows: auto;
    grid-template-areas: "nav ." "preamble toc" "content toc";
  }
}

@media (max-width: 30em) {
  .toc-page {
    grid-area: toc-page;
  }
  .toc-pkg {
    grid-area: toc-pkg;
  }
  .grid {
    grid-template-rows: auto;
    grid-template-areas: "nav" "preamble" "toc-page" "content" "toc-pkg";
  }
}

body {
  margin: 1rem;
}
<div class = "grid medium">
  <div class = "nav">NAV</div>
  <div class = "preamble">PRE</div>
  <div class = "toc-page">TOC-PAGE</div>
  <div class = "toc-pkg">TOC-PKG</div>
  <div class = "content">TXT</div>
</div>

Вопросы, требующие помощи по коду, должны включать кратчайший код, необходимый для его воспроизведения, в самом вопросе, желательно во фрагменте стека с использованием значка <>. Несмотря на то, что вы предоставили ссылку, если она станет недействительной, ваш вопрос не будет иметь никакой ценности. другие будущие пользователи SO с той же проблемой. См. Что-то на моем сайте/примере не работает, могу я просто вставить ссылку.

Paulie_D 11.06.2024 16:07
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
1
1
62
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В нужной точке разрыва переключите поток на column и отрегулируйте области, чтобы расширить preamble на два ряда.

  .preamble {
    grid-row: span 2;
  }

  .grid {
    grid-template-rows: auto;
    grid-template-areas: 
      "nav ." 
      "preamble toc-page" 
      "preamble toc-pkg" 
      "content .";
  }

Я заменил высоту .preamble на min-height: 6em;, но это всего лишь вопрос предпочтений.

.grid>* {
  display: flex;
  justify-content: center;
  align-items: center;
}

.nav {
  height: 1em;
  background: #3c354f;
  color: white;
  grid-area: nav;
}

.toc-page {
  height: 4em;
  width: 100%;
  background: #e0695e;
  grid-area: toc-page;
}

.toc-pkg {
  height: 2em;
  width: 100%;
  background: #e0695e;
  grid-area: toc-pkg;
}

.content {
  height: 10em;
  background: #dfd4c7;
  grid-area: content;
}

.preamble {
  min-height: 6em;
  background: #f3f3e3;
  grid-area: preamble;
}

.tocs {
  display: flex;
  grid-area: tocs;
  flex-direction: column;
  justify-content: start;
  align-items: center;
}

.grid {
  display: grid;
  gap: .25rem;
}

.grid {
  grid-template-rows: auto;
  grid-template-areas: ". nav ." "toc-page preamble toc-pkg" "toc-page content toc-pkg";
}

@media (max-width: 40em) {
  .grid {
    grid-auto-flow: column;
  }
  .preamble {
    grid-row: span 2;
  }
  .toc-page {
    grid-area: toc-page;
  }
  .toc-pkg {
    grid-area: toc-pkg;
  }
  .grid {
    grid-template-rows: auto;
    grid-template-areas: "nav ." "preamble toc-page" "preamble toc-pkg" "content .";
  }
}

@media (max-width: 30em) {
  .toc-page {
    grid-area: toc-page;
  }
  .toc-pkg {
    grid-area: toc-pkg;
  }
  .grid {
    grid-template-rows: auto;
    grid-template-areas: "nav" "preamble" "toc-page" "content" "toc-pkg";
  }
}

body {
  margin: 1rem;
}
<div class = "grid medium">
  <div class = "nav">NAV</div>
  <div class = "preamble">PRE</div>
  <div class = "toc-page">TOC-PAGE</div>
  <div class = "toc-pkg">TOC-PKG</div>
  <div class = "content">TXT</div>
</div>

Это выравнивает содержание преамбулы, а это не то, чего я хочу. Однако ваш комментарий к display: contents позволяет мне решить проблему (см. jsfiddle.net/gmuyt7jb), хотите ли вы опубликовать ответ, который я принимаю? В противном случае я опубликую это.

Daniel Bünzli 11.06.2024 16:58

Вы можете опубликовать это, если хотите. Я предполагал, что вы не можете изменить HTML.

Paulie_D 11.06.2024 17:00
Ответ принят как подходящий

@Paulie_D предложил использовать display: contents (спасибо!). Настроив разметку на

<div class = "grid medium">
  <div class = "nav">NAV</div>
  <div class = "preamble">PRE</div>
  <div class = "tocs"
    <div class = "toc-page">TOC-PAGE</div>
    <div class = "toc-pkg">TOC-PKG</div>
  </div>
  <div class = "content">TXT</div>
</div>

Позволяет заставить это работать как:

.grid > * {  display: flex; justify-content: center; 
         align-items: center;  }
.nav { height: 1em; background: #3C354F; color: white; grid-area: nav; }
.toc-page { height: 4em; width: 100%; background: #E0695E; 
        grid-area: toc-page; }
.toc-pkg  { height: 2em; width: 100%; background: #E0695E; 
        grid-area: toc-pkg; }
.content { height: 10em; background: #DFD4C7; grid-area: content; }
.preamble { height: 5em; background: #F3F3E3; grid-area: preamble; }
.grid { grid-template-rows: auto; display: grid; gap: 1rem;}
.tocs { display: contents; grid-area: unset; }
.grid {
   grid-template-areas: 
 ". nav ."
 "toc-page preamble toc-pkg"
 "toc-page content toc-pkg";
 }

@media (max-width: 80em) {
  .toc-page { grid-area: unset; }
  .toc-pkg { grid-area: unset; }
  .tocs { display: block; grid-area: toc }
  .grid {
  grid-template-areas: 
"nav ."
"preamble toc"
"content toc";
}
}

@media (max-width: 60em) {
  .toc-page { grid-area: toc-page; }
  .toc-pkg { grid-area: toc-pkg; }
  .tocs { display: contents; grid-area: unset }
  .grid {
 grid-template-areas: 
  "nav"
  "preamble" 
  "toc-page"
  "content"
  "toc-pkg";
  }
}
body { margin: 1rem; }
 <div class = "grid medium">
  <div class = "nav">NAV</div>
  <div class = "preamble">PRE</div>
  <div class = "tocs">
<div class = "toc-page">TOC-PAGE</div>
<div class = "toc-pkg">TOC-PKG</div>
  </div>
  <div class = "content">TXT</div>
</div>

Другие вопросы по теме