'HTML-CSS: How to deal with overflowing content in Grid Areas/Columns/Rows
I want to make a portfolio site and am struggling with my page creation:
The visual elements are a Header, a Sidebar, a Frame for the content and the Content itself. I already have a Grid designed with respective areas for all the elements and dynamic resizing based on the calculated dimensions of a logo in the Header.
Now I have the issue, that the Content overflows and therefore should be scrollable, however the Header and the Frame (literally a frame as from an old painting) shall not move when scrolling and always be on top.
The size of the container with the Grid is defined by the viewport and overflow is hidden. The size of the container with the Content is defined by its content and overflow is scrollable. With z-index or order of containers the Content was put on a layer below the Header and Frame. This does not work, since as soon as the layer of the scrollable Content was not on top of everything, it became not scrollable anymore. Modyfing the above layers with pointer-events: none is not possible since they contain the site navigation. Stacking a separate Grid for Content and Header/Sidebar/Frame on top of each other seemed to suffer from the same layer problem.
How shall one design a site with scrollable content beneath a fixed header in the Grid system? I would greatly appreciate the help, I promise I tried to look it up online but did not really see it discussed. This approach by Michael X for example did not work for me due to layer issues: https://medium.com/@beyondborders/beginner-css-grid-sticky-navigation-scrolling-content-7c4de0a8d1dc
I added the relevant code:
/* ////////////////////////////////////////////////////////////ROOT */
:root {
--margin-left: min(10vw, var(--max-margin-left));
--max-margin-left: 6rem;
--margin-right: min(10vw, var(--max-margin-right));
--max-margin-right: 8rem;
--margin-top: 2rem;
--margin-bottom: 2rem;
--dimensions-logo: min(20vw, var(--max-dimensions-logo));
--max-dimensions-logo: 8rem;
--padding-logo: calc(var(--dimensions-logo) / 7);
--margin-left-content: calc(var(--margin-left) + var(--dimensions-logo) + 3 * var(--padding-logo));
--margin-right-content: calc(var(--margin-right) + 2 * var(--padding-logo));
--margin-top-content: calc(var(--margin-top)) + var(--dimensions-logo) + 3 * var(--padding-logo));
--margin-bottom-content: calc(var(--margin-bottom) + 2 * var(--padding-logo));
}
*,
*::before,
*::after {
box-sizing: border-box;
}
/* ////////////////////////////////////////////////////////////HTML-ROOT */
html {
line-height: 1.15;
}
body {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
/* ////////////////////////////////////////////////////////////LAYOUT */
/* ///////////////////////////////GRID */
.layout-main {
position: relative;
width: 100vw;
height: 100vh;
display: grid;
grid-template-columns: var(--margin-left) var(--dimensions-logo) var(--padding-logo) var(--padding-logo) var(--padding-logo) 1fr var(--padding-logo) var(--padding-logo) var(--margin-right);
grid-template-rows: var(--margin-top) var(--dimensions-logo) var(--padding-logo) var(--padding-logo) var(--padding-logo) 1fr var(--padding-logo) var(--padding-logo) var(--margin-bottom);
}
.layout-content {
position: absolute;
top: var(--margin-top-content);
bottom: var(--margin-bottom-content);
overflow-y: scroll;
grid-column: 6 / 7;
grid-row: 6 / 7;
}
/* ///////////////////////////////LOGO */
.cont-logo {
grid-column: 2 / 3;
grid-row: 2 / 3;
}
.logo {
width:100%;
height: auto;
}
/* ///////////////////////////////NAVIGATION */
.cont-topheader {
grid-column: 4 / 9;
grid-row: 2 / 3
}
.cont-leftaside {
grid-column: 2 / 3;
grid-row: 4 / 7;
}
/* ///////////////////////////////FRAME */
.cont-frame {
position: relative;
grid-column: 4 / 9;
grid-row: 4 / 9;
}
.c1 {
width: var(--dimensions-logo);
height: auto;
}
.c2 {
position: absolute;
right: 0;
bottom: 0;
width: var(--dimensions-logo);
height: auto;
}
/* ///////////////////////////////BACKGROUND*/
.cont-uppergradient {
height: 100%;
background: linear-gradient(0deg, rgba(2,0,36,1) 0%, rgba(0,0,0,0) 0%, rgba(255,255,255,0.8939776594231442) 6%, rgba(255,255,255,1) 10%);
}
.cont-lowergradient {
height: 100%;
background-color: #767575;
background: linear-gradient(180deg, rgba(2,0,36,1) 0%, rgba(0,0,0,0) 0%, rgba(255,255,255,0.8939776594231442) 20%, rgba(255,255,255,1) 10%);
}
////////////////////////////////////////////////////////////NAVIGATION */
.primary-nav {
width: var(--dimensions-logo);
height: var(--dimensions-logo);
}
#primary-nav {
display: flex;
flex-direction: column;
justify-content: space-between;
width: auto;
height: 100%;
}
.primary-inf {
margin-top: var(--padding-logo);
}
#secondary-nav {
display: flex;
flex-direction: column;
justify-content: space-between;
width: auto;
height: var(--dimensions-logo);
}
.secondary-nav {
width: var(--dimensions-logo);
height: var(--dimensions-logo);
}
#secondary-nav {
width: auto;
height: 100%;
}
ul {
list-style: none;
padding-left: 0em;
}
a {
font: var(--font-family-sans-serif);
color: var(--font-navigation);
}
a:hover {
font-size: calc(var(--dimensions-logo) / 6);
}
.menu-item {
font-size: calc(var(--dimensions-logo) / 7);
text-align: center;
border-style: solid;
border-width: calc(var(--dimensions-logo) / 44);
background-color: #fff;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PAGE</title>
</head>
<body>
<div class = "layout-main">
<div class = "cont-gradient cont-uppergradient"></div>
<div class = "cont-gradient cont-lowergradient"></div>
<section class = "cont-logo">
<img class = "logo" src="link-to-logo">
</section>
<header class = "cont-topheader">
<nav class = "secondary-nav">
<?php
wp_nav_menu(
array(
'menu' => 'secondary-nav',
'container' => '',
'theme_location' => 'secondary-nav',
'items_wrap' => '<ul id="secondary-nav">%3$s</ul>',
)
);
?>
</nav>
</header>
<aside class = "cont-leftaside">
<nav class = "primary-nav">
<?php
wp_nav_menu(
array(
'menu' => 'primary-nav',
'container' => '',
'theme_location' => 'primary-nav',
'items_wrap' => '<ul id="primary-nav">%3$s</ul>',
)
);
?>
</nav>
<nav class = "primary-inf">
<?php
wp_nav_menu(
array(
'menu' => 'primary-inf',
'container' => '',
'theme_location' => 'primary-inf',
'items_wrap' => '<ul id="primary-inf">%3$s</ul>',
)
);
?>
</nav>
</aside>
<div class = "cont-heading">
<div class = "page-heading-box"><p><?php the_title(); ?></p></div>
<div class = "post-heading-box"><p><?php the_post(); ?></p></div>
</div>
<div class = "cont-frame">
<img class = "c1" src="link-to-frame-image-1"></img>
<img class = "c2" src="link-to-frame-image-2"></img>
</div>
<div class = "layout-content">
<div class = "cont-content">
<article class = "a-scrollable-article">
<p>article-testBEGINNING</p>
</div>
</div>
</div>
</body>
</html>
Solution 1:[1]
The problem with a layout of overlapping content is that elements may obstruct pointer-events so that the elements below are not interactive anymore. The fast solution is to modify the obstructing elements with pointer-events:
.body {
position: relative;
}
.element-top {
position: absolute;
pointer-events: none
}
.element-bottom {
position: absolute;
background-color: red;
}
.element-bottom:hover {
background-color: green;
}
<body>
<div class = "element-bottom">_</div>
<div class = "element-top">_</div>
</body>
However this may not always be an option - for example when there are interactive elements on the layer of the top element. In this case, a more organized layout and layering can help eliminate these conflicts: Use one main grid to assign areas for the different overlapping page-parts but make sure that only the bottom layer covers the entire viewport. Make sure that the interactive elements on the page obstruct only the place they need by confining them in subgrids.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Nimantha |
