directory-level yaml gets applied to entire quarto website?

I have a Quarto website & am trying to add a page that has different formatting from the rest of the site. Adding directory level formatting works, but it then gets applied to the entire site. My assumption is that this is somehow due to the metadata getting merged, but the parent directory inheriting from a child directory isn't desirable. Is there a way to avoid this behavior? (I should note that this also occurs if I run quarto::render() and view the results in browser.

The following minimal example based on the default Quarto website template displays the behavior (also, if there's a better way to generate a quarto reprex, I'm all ears):

_quarto.yml:

project:
  type: website

website:
  title: "example"
  navbar:
    left:
      - href: index.qmd
        text: Home
      - about.qmd
      - href: subdir/index.qmd
        text: Subdir

format:
  html:
    theme: cosmo
    css: styles.css
    toc: true

editor: visual

subdir/_metadata.yml:

format:
  html:
    fontcolor: red

Running quarto::preview() generates the site as expected (initially):

Navigating to the subdir page shows the red formatting as expected:

Navigating back to the homepage/elsewhere now has red text formatting, even though its only specified in the directory-level yaml:

I'll also add that the inverse behavior (parent overwriting child) pops up as well --- if I render and open up subdir from the above example first, the text shows up red as specified in the yaml. If I head to the homepage, the text appears with the expected (black/gray) coloring. But if I then head back to subdir, the text no longer appears red!

Alrighty, a further wrinkle --- this appears to incur one issue when running locally and another when deployed. The local issue is described in the previous two comments. On a real directory, tested deployments with directory and document-level yaml that differs from the rest of the site --- in both cases, the site yaml overwrites/ignores the lower-level yaml.

My assumption is that there's some css property ~somewhere~ as a part of the theme that is taking precedence over the html that the metadata produces.

I believe this is an issue we have based on how theme merging happens. We currently merge Quarto theme layers, and thus SASS variable in the same theme files for all page on a website.

We knew about this issue for revealjs presentation used in website

But it seems this happens also for html format.

If you look into the two html page produce, they will use the same style site_libs/bootstrap/bootstrap.min.css. There is only one file where they should be two css files.

This issue can be different in preview or render because the last page build will win and overwrite the other themes.

I'll open an issue for this one specifically, but this is the same as the revealjs one.

Really annoying - sorry for this.

Follow up discussion to track at

1 Like

@markjrieke Would you mind describing your real-life use case a bit? Setting fontcolor: red is great for a reprex (and thanks for that!), but I'm sure that's not what you're doing in real life. It'd be helpful to have a sense of what kind of changes you're wanting to make at a directory level.

Thank you all for checking! My actual use case involves updating the body-width & mainfont for a directory on my site. You can see where I tested document-level yaml here and the output here (note that the width matches the rest of the site). I tested with a deployment because my hunch was that the changing formatting between pages was a local phenomena (testing on main is bad but also I have a low/no traffic site & would otherwise need to reconfigure deployments to use netlify's branch deploys).

After lots of digging around last night, I realized that body-width is not adjustable at the document/directory level for websites (in an ideal world, this would work, but my hunch is that making it work like this would be really hard).

I think I've managed to get a workaround up/running using page-layout: custom. I copied the theme's default page-columns class and just replaced the column width for the body with what I want. Adding a couple other classes to tell where content should go seems to be working in a minimal repo.

I haven't yet tried a workaround for the mainfont property, but I think I should be able to just define another css class with the desired font and plop into a div.

Here's the setup for the in-situ workaround that's closer to my actual use case:

styles.scss:

/*-- scss:defaults --*/

$theme: "cosmo" !default;

/*-- scss:rules --*/

.page-layout-custom {
    display: grid;
    gap: 0;
    grid-template-columns:
      [screen-start] 1.5em
      [screen-start-inset] 5fr
      [page-start page-start-inset] 35px
      [body-start-outset] 35px
      [body-start] 1.5em
      [body-content-start] 1200px
      [body-content-end] 1.5em
      [body-end] 35px
      [body-end-outset] minmax(75px, 145px)
      [page-end-inset] 35px
      [page-end] 5fr
      [screen-end-inset] 1.5em
      [screen-end];
}

.column-body-custom {
  grid-column: 6;
}

.column-margin-custom {
  grid-column: 8;
}

subdir/index.qmd:

---
format: 
  html:
    page-layout: custom
---

::: {.column-body-custom}

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

:::

::: {.column-margin-custom}

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

:::

output:

Ah that helps, thanks! Instead of using Sass for these pages, I'd recommend using plain CSS. I think you can include specific or extra CSS files for pages in a subdirectory -- that property shouldn't be merged into the global css property of your _quarto.yml(unless the linked bug also applies there).

In that CSS file you could probably mess with the grid-template-columns property of body .page-columns to nudge it in the direction you want. You can also set your main font by taking advantage of Bootstrap's CSS variables, e.g.

@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap');

:root {
  --bs-font-sans-serif: "IBM Plex Sans"
} 
1 Like

Thanks! I've been doing a bit of CSS hackery this evening & have a working version in a dev branch --- thank you both for taking a look into this & pointing me in the right direction!