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-queries
theme.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
,only
andbetween
)
Attrs
method 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 link
On styled-container-queries project:
npm link
On your app/project:
npm link styled-container-queries
This will create a symlink into your
node_modules
app, 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
semver
label 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