pico
pico copied to clipboard
Don't rely on <main> being a direct child of <body>
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 justbody>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
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
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.
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:
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):
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
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>
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?
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.
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
...but this might break layout in scenarios with nested
<main>
blocks
FWIW, nesting <main>
elements is invalid markup and shouldn't be done anyway.
...but this might break layout in scenarios with nested
<main>
blocksFWIW, 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
...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.
...whose ancestor elements are limited to html, body, div, form without an accessible name, and autonomous custom elements.
Nesting
main
elements would mean that onemain
element is an ancestor of anothermain
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>
"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.
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.
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