Simple lib to use container queries with styled-components
npm install styled-container-queries
!GitHub Workflow Status (with event)
!minified size
!npm
Simple lib to use container queries with styled-components
Inspired by styled-breakpoints
- Styled Components >= 6.0.0
- Browsers: check here
- how to use
- documentation
- how to contribute
- license
``shell
npm i styled-container-queries
#or
yarn add styled-container-queries
#or
pnpm add styled-container-queries
`
theme.ts
`tsx
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
`tsx
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
`tsx
import "styled-components";
import { theme } from "./theme";
declare module "styled-components" {
export interface DefaultTheme {
container: typeof theme.container;
}
}
`
main.tsx
`tsx
import { ThemeProvider } from "styled-components";
import { theme } from "./theme";
import * as S from "./styled.ts";
const Main = () => ( example text
);
export { Main };
`
- theme structure
- container types
- inline-size
- size
- normal
- query without type
- container queries
- min-width
- max-width
- exact breakpoint
- between breakpoint
- only-attrs
- only-query
- named container
- name
- context
- both
Create theme
`ts
import { createStyledContainerQueries } from "styled-container-queries";
const breakpoints = {
sm: "200px",
} as const;
const containerTheme = createStyledContainerQueries(breakpoints);
`
`tscontainer-type
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 `
query: {
up,
down,
only,
between,
attrs,
},
};
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.inline.up("md")} {
background-color: red;
};`
Result
`css
container-type: inline-size;
@container (min-width: $MD_SIZE) {
background-color: red;
}
`
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.size.up("md")} {
background-color: red;
};`
Result
`css
container-type: size;
@container (min-width: $MD_SIZE) {
background-color: red;
}
`
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.normal.up("md")} {
background-color: red;
};`
Result
`css
container-type: normal;
@container (min-width: $MD_SIZE) {
background-color: red;
}
`
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.query.up("md")} {
background-color: red;
};`
Result
`css`
@container (min-width: $MD_SIZE) {
background-color: red;
}
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.inline.up("md")} {
background-color: red;
};`
Result
`css
container-type: inline-size;
@container (min-width: $MD_SIZE) {
background-color: red;
}
`
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.inline.down("md")} {
background-color: red;
};`
Result
`css
container-type: inline-size;
@container (max-width: $MD_SIZE) {
background-color: red;
}
`
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.inline.only("md")} {
background-color: red;
};`
Result
Whether find next largest size
`css
container-type: inline-size;
@container (min-width: $MD_SIZE) and (max-width: $NEXT_SIZE - 0.2) {
background-color: red;
}
`
Else
`css
container-type: inline-size;
@container (min-width: $MD_SIZE) {
background-color: red;
}
`
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.inline.between(["sm", "md"])} {
background-color: red;
};`
Result
`css
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
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.inline.attrs()};`
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.size.attrs()};`
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.inline.attrs("name")};`
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.size.attrs("name")};`
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.query.attrs("name")};`
Results
`css`
container-type: inline-size;
`css`
container-type: size;
`css`
container-type: inline-size;
container-name: name;
`css`
container-type: size;
container-name: name;
`css`
container-name: name;
> With this method you get queries without type (ex: up, down, only and between)
> Attrs method also can be used)
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.query.up("md")} {
background-color: red;
};`
Result
`css`
@container (min-width: $MD_SIZE) {
background-color: red;
}
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.inline.up("md", "name")} {
background-color: red;
};`
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.inline.between(["sm", "md"], "name")} {
background-color: red;
};`
Results
`css
container-type: inline-size;
container-name: name;
@container (min-width: $MD_SIZE) {
background-color: red;
}
`
`css
container-type: inline-size;
container-name: name;
@container (min-width: $SM_SIZE) and (max-width: $MD_SIZE - 0.2) {
background-color: red;
}
`
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.inline.up("md", ".context")} {
background-color: red;
};`
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.inline.between(["sm", "md"], ".context")} {
background-color: red;
};`
Results
`css
container-type: inline-size;
@container context (min-width: $MD_SIZE) {
background-color: red;
}
`
`css
container-type: inline-size;
@container context (min-width: $SM_SIZE) and (max-width: $MD_SIZE - 0.2) {
background-color: red;
}
`
#### 1. Simple example
`tsx
const Container = styled.div
width: 100%;
${({ theme }) => theme.container.inline.up("md", "name.context")} {
background-color: red;
};`
`tsx
const Container = styled.div
width: 100%;
${({ theme }) =>
theme.container.inline.between(["sm", "md"], "name.context")} {
background-color: red;
};`
Results
`css
container-type: inline-size;
container-nane: name;
@container context (min-width: $MD_SIZE) {
background-color: red;
}
`
`css
container-type: inline-size;
container-name: name;
@container context (min-width: $SM_SIZE) and (max-width: $MD_SIZE - 0.2) {
background-color: red;
}
`
#### 2. Complex example
styled.ts
`tsx
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
`tsx
import * as S from "./styled.ts";
const Component = () => ( container sub-sub-container
);
`
Result

To contribute, make sure to follow the steps bellow:
1. Create a new branch:
`shell`
git checkout -b feat/your-new-feature
2. Make your changes, add unit tests (with jest) and test with npm link
On styled-container-queries project:
`shell`
npm link
On your app/project:
`shell`
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
3. Before to push your changes to origin, open your pull request and fill all required fields.
1. Make sure to fill the Release section with what your pull request changes. This section is required to merge pull request.
4. Set a _required_ semver label according to your change:semver:patch
1. : used when you submit a fix to a bug, enhance performance, etc;semver:minor
2. : used when you submit a new component, new feature, etc;semver:major
3. : used when you submit some breaking change, etc;semver:prerelease
4. : 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.
5.
> Info: Once you have merged your pull request, with all required fields, GitHub Actions will be responsible to create a new build and publish on stage environment.
MIT License