Skip to content

Instantly share code, notes, and snippets.

@joshdavenport
Last active February 22, 2024 23:55
Show Gist options
  • Save joshdavenport/3e6d7fed02fba0cf47b6f85d4e2faf40 to your computer and use it in GitHub Desktop.
Save joshdavenport/3e6d7fed02fba0cf47b6f85d4e2faf40 to your computer and use it in GitHub Desktop.
Generate srcset sizes attribute from tailwind screens
/*
The main method here is processTailwindSrcsetSizes. You can generate a sizes attribute using it based on
tailwind style breakpointed sizes referencing your screens, such as:
"100vw md:500px"
"200px lg:100vw"
"200px md:300px xl:600px"
"100vw lg:50vw"
"100vw"
"400px"
Your full tailwind config is resolved and screens from it used, so you can use whatever you normally use.
Given the default tailwind screens the above becomes
"(min-width: 768px) 500px, 100vw"
"(min-width: 1024px), 200px"
"(min-width: 1280px) 600px, (min-width: 768px) 300px, 200px"
"(min-width: 1024px) 50vw, 100vw"
"100vw"
"400px"
I use it in a React component by taking a sizes prop on the component, then passing that value into processTailwindSrcsetSizes
then using that as the actual sizes attribute.
*/
import resolveConfig from 'tailwindcss/resolveConfig';
// Resolve correctly based on your codebase
import tailwindConfig from '@/../tailwind.config.js';
const fullConfig = resolveConfig(tailwindConfig);
export function isTailwindScreen(
screen: string,
): screen is keyof typeof fullConfig.theme.screens {
return screen in fullConfig.theme.screens;
}
export function processTailwindSrcsetSizes(sizes: string) {
type TailwindSizesSize = {
size: number;
width: string;
};
const convertedSizes = sizes
.split(' ')
.map((rule) => {
const [screenOrSoleWidth, width] = rule.split(':');
if (screenOrSoleWidth && !width) {
return {
size: 0,
width: screenOrSoleWidth,
};
}
if (
!screenOrSoleWidth ||
!width ||
!isTailwindScreen(screenOrSoleWidth)
) {
return null;
}
return {
size: parseInt(fullConfig.theme.screens[screenOrSoleWidth]),
width: width,
};
})
.filter((rule) => rule !== null) as TailwindSizesSize[];
if (!convertedSizes.length) {
return null;
}
return convertedSizes
.sort((a, b) => b.size - a.size)
.map(({ size, width }) =>
size === 0 ? width : `(min-width: ${size}px) ${width}`,
)
.join(', ');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment