#Responsive styles
1 messages · Page 1 of 1 (latest)
Puck doesn't need anything special here. So just use media queries if using CSS, or Tailwind viewport modifiers if using Tailwind, etc
I am using CSS and have added media queries, but for a component that appears on two different pages, each page needs separate responsive styles. How can I resolve this case?
However you would solve it if Puck wasn't involved - easiest to add a separate component with its own styles. You could also create a separate page with its own styles and import your Puck instance as a component.
Late to this show. Im trying out what @tiny dust here says to use tailwind's viewport modifiers. The problem here is that tailwind automatically strips (or never includes) unused classes, keeping the bundle small. Tailwind of course does not know what dynamic html is inserted into the view, it could never know.
You can easily get proof of this problem if you add classes to the safelist https://tailwindcss.com/docs/content-configuration#safelisting-classes
You see then that responsive-ness starts to work.
Puck seems to be an amazing tool, but for me it breaks a bit on "how to actually build responsive webpages", or at least a bit of guidance on best practices that work.
This is what Im trying to do in the editor, see "textAlign". But Im getting stuck with the styles not being seen by tailwind, so they are stripped sadly.
What helped here is to build 'mobile first' and then take a break point like "md" for which you can define all the styles in a placeholders file (anywhere defined because tailwind uses it to to see which classes to keep).
Generated with ChatGPT:
// Just export a string that includes all the classes you want Tailwind to preserve:
module.exports = `
/* Text alignment (md:) */
md:text-left
md:text-center
md:text-right
md:text-justify
md:text-start
md:text-end
/* Flexbox (md:) */
md:flex
md:inline-flex
md:flex-row
md:flex-row-reverse
md:flex-col
md:flex-col-reverse
md:flex-wrap
md:flex-wrap-reverse
md:flex-nowrap
md:justify-start
md:justify-center
md:justify-end
md:justify-between
md:justify-around
md:justify-evenly
md:items-start
md:items-center
md:items-end
md:items-baseline
md:items-stretch
md:content-start
md:content-center
md:content-end
md:content-between
md:content-around
md:content-evenly
md:self-auto
md:self-start
md:self-center
md:self-end
md:self-stretch
md:grow
md:grow-0
md:shrink
md:shrink-0
/* Grid (md:) */
md:grid
md:inline-grid
md:grid-cols-1
md:grid-cols-2
md:grid-cols-3
md:grid-cols-4
md:grid-cols-5
md:grid-cols-6
md:grid-cols-7
md:grid-cols-8
md:grid-cols-9
md:grid-cols-10
md:grid-cols-11
md:grid-cols-12
md:grid-rows-1
md:grid-rows-2
md:grid-rows-3
md:grid-rows-4
md:grid-rows-5
md:grid-rows-6
md:gap-0
md:gap-1
md:gap-2
md:gap-3
md:gap-4
md:gap-5
md:gap-6
md:gap-7
md:gap-8
md:gap-9
md:gap-10
/* place-content (md:) */
md:place-content-center
md:place-content-start
md:place-content-end
md:place-content-between
md:place-content-around
md:place-content-evenly
md:place-content-stretch
`;
CC @sly jacinth - could be some good content
@remote dew you will probably find it works if you disable iframes, but you may also need to consider creating some kind of override so tailwind can find the dynamic styles.
We should probably wrap this up as a plugin. Here's a similar one for emotion: https://github.com/measuredco/puck/blob/main/packages/plugin-emotion-cache/index.tsx
Ah I tried without the iframe, but "problem" is that tailwind optimizes and purges all classes that you haven't defined anywhere. So, it's not the iframe, it's tailwind stripping everything it didn't "see". And since I'm dynamically creating the classes, it hasnt seen them anywhere.
For example, this is my custom textAlign field, so you can select different text-aligns based on the tailwind breakpoints. You see, it never sees md:text-center anywhere as it hasnt been stated. Therefore in combination with the file above (with all those classes stated), it does work.
const typographyFields = [
textAlign: {
type: "custom",
label: "Label Example",
options: [
{ label: "Left", value: "text-left" },
{ label: "Center", value: "text-center" },
{ label: "Right", value: "text-right" },
],
defaultValue: {
default: "text-left",
md: "text-right",
},
render: ({ field, onChange, value }) => {
const breakpoints = ["default", "md"];
return (
<div className="responsive-field">
{breakpoints.map((breakpoint) => (
<Box key={breakpoint}>
<FieldLabel key={breakpoint} label={breakpoint ? `${breakpoint.toUpperCase()}:` : "Default:"} />
<AutoField
field={{ type: "radio", options: field.options }}
value={value?.[breakpoint] || ""}
onChange={(v) => {
onChange({
...(typeof value === "string" ? {} : value),
[breakpoint]: v,
})}
}
/>
</Box>
))}
</div>
)
}
},
]
Ah right
Can you whitelist everything for the editor and then rely on the detection for rendering the final page?
Let me see. I won't see how that could work, you would need to preprocess a build version of what comes out of Puck when rendered. In theory you could do it, but I don't see that path yet. Hmm.
Im using nextjs, so for it to work correctly you would pre-build those pages (server side components without any interaction possible), and then not include the whitelist file in the final build (somehow)
We need to spend a bit more time on this so let us know what you discover
in the mean time, I think whitelisting all available options is the easiest way to work around it
Yea will do for now, I probably also wont need ALL of the options. Just a default (mobile first) and then exceptions starting the md or lg breakpoint works for me.
Maybe Im trying to make a bit too customizable components within Puck, I could also predefine pretty Sections which would work on all viewport sizes. But it seemed like a cool thing to support with these breakpoints, it then resembles how things like Elementor, Builder.io, Divi and such. But all those builders have short comings too, so it's a lot of fun to start having more control!
Thanks for the input (and the amazing work that went into this project!).
Wonderful! Excited to see what you do 🙂
Ill be sharing something for sure! Need to make some time in between full-time working but this little pet project gets me going for sure
Hello, I'm testing the Grid component ... I want to play with gridTemplateColumns : 1fr 1fr 1fr in desktop and i want it to be set as only 1fr in mobile and tablet ... Is there a way I can do it easily ?