Inspired by styled-breakpoints
- Styled Components >=
6.0.0 - Browsers: check here
npm i styled-container-queries
#or
yarn add styled-container-queries
#or
pnpm add styled-container-queriestheme.ts
import { createStyledContainerQueries } from "styled-container-queries";
const breakpoints = {
sm: "500px",
md: "700px",
lg: "900px",
} as const;
const containerTheme = createStyledContainerQueries(breakpoints);
const theme = {
...containerTheme,
...styledTheme,
};
export { theme };styled.ts
import styled from "styled-components";
export const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.inline.up("sm")} {
& > p {
background-color: red;
}
}
${({ theme }) => theme.container.inline.down("sm")} {
& > p {
background-color: yellow;
}
}
`;styled.d.ts
This is the current way to solve types
import "styled-components";
import { theme } from "./theme";
declare module "styled-components" {
export interface DefaultTheme {
container: typeof theme.container;
}
}main.tsx
import { ThemeProvider } from "styled-components";
import { theme } from "./theme";
import * as S from "./styled.ts";
const Main = () => (
<ThemeProvider theme={theme}>
<S.Container>
<p>example text</p>
</S.Container>
</ThemeProvider>
);
export { Main };Create theme
import { createStyledContainerQueries } from "styled-container-queries";
const breakpoints = {
sm: "200px",
} as const;
const containerTheme = createStyledContainerQueries(breakpoints);const containerTheme = {
//return query and container-type: inline-size
inline: {
up,
down,
only,
between,
attrs,
},
//return query and container-type: size
size: {
up,
down,
only,
between,
attrs,
},
//return query and container-type: normal
normal: {
up,
down,
only,
between,
attrs,
},
//return only query without `container-type`
query: {
up,
down,
only,
between,
attrs,
},
};const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.inline.up("md")} {
background-color: red;
}
`;Result
container-type: inline-size;
@container (min-width: $MD_SIZE) {
background-color: red;
}const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.size.up("md")} {
background-color: red;
}
`;Result
container-type: size;
@container (min-width: $MD_SIZE) {
background-color: red;
}const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.normal.up("md")} {
background-color: red;
}
`;Result
container-type: normal;
@container (min-width: $MD_SIZE) {
background-color: red;
}const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.query.up("md")} {
background-color: red;
}
`;Result
@container (min-width: $MD_SIZE) {
background-color: red;
}const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.inline.up("md")} {
background-color: red;
}
`;Result
container-type: inline-size;
@container (min-width: $MD_SIZE) {
background-color: red;
}const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.inline.down("md")} {
background-color: red;
}
`;Result
container-type: inline-size;
@container (max-width: $MD_SIZE) {
background-color: red;
}const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.inline.only("md")} {
background-color: red;
}
`;Result
Whether find next largest size
container-type: inline-size;
@container (min-width: $MD_SIZE) and (max-width: $NEXT_SIZE - 0.2) {
background-color: red;
}Else
container-type: inline-size;
@container (min-width: $MD_SIZE) {
background-color: red;
}const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.inline.between(["sm", "md"])} {
background-color: red;
}
`;Result
container-type: inline-size;
@container (min-width: $SM_SIZE) and (max-width: $MD_SIZE - 0.2) {
background-color: red;
}With this method you get only container attrs
const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.inline.attrs()}
`;const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.size.attrs()}
`;const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.inline.attrs("name")}
`;const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.size.attrs("name")}
`;const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.query.attrs("name")}
`;Results
container-type: inline-size;container-type: size;container-type: inline-size;
container-name: name;container-type: size;
container-name: name;container-name: name;With this method you get queries without type (ex:
up,down,onlyandbetween)
Attrsmethod also can be used)
const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.query.up("md")} {
background-color: red;
}
`;Result
@container (min-width: $MD_SIZE) {
background-color: red;
}const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.inline.up("md", "name")} {
background-color: red;
}
`;const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.inline.between(["sm", "md"], "name")} {
background-color: red;
}
`;Results
container-type: inline-size;
container-name: name;
@container (min-width: $MD_SIZE) {
background-color: red;
}container-type: inline-size;
container-name: name;
@container (min-width: $SM_SIZE) and (max-width: $MD_SIZE - 0.2) {
background-color: red;
}const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.inline.up("md", ".context")} {
background-color: red;
}
`;const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.inline.between(["sm", "md"], ".context")} {
background-color: red;
}
`;Results
container-type: inline-size;
@container context (min-width: $MD_SIZE) {
background-color: red;
}container-type: inline-size;
@container context (min-width: $SM_SIZE) and (max-width: $MD_SIZE - 0.2) {
background-color: red;
}const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.inline.up("md", "name.context")} {
background-color: red;
}
`;const Container = styled.div`
width: 100%;
${({ theme }) =>
theme.container.inline.between(["sm", "md"], "name.context")} {
background-color: red;
}
`;Results
container-type: inline-size;
container-nane: name;
@container context (min-width: $MD_SIZE) {
background-color: red;
}container-type: inline-size;
container-name: name;
@container context (min-width: $SM_SIZE) and (max-width: $MD_SIZE - 0.2) {
background-color: red;
}styled.ts
import styled from "styled-components";
export const Container = styled.div`
width: 100%;
${({ theme }) => theme.container.inline.up("md")} {
p {
background-color: red;
}
}
`;
export const SubContainer = styled.div`
width: 50%;
${({ theme }) => theme.container.inline.up("md", "container")} {
background-color: pink;
}
`;
export const SubSubContainer = styled.div`
${({ theme }) => theme.container.inline.up("md", ".container")} {
background-color: yellow;
}
`;component.tsx
import * as S from "./styled.ts";
const Component = () => (
<S.Container>
<p>container</p>
<S.SubContainer>
<S.SubSubContainer>
<p>sub-sub-container</p>
</S.SubSubContainer>
</S.SubContainer>
</S.Container>
);To contribute, make sure to follow the steps bellow:
-
Create a new branch:
git checkout -b feat/your-new-feature
-
Make your changes, add unit tests (with
jest) and test withnpm linkOn styled-container-queries project:
npm link
On your app/project:
npm link styled-container-queries
This will create a symlink into your
node_modulesapp, and you can test iteratively. You can check more about npm-link here -
Before to push your changes to origin, open your pull request and fill all required fields.
- Make sure to fill the Release section with what your pull request changes. This section is required to merge pull request.
-
Set a required
semverlabel according to your change:semver:patch: used when you submit a fix to a bug, enhance performance, etc;semver:minor: used when you submit a new component, new feature, etc;semver:major: used when you submit some breaking change, etc;semver:prerelease: used when you submit a prerelease (ex:1.0.0-beta.1);semver:bypass: used to update docs, or something that doesn’t affect the build.
Info: Once you have merged your pull request, with all required fields, GitHub Actions will be responsible to create a new build and publish.
MIT License

