pico icon indicating copy to clipboard operation
pico copied to clipboard

Don't rely on <main> being a direct child of <body>

Open adamerose opened this issue 1 year ago • 14 comments

Current Behavior

<main> and <header> don't have any padding unless they are directly inside <body>. This is a problem in any React project because components always get mounted inside <div id="root">

Expected Behavior

We should still get edge padding on the page even if <main> isn't a direct child of <body>

Potential Solutions

  • Apply the padding to any <main> not just body>main, but this might break layout in scenarios with nested <main> blocks
  • Apply the padding directly to <body> or it's direct children

Reproduction URL

Adding a parent div to your Classless example breaks the padding: https://codesandbox.io/s/eloquent-khayyam-gxmtfc


image

image

adamerose avatar Sep 14 '23 17:09 adamerose

Could this be a solution?

If you need to customize the default parent (<body>) for <header>, <main>, and <footer>, you can recompile Pico by defining another CSS selector. https://picocss.com/docs/classless.html

Bjorn-Eric-Abr avatar Sep 20 '23 17:09 Bjorn-Eric-Abr

Distributing multiple versions or asking users to do their own recompilation seems unnecessary.

Couldn't PicoCSS just use the selector #root, body > main so it will work for everyone by default? Or alternatively why not apply the padding on body instead of trying to find the appropriate root element inside is.

adamerose avatar Sep 20 '23 18:09 adamerose

fwiw, I have the same issue on a Sveltekit project. I'm simply ignoring their recommendation and living with a console warning from their tools but it would be nice to see this changed.

here's what I'm doing to make pico happy:

<body data-sveltekit-preload-data="hover">
	%sveltekit.body%
</body>

Here's the warning I get from sveltekit: image

here's what they really want:

<body data-sveltekit-preload-data="hover">
	<div style="display: contents">%sveltekit.body%</div>
</body>

and here's their rationale (and probably others I would expect): image

here's an associated discussion about it which elaborates a bit on the author's reasoning: https://github.com/sveltejs/kit/discussions/7585

I like @adamerose 's ideas

longrunningprocess avatar Sep 25 '23 14:09 longrunningprocess

I had the same issue using Vue, but instead I renamed the div in to body.

<div id="root"></div> becomes <body id="root"></body>

jelmerveen avatar Sep 28 '23 13:09 jelmerveen

Couldn't PicoCSS just use the selector #root, body > main so it will work for everyone by default?

#root, body > main is too opinionated, imo, as #root is not necessarily exclusive to React.

Or alternatively why not apply the padding on body instead of trying to find the appropriate root element inside is.

This would break all full-width potential.

Would it suffice to create your own rule(s) for #root using any of Pico's variables?

steven-aj avatar Dec 08 '23 22:12 steven-aj

I think requiring main, header, etc to be direct children of body is also too opinionated. And needing custom rules or config to get proper default padding defeats the purpose of classless CSS IMO.

Why would applying padding to body instead of body>main would break things? Most other classless CSS libraries like water just put padding on the body.

adamerose avatar Dec 08 '23 22:12 adamerose

The upcoming v2 will make it easy to customize the root element.

@use "@picocss/pico/scss/pico" as * with (
  $semantic-root-element: "#root",
  $enable-semantic-container: true,
);

Example: https://codesandbox.io/p/devbox/github/picocss/examples/tree/master/v2-react-classless-login?embed=1&file=%2Fsrc%2Fmain.scss

lucaslarroche avatar Jan 27 '24 03:01 lucaslarroche

...but this might break layout in scenarios with nested <main> blocks

FWIW, nesting <main> elements is invalid markup and shouldn't be done anyway.

dev-willis avatar Jan 27 '24 20:01 dev-willis

...but this might break layout in scenarios with nested <main> blocks

FWIW, nesting <main> elements is invalid markup and shouldn't be done anyway.

~~This isn't entirely true.~~

Edit 2: Nevermind. This is 100% inaccurate.

A hierarchically correct main element is one whose ancestor elements are limited to html, body, div, form without an accessible name, and autonomous custom elements. Each main element must be a hierarchically correct main element.

Edited for readability

steven-aj avatar Jan 28 '24 07:01 steven-aj

...whose ancestor elements are limited to html, body, div, form without an accessible name, and autonomous custom elements.

Nesting main elements would mean that one main element is an ancestor of another main element which, per your own quote, is invalid markup. Multiple main elements are permissible only when they are hierarchically correct and when all but one also have the hidden attribute applied.

dev-willis avatar Jan 28 '24 16:01 dev-willis

...whose ancestor elements are limited to html, body, div, form without an accessible name, and autonomous custom elements.

Nesting main elements would mean that one main element is an ancestor of another main element

"Ancestor" is not explicit to direct parents/descendants.

~~Per spec, the following is a valid main element hierarchichally descending another:~~

Edit: For clarity, This is 100% inaccurate. Please excuse the error.

<main>
   ...
   <form>
      <main></main>
   </form>
   ...
</main>

steven-aj avatar Jan 28 '24 18:01 steven-aj

"Ancestor" is not explicit to direct parents/descendants.

I don't understand. How can one element descend from another without the one it descends from being its ancestor?

If I plug your example into https://validator.w3.org/nu/#textarea it fails validation.

dev-willis avatar Jan 29 '24 20:01 dev-willis

Apologies. I was unequivocally wrong. Literally above my former quote:

A document must not have more than one main element that does not have the hidden attribute specified.

I thought I understood more of that area of the spec than I obviously do.

steven-aj avatar Jan 29 '24 21:01 steven-aj

I might close this issue because the root container is customizable with SCSS. https://picocss.com/docs/classless#root-container

Here is an example of changing the root container to #root (React): https://codesandbox.io/p/devbox/github/picocss/examples/tree/master/v2-react-classless-login?embed=1&file=%2Fsrc%2Fmain.scss

Also, you don't need to use the classless version; you can simply use the regular version, with .container: https://picocss.com/docs/container

lucaslarroche avatar Feb 18 '24 06:02 lucaslarroche