diff --git a/components/curriculum-about/server.js b/components/curriculum-about/server.js index b3e537d70..16921d83e 100644 --- a/components/curriculum-about/server.js +++ b/components/curriculum-about/server.js @@ -29,24 +29,33 @@ export class CurriculumAbout extends ServerComponent { return PageLayout.render( context, html` -
+
-
+

${coloredTitle} ${restTitle.join(" ")}

-
-
diff --git a/components/curriculum-default/server.js b/components/curriculum-default/server.js index 218a30ea7..c0fa72113 100644 --- a/components/curriculum-default/server.js +++ b/components/curriculum-default/server.js @@ -29,24 +29,33 @@ export class CurriculumDefault extends ServerComponent { return PageLayout.render( context, html` -
+
-
+

${coloredTitle} ${restTitle.join(" ")}

-
-
diff --git a/components/curriculum-module/server.js b/components/curriculum-module/server.js index a7f32100d..4a527d332 100644 --- a/components/curriculum-module/server.js +++ b/components/curriculum-module/server.js @@ -32,13 +32,17 @@ export class CurriculumModule extends ServerComponent { return PageLayout.render( context, html` -
+
-
+
${doc?.topic ? renderTopicIcon(context, doc.topic) : nothing}

${doc?.title}

${doc?.topic @@ -48,16 +52,21 @@ export class CurriculumModule extends ServerComponent { ? html`

${doc.group}

` : nothing}
-
-
diff --git a/components/curriculum-overview/server.js b/components/curriculum-overview/server.js index 9d865b0d3..f8784cfbd 100644 --- a/components/curriculum-overview/server.js +++ b/components/curriculum-overview/server.js @@ -36,22 +36,28 @@ export class CurriculumOverview extends ServerComponent { return PageLayout.render( context, html` -
+
-
+

${coloredTitle} ${restTitle}

-
-
`, - - // html` - //
- // ${sidebar} - //
- //
- //

${coloredTitle} ${restTitle}

- //
- // ${renderCurriculumBody(context, doc)} - // ${doc?.modules && doc.modules.length > 0 - // ? html` - //
- //

Module list

- // ${renderModulesList(context, doc.modules)} - //
- // ` - // : nothing} - // ${this.renderPrevNext(context, doc)} - //
- //
- // - // - //
- //
- // `, ); } diff --git a/components/curriculum/layout.css b/components/curriculum/layout.css index 700cd4c76..646c0dad6 100644 --- a/components/curriculum/layout.css +++ b/components/curriculum/layout.css @@ -1,39 +1,12 @@ -.curriculum-content-container { - display: grid; - - grid-template-areas: - "sidebar . header . toc" - "sidebar . body . toc"; - grid-template-rows: min-content auto; - grid-template-columns: var(--layout-2-sidebars); - - justify-content: space-between; - - padding-inline: var(--layout-side-padding); - - .curriculum-layout__content { - display: contents; - } - - .curriculum-layout__header { - grid-area: header; - } +@import url("../layout/2-sidebars.css"); +.curriculum-content-container { .curriculum-layout__body { - grid-area: body; padding-bottom: 3rem; } .curriculum-layout__sidebar { - grid-area: sidebar; padding-top: 0; - - @media (--screen-layout-2-sidebars) { - .left-sidebar { - padding-right: calc(var(--layout-sidebar-gap) / 2); - margin-right: calc(var(--layout-sidebar-gap) / -2); - } - } } .curriculum-layout__toc { @@ -41,62 +14,14 @@ flex-wrap: wrap; - grid-area: toc; - gap: 0.5rem; align-content: start; align-items: start; justify-content: space-between; } - .curriculum-layout__sidebar .left-sidebar, - .curriculum-layout__toc { - position: sticky; - top: var(--sticky-header-height); - - max-height: calc(100vh - var(--sticky-header-height)); - - overflow-y: auto; - } - - @media (--screen-layout-1-sidebar-or-less) { - grid-template-areas: - "toc . header" - "toc . body"; - grid-template-columns: var(--layout-1-sidebar-left); - - .curriculum-layout__sidebar { - z-index: 1; - - display: none; - - grid-area: toc; - - background: var(--color-background-page); - } - } - @media (--screen-layout-no-sidebar) { - display: block; - - .curriculum-layout__sidebar { - position: fixed; - inset: 0; - top: var(--sticky-header-height); - z-index: var(--z-index-sidebar-mobile); - - .left-sidebar { - padding: 1rem; - } - } - .curriculum-layout__toc { - position: unset; - top: unset; - - max-height: unset; - - overflow-y: unset; --toc-header-font-size: var(--font-size-larger); } } diff --git a/components/curriculum/sidebar.css b/components/curriculum/sidebar.css index f7e855fdf..b972aaf76 100644 --- a/components/curriculum/sidebar.css +++ b/components/curriculum/sidebar.css @@ -1,9 +1,5 @@ .curriculum-content-container .left-sidebar { - position: sticky; - top: var(--sticky-header-height); - padding-bottom: 3rem; - overflow-wrap: anywhere; ol { diff --git a/components/curriculum/toc.css b/components/curriculum/toc.css index d99941931..af7779f60 100644 --- a/components/curriculum/toc.css +++ b/components/curriculum/toc.css @@ -1,7 +1,5 @@ .curriculum-content-container { .curriculum-layout__toc { - padding: 2px; - .document-toc { padding: 0; margin-bottom: 2rem; @@ -83,7 +81,7 @@ } } - @media (--screen-small-and-narrower) { + @media (--screen-layout-no-sidebar) { padding: 0 1rem; } diff --git a/components/generic-layout/server.css b/components/generic-layout/server.css index cbe693b28..f7b210f27 100644 --- a/components/generic-layout/server.css +++ b/components/generic-layout/server.css @@ -1,69 +1,13 @@ -/* Generic Layout */ -.generic-layout { - display: grid; - - grid-template-areas: "sidebar . body . toc"; - grid-template-columns: var(--layout-2-sidebars); - - padding-inline: var(--layout-side-padding); - - @media (--screen-layout-1-sidebar-or-less) { - grid-template-areas: "leftsidebar . body"; - grid-template-columns: var(--layout-1-sidebar-left); - - .generic-layout__toc { - grid-area: leftsidebar; - } - - .generic-layout__sidebar { - z-index: 1; - - display: none; - - grid-area: leftsidebar; - - background: var(--color-background-page); - } - } +@import url("../layout/2-sidebars.css"); - @media (--screen-layout-no-sidebar) { - grid-template-areas: ". body ."; - grid-template-columns: var(--layout-no-sidebar); - - .generic-layout__toc { - display: none; - } - - .generic-layout__sidebar { - inset: 0; - top: var(--sticky-header-height); - z-index: var(--z-index-sidebar-mobile); - - display: none; - - grid-area: body; - - .left-sidebar { - padding: 1rem; - } - } - } -} - -/* Sidebar */ -.generic-layout__sidebar { - grid-area: sidebar; - padding: 2rem 0; -} +/* Generic Layout */ /* Content */ .generic-layout__content { - grid-area: body; - padding: 2rem 0; + padding-block: 2rem; } /* TOC */ .generic-layout__toc { - grid-column: toc; - padding: 2rem 0; + padding-block: 2rem; } diff --git a/components/generic-layout/server.js b/components/generic-layout/server.js index d3b097a81..c01e2fdf5 100644 --- a/components/generic-layout/server.js +++ b/components/generic-layout/server.js @@ -11,12 +11,17 @@ export class GenericLayout extends ServerComponent { */ render(context) { return html` -
- -
+
+ +
${GenericContent.render(context)}
-
diff --git a/components/generic-sidebar/server.css b/components/generic-sidebar/server.css index aaad83635..df1c13679 100644 --- a/components/generic-sidebar/server.css +++ b/components/generic-sidebar/server.css @@ -2,9 +2,7 @@ --color-accent: var(--color-blue-50); --color-background-accent: var(--color-background-blue); --color-border-items: light-dark(var(--color-gray-80), var(--color-gray-20)); - - position: sticky; - top: var(--sticky-header-height); + padding-block: 2rem; margin-bottom: 2rem; .generic-sidebar__header { diff --git a/components/generic-toc/server.css b/components/generic-toc/server.css index 16a880e7b..9fd2f27b5 100644 --- a/components/generic-toc/server.css +++ b/components/generic-toc/server.css @@ -1,7 +1,4 @@ .generic-toc { - position: sticky; - top: var(--sticky-header-height); - .generic-toc__header { margin: 0 0 1rem; diff --git a/components/layout/2-sidebars.css b/components/layout/2-sidebars.css new file mode 100644 index 000000000..2aeae970f --- /dev/null +++ b/components/layout/2-sidebars.css @@ -0,0 +1,141 @@ +.layout__2-sidebars, +.layout__2-sidebars-inline { + display: grid; + + grid-template-columns: var(--layout-2-sidebars); + + justify-content: space-between; + + padding-inline: var(--layout-side-padding); + + .layout__left-sidebar { + grid-area: left-sidebar; + } + + .layout__right-sidebar { + grid-area: right-sidebar; + } + + .layout__left-sidebar, + .layout__right-sidebar { + position: sticky; + top: var(--sticky-header-height); + + max-height: calc(100vh - var(--sticky-header-height)); + + overflow-y: auto; + + outline-offset: -2px; + } + + @media (--screen-layout-2-sidebars) { + .layout__left-sidebar { + padding-right: var(--layout-sidebar-padding); + padding-left: var(--layout-side-padding-min); + margin-left: calc(-1 * var(--layout-side-padding-min)); + } + + .layout__right-sidebar { + padding-right: var(--layout-side-padding-min); + padding-left: var(--layout-sidebar-padding); + margin-right: calc(-1 * var(--layout-side-padding-min)); + } + } + + @media (--screen-layout-1-sidebar-or-less) { + grid-template-columns: var(--layout-1-sidebar-left); + + .layout__left-sidebar { + z-index: 1; + display: none; + background: var(--color-background-page); + } + + .layout__left-sidebar, + .layout__right-sidebar { + grid-area: sidebar; + + padding-right: var(--layout-sidebar-padding); + padding-left: var(--layout-side-padding-min); + margin-left: calc(-1 * var(--layout-side-padding-min)); + } + } + + @media (--screen-layout-no-sidebar) { + display: block; + + .layout__left-sidebar, + .layout__right-sidebar { + padding-right: unset; + padding-left: unset; + margin-left: unset; + } + + .layout__left-sidebar { + position: fixed; + inset: 0; + top: var(--sticky-header-height); + z-index: var(--z-index-sidebar-mobile); + + padding: 0 var(--layout-side-padding-min); + } + + .layout__right-sidebar { + position: unset; + top: unset; + + max-height: unset; + + overflow-y: unset; + } + } +} + +.layout__2-sidebars { + .layout__content { + grid-area: content; + } + + @media (--screen-layout-no-sidebar) { + .layout__right-sidebar { + display: none; + } + } +} + +.layout__2-sidebars-inline { + grid-template-areas: + "left-sidebar . header . right-sidebar" + "left-sidebar . body . right-sidebar"; + grid-template-rows: min-content 1fr; + + .layout__content { + display: contents; + } + + .layout__header { + grid-area: header; + } + + .layout__body { + grid-area: body; + } + + @media (--screen-layout-1-sidebar-or-less) { + grid-template-areas: + "sidebar . header" + "sidebar . body"; + grid-template-columns: var(--layout-1-sidebar-left); + } + + @media (--screen-layout-no-sidebar) { + .layout__right-sidebar { + position: unset; + top: unset; + + max-height: unset; + + overflow-y: unset; + } + } +} diff --git a/components/layout/README.md b/components/layout/README.md index 320178d1b..bf4f3399e 100644 --- a/components/layout/README.md +++ b/components/layout/README.md @@ -1,8 +1,50 @@ # Layout -This component provides some global utility variables for consistent layout. +This component provides some global utility variables and some importable stylesheets for consistent layout. -## Side padding +If you need to do something very custom, you can use the variables directly, otherwise we recommend using one of the importable stylesheets and applying the classes to your component. + +## Class based layouts + +### `.layout__2-sidebars` + +Import from `./2-sidebars.css` + +Classes should be used with this hierarchy: + +- `layout__2-sidebars` + - `layout__left-sidebar` + - `layout__content` + - `layout__right-sidebar` + +When there's space for 2 sidebars then both sidebars will show, left on the left and right on the right. + +When there's only space for 1 sidebar then the right sidebar will show on the left and the left sidebar will become toggleable with ``. + +When there's no space for sidebars then the right sidebar will be hidden and the left sidebar still toggleable. + +### `.layout__2-sidebars-inline` + +Import from `./2-sidebars.css` + +Classes should be used with this hierarchy: + +- `layout__2-sidebars-inline` + - `layout__left-sidebar` + - `layout__content` + - `layout__header` + - `layout__right-sidebar` + - `layout__body` + +When there's space for 2 sidebars then both sidebars will show, left on the left and right on the right, with header and body shown in the central content area. + +When there's only space for 1 sidebar then the right sidebar will show on the left and the left sidebar will become toggleable with ``. + +When there's no space for sidebars then the right sidebar will be displayed inline within the content and the left sidebar still toggleable. + +## Global utility variables + +### Side padding In the simplest case, you may just need the `--layout-side-padding` variable. This keeps full width content in line with the padding in the navigation and footer, which provides a small padding on small screens, and centers content on very large screens: @@ -12,7 +54,7 @@ In the simplest case, you may just need the `--layout-side-padding` variable. Th } ``` -## Content and sidebar layouts +### Content and sidebar layouts If the page has "content" - some kind of prose - and optionally sidebars, you'll likely want one of the following layouts. The columns are sized to ensure that the content column doesn't become too wide (and have unreadably long lines of text), and that the sidebar columns don't become too narrow. @@ -57,7 +99,7 @@ If you're using sidebars, you'll probably want to use the [custom media queries] } ``` -### 2 sidebars: `--layout-2-sidebars` +#### 2 sidebars: `--layout-2-sidebars` A column for content, two columns for sidebars, and two columns for a gap between the content and sidebars. The columns are named as follows: @@ -69,13 +111,13 @@ A column for content, two columns for sidebars, and two columns for a gap betwee Use the `--screen-layout-1-sidebar-or-less` custom media query to change to a different layout when the viewport becomes too narrow. -### 1 sidebar +#### 1 sidebar Two variants, which are identical apart from one having a left sidebar and the other a right sidebar. They have a column for content, a column for the sidebar, and a column for a gap between the content and sidebar. Use the `--screen-layout-no-sidebar` custom media query to change to a different layout when the viewport becomes too narrow. -#### Left sidebar `--layout-1-sidebar-left` +##### Left sidebar `--layout-1-sidebar-left` The columns are named as follows: @@ -86,7 +128,7 @@ The columns are named as follows: | left-sidebar | | | | sidebar | | | -#### Right sidebar `--layout-1-sidebar-right` +##### Right sidebar `--layout-1-sidebar-right` The columns are named as follows: @@ -97,11 +139,11 @@ The columns are named as follows: | | | right-sidebar | | | | sidebar | -### No sidebar +#### No sidebar Two variants, one if you're using `--layout-side-padding`, the other if you'd like to place things within that padding (e.g. a full width banner): -#### Using padding: `--layout-no-sidebar` +##### Using padding: `--layout-no-sidebar` The columns are named as follows: @@ -122,7 +164,7 @@ The columns are named as follows: } ``` -#### Not using padding: `--layout-no-sidebar-extended` +##### Not using padding: `--layout-no-sidebar-extended` The columns are named as follows: diff --git a/components/layout/global.css b/components/layout/global.css index 0ca1286e7..5c2db0d85 100644 --- a/components/layout/global.css +++ b/components/layout/global.css @@ -1,9 +1,9 @@ /* --layout-side-padding-min * 2 + (--layout-sidebar-min + --layout-sidebar-gap) * 2 + --layout-content-min */ -@custom-media --screen-layout-2-sidebars (width >= calc(1rem * 2 + (14rem + 2rem) * 2 + 31rem)); -@custom-media --screen-layout-1-sidebar-or-less (width < calc(1rem * 2 + (14rem + 2rem) * 2 + 31rem)); +@custom-media --screen-layout-2-sidebars (width >= calc(1rem * 2 + (15rem + 1rem) * 2 + 31rem)); +@custom-media --screen-layout-1-sidebar-or-less (width < calc(1rem * 2 + (15rem + 1rem) * 2 + 31rem)); /* --layout-side-padding-min * 2 + --layout-sidebar-min + --layout-sidebar-gap + --layout-content-min */ -@custom-media --screen-layout-no-sidebar (width < calc(1rem * 2 + 14rem + 2rem + 31rem)); +@custom-media --screen-layout-no-sidebar (width < calc(1rem * 2 + 15rem + 1rem + 31rem)); :root { --layout-side-padding-min: 1rem; @@ -13,13 +13,14 @@ ); --layout-full-width: calc(100vw - 2 * var(--layout-side-padding)); - --layout-sidebar-min: 14rem; - --layout-sidebar-gap: 2rem; + --layout-sidebar-min: 15rem; + --layout-sidebar-gap: 1rem; + + /* maintain existing gap, will remove/simplify soon: */ + --layout-sidebar-padding: calc(1rem + 2px); --layout-content-min: 31rem; --layout-content-max: 48rem; - /* WARNING: TODO: left/center/right cols widths will change */ - /* prettier-ignore */ --layout-2-sidebars: [full-start left-sidebar-start] diff --git a/components/left-sidebar/server.css b/components/left-sidebar/server.css index bd8b120c7..a78263ac7 100644 --- a/components/left-sidebar/server.css +++ b/components/left-sidebar/server.css @@ -1,9 +1,5 @@ .left-sidebar { - position: sticky; - top: var(--sticky-header-height); - padding-bottom: 3rem; - overflow-wrap: anywhere; h4 { @@ -131,12 +127,6 @@ } } -.left-sidebar__content { - > ol { - padding-left: 2px; - } -} - .left-sidebar__header { position: sticky; top: 0; @@ -145,7 +135,6 @@ padding-top: 0.5rem; padding-right: 0.5rem; padding-bottom: 2rem; - padding-left: 2px; background: linear-gradient( to bottom, diff --git a/components/page-layout/server.css b/components/page-layout/server.css index 26175eb93..c12c80442 100644 --- a/components/page-layout/server.css +++ b/components/page-layout/server.css @@ -29,7 +29,7 @@ color-scheme: dark; } - @media (--screen-small-and-narrower) { + @media (--screen-small-and-narrower) or (--screen-layout-no-sidebar) { display: none; } } diff --git a/components/print/global.css b/components/print/global.css index af987ac3d..174b6c33f 100644 --- a/components/print/global.css +++ b/components/print/global.css @@ -42,8 +42,8 @@ } .page-layout__banner, - .reference-layout__toc, - .reference-layout__sidebar, + .layout__left-sidebar, + .layout__right-sidebar, .footer__socials, .footer__links, .footer__mozilla, diff --git a/components/reference-layout/server.css b/components/reference-layout/server.css index 00c07beea..e0694f725 100644 --- a/components/reference-layout/server.css +++ b/components/reference-layout/server.css @@ -1,25 +1,9 @@ +@import url("../layout/2-sidebars.css"); + /* Reference Layout */ .reference-layout { - display: grid; - - grid-template-areas: - "sidebar . header . toc" - "sidebar . body . toc"; - grid-template-rows: min-content 1fr; - grid-template-columns: var(--layout-2-sidebars); - - justify-content: space-between; - - padding-inline: var(--layout-side-padding); - - .reference-layout__content { - display: contents; - } - .reference-layout__header { - grid-area: header; - h1 { margin: 1rem 0; @@ -31,84 +15,22 @@ } .reference-layout__body { - grid-area: body; padding-bottom: 3rem; } - .reference-layout__sidebar { - grid-area: sidebar; - - @media (--screen-layout-2-sidebars) { - .left-sidebar { - padding-right: calc(var(--layout-sidebar-gap) / 2); - margin-right: calc(var(--layout-sidebar-gap) / -2); - } - } - } - .reference-layout__toc { display: flex; flex-wrap: wrap; - grid-area: toc; - gap: 0.5rem; align-content: start; align-items: start; justify-content: space-between; } - .reference-layout__sidebar .left-sidebar, - .reference-layout__toc { - position: sticky; - top: var(--sticky-header-height); - - max-height: calc(100vh - var(--sticky-header-height)); - - padding-left: 2px; - - overflow-y: auto; - } - - @media (--screen-layout-1-sidebar-or-less) { - grid-template-areas: - "toc . header" - "toc . body"; - grid-template-columns: var(--layout-1-sidebar-left); - - .reference-layout__sidebar { - z-index: 1; - - display: none; - - grid-area: toc; - - background: var(--color-background-page); - } - } - @media (--screen-layout-no-sidebar) { - display: block; - - .reference-layout__sidebar { - position: fixed; - inset: 0; - top: var(--sticky-header-height); - z-index: var(--z-index-sidebar-mobile); - - .left-sidebar { - padding: 0 1rem; - } - } - .reference-layout__toc { - position: unset; - top: unset; - - max-height: unset; - - overflow-y: unset; --toc-header-font-size: var(--font-size-larger); } } diff --git a/components/reference-layout/server.js b/components/reference-layout/server.js index c4803928f..16267824e 100644 --- a/components/reference-layout/server.js +++ b/components/reference-layout/server.js @@ -21,24 +21,24 @@ export class ReferenceLayout extends ServerComponent { doc.body?.map((section) => ContentSection.render(context, section)) || []; return html` -
-
-
+
+
+
${WRITER_MODE ? WriterToolbar.render(context) : nothing} ${TranslationBanner.render(context)}

${doc.title}

${BaselineIndicator.render(context)} ${description}
-
-