Skip to main content

Layout & Page Structure

Page Structure

The overall page structure is controlled by src/layouts/Layout.astro. Astro uses slots to inject content from components or files.

Here is the structure (starting out at the <main id="main-content"> portion (this Layout file contains <head> and <body> tags which are irrelevant for this topic). The slots are all highlighted below. They can be named to target specific components (ie the subnav). New slots can be added as needed per project.

Note: This template contains logic to determine if this is the "homepage" or a component page, (the ICL Components/Page list) in order to alter the output on this page. The pages without the ICL Component/Page list contain the <div class="outer-pad"> wrapper.

src/layouts/Layout.astro
  <main id="main-content">
<slot name="hero" />
// Show outer-pad if not main index or a component page
{Astro.url.pathname !== '/' && !Astro.url.pathname.startsWith('/components') ? (
<div class="outer-pad">
<slot name="subnav" />
<div class="page-content">
<slot />
</div>
</div>
) : (
<>
<slot name="subnav" />
<div class="page-content">
<slot />
</div>
</>
)}
<slot name="end-of-page-cta" />
// Show site footer if not main index or a component page
{Astro.url.pathname !== '/' && !Astro.url.pathname.startsWith('/components') && <SiteFooter />}
</main>

Usage with Individual Page Templates

Pages will need to import the main layout in the frontmatter:

Page Example
---
import Layout from '../layouts/Layout.astro';
// rest of frontmatter

A named slot can be used (subnav example) as:

Page Example
<Subnav slot="subnav" subnav={data.ks_subnav.subnav} />

The rest of the components on the page using this template wihtout a slot will be inserted into the unnamed slot on the Layout.astro page

Outer Padding

Inline (Left & Right) Padding

<div class="outer-pad"> is a direct descendent of the <main> tag and is used to match the left and right spacing seen in the design reference (differs per project). The value will typically change according to screen-width and could also change per page template-type.

The inline padding (left and right) custom property values --outer-padding can be updated in base.scss. The value is changed based on screen width with media queries. One or two values can be used, if two values are used, the first is left padding and the second is right padding. For example:

// outer padding mobile
--outer-padding: 30px;

// outer padding tablet
@media (--tablet) {
--outer-padding: 60px;
}

// outer padding desktop
@media (--lg_desktop) {
--outer-padding: 100px;
}

Outer-pad is in the helpers.css file so that it can be re-used with @extend (ie @extend .outer-pad;):

.outer-pad {
padding-inline: var(--outer-padding);
&:has(.subnav) {
@media (--lg_desktop) {
display: grid;
grid-template-columns: var(--outer-pad-subnav-grid-width) minmax(0, 1fr);
gap: var(--outer-pad-subnav-grid-gap);
align-items: start;
}
}
}

Handling Outer Padding With a Subnav

When a page (ie the Kitchen Sink With Subnav variation) has a subnav, .outer-padding class sets grid layout on desktop with the subnav as the first column and the main content <div class="page-content"> as the second column:

.outer-pad {
&:has(.subnav) {
@media (--lg_desktop) {
display: grid;
grid-template-columns: var(--outer-pad-subnav-grid-width) minmax(0, 1fr);
gap: var(--outer-pad-subnav-grid-gap);
align-items: start;
}
}

The custom properties used here --outer-pad-subnav-grid-gap and --outer-pad-subnav-grid-width are used in the formula to negate outer padding for full width components (see next section)

Negating Outer Padding for Full Width Components

Sometimes it's necessary to have a component take up the full width of the page - the helper class .negate-outer-pad-x can be used to accomplish this.

.negate-outer-pad-x {
margin-inline: calc(var(--outer-padding) * -1);
body:has(.subnav) & {
@media (--lg_desktop) {
margin-inline: calc(
(
var(--outer-pad-subnav-grid-gap) + var(--outer-padding) +
var(--outer-pad-subnav-grid-width)
) * -1
)
calc(var(--outer-padding) * -1);
}
}
}

Padding-Top for the <main> Element

The <main> tag needs padding-top set to push itself down underneath the site header. Custom propties used with the site header help to create a formula to achieve this without the need for editing (in most cases):

main {
padding-top: var(--header-top-height);
@media (--lg_desktop) {
padding-top: calc(
var(--header-top-height) + var(--header-main-menu-height)
);
}
body:has(.site-header--hamburger) & {
@media (--lg_desktop) {
padding-top: var(--header-top-height);
}
}
}

Spacing Between Kitchen Sink Components

Spacing between kitchen sink components is managed by adding a wrapper to each component on the page level (wrapper classes are not added in the component file - but in the page where they are included).

  • The wrapper class will be paragraph-widget as well as the same paragraph-widget-component-name to give extra specificity if certain components need different spacing. For example, to wrap the button-set component - this is how it would appear on a page (for example on the kitchen sink):
<div class="paragraph-widget paragraph-widget--button-set">
{% include "@components/buttons-links/button-set.twig" with
kitchen_sink_button_set %}
</div>

The general paragraph widget spacing css is handled in base.css and will need updated per project, according to the design.

  • Use margin-bottom for the spacing to avoid margin collapsing
  • If a particular component needs different spacing, handle this in the respective component's scss file using the unique paragraph widget class (ie paragraph-widget--button-set), ideally at the start of the file. For example in the button set:
.paragraph-widget--button-set {
margin-bottom: 10px;
}

.button-set {
// rest of styles

Testing Space Between Components

  • When the site is integrated and actual real-world content entered, the ordering of components will vary greatly
  • It can be beneficial to re-order kitchen sink components temporarily on a page to ensure that there are no unwanted spacing issues that will occur
  • This can be done by either re-ordering in the respective page's twig file, or by using dev tools to move sections

Site Width

There is no max-width set on the site. Instead, since rem units are used throughout (PostCSS converts pixel values to rems on dev/build) - we can increase the size (essentially scale) the site at larger viewport widths. In base.css the html element has the following style applied at the max_desktop width:

html {
// other styles not relevant to site width not displayed here for clarity
@media (--max_desktop) {
font-size: calc(100% + 0.2vw);
}
}

Updating the font size with a small vw unit here will dynamically increase the value of rems throughout the site, giving the scaling effect.