Search code examples
css-grid

CSS Grid breakout for page title


I am using a css grid (previously been using flexbox) and I am trying to work out how to break out of a css grid for my page title. My site structure looks like this:

site-structure

Here is the css:

.site {
  column-gap: $sidebar-gap;
  display: grid;
  grid-template-columns: auto ($sidebar-width);   // site structure
  grid-template-rows: auto 1fr auto;              // sticky header & footer
  grid-template-areas:
    "header header"
    "main sidebar"
    "footer footer";
}

header {
  grid-area: header;
}

.site-main {
  grid-area: main;
}

.widget-area {
  grid-area: sidebar;
}

footer {
  grid-area: footer;
}

My HTML structure looks like this:

body
└── div (#page .site)
    ├── header (#masthead .site-header)
    |   ├── div (.site-branding)
    |   |   ├── a (.logo)
    |   |   └── p (.site-description)
    |   ├── nav (#site-navigation .main-navigation)
    |   |   ├── button (.menu-toggle)
    |   |   ├── div (#menu-desktop-container .menu-desktop-container)
    |   |   └── div (#menu-mobile-container .menu-mobile-container)
    |   └── div (.head-search)
    |
    ├── main (#primary .site-main)
    |   └── article (.module)
    |       ├── div (.page-head)
    |       |   ├── h1 (.page-title)
    |       |   └── div (.page-meta)
    |       └── div (.page-content)
    |           └── <page content goes here>
    |
    ├── aside (#secondary .widget-area)
    |   └── <content> (section)
    |
    └── footer (#colophon .site-footer)
        ├── div (.footer-widgets)
        ├── nav (.footer-navigation)
        |   └── div (#menu-footer-container .menu-footer-container)
        └── div (.site-info)

What I am trying to achieve is the .page-head div to breakout of the css grid and span across the entire width of the page. From here I would like the sidebar (i.e. .widget-area) to commence below the .page-head. Typically in the past when using flexbox I would achieve this would using position: absolute on the .page-head which has a fixed height. I would then just add margin-top to the .widget-area to be the same as the .page-head site.

I tried this in CSS grid and this doesn't work. This is what I am trying to achieve visually:

example-of-what-I-need-to-achieve

I am not able to change the HTML structure - i.e. the obvious thing would be to move the sidebar (.widget-area) within main (.site-main), then this would be super easy to achieve. As this is a Wordpress theme, this is not possible.


Solution

  • You can do it with a grid inside a grid and this will do the job :

    enter image description here

    To be sure the layout meet your requirements I use the html of your codepen.

    Test the snippet below :

    .site {
      column-gap: 40px;
      display: grid;
      grid-template-columns: auto (25%);
      grid-template-rows: auto 3rem 1fr auto;
    }
    
    header {
      grid-row: 1;
      grid-column: 1 / 3;
    }
    
    .site-main {
      grid-row: 2 / 4;
      grid-column: 1 / 3;
    }
    
    .widget-area {
      grid-row: 3;
      grid-column: 2;
    }
    
    footer {
      grid-row: 4;
      grid-column: 1 / 3;
    }
    article {
      display: grid;
      column-gap: 40px;
      grid-template-columns: auto (25%);
      grid-template-rows: 3rem 1fr;
      width: 100%;
      height: 100%;
    }
    
    .page-head {
      grid-column: 1 / 3;
      grid-row: 1;
      text-align: center;
    }
    .page-content {
      grid-column: 1;
      grid-row: 2;
    }
    .site {
      padding: 0 10px;  
    }
    
    header,
    footer {
      background-color: grey;
      color: white;
      padding: 50px 0;
      text-align: center;
    }
    
    header {
      margin-bottom: 40px;
    }
    
    footer {
      margin-top: 40px;
    }
    
    .page-content {
      border: 1px solid blue;
    }
    
    h1 {
      border: 1px solid red;
      margin: 0;
      padding: 0;
    }
    
    .widget-area {
      border: 1px solid green;
      
      .module {
        margin-bottom: 20px;
      }
    }
    <div class="site">
      <header>Header</header>
      
      <main class="site-main">
        <article class="module">
          <div class="page-head">
            <h1>Page Title</h1>
          </div>
          <div class="page-content">
          </div>
        </article>
      </main>
      
      <aside class="widget-area">
        <div class="module">Widget 1</div>
        <div class="module">Widget 2</div>
        <div class="module">Widget 3</div>
      </aside>
    
      <footer>Footer</footer>
    </div>

    Or check the Codepen here : https://codepen.io/BSO__/pen/ZEXvgXR