Features
next-yak is a featured packed static CSS-in-JS framework with a minimal runtime aspect.
Table of contents
- Static CSS
- Dynamic styles
- Compatible with utility-first CSS frameworks (e.g. Tailwind)
- Animations
- Mixins
- Automatic CSS variables
- Theming
- CSS Prop
Static CSS
At the heart of next-yak lies the extraction of static CSS. You can write your styles as you normally would with styled-components. During build time, these styles are extracted, and your component is assigned a class that encapsulates these styles.
import { styled } from 'next-yak';
const Headline = styled.h1`
font-size: 2rem;
font-weight: bold;
color: rgba(253, 29, 29, 1);
`;
const Component = () => {
return <Headline>Hello there!</Headline>
}
See transformed output
const Headline = styled.h1`
font-size: 2rem;
font-weight: bold;
color: rgba(253, 29, 29, 1);
`;
Dynamic styles
The static functionality itself is already very useful, but the bread and butter is an easy way to create dynamic styles. Styled-components popularized the approach of using props to drive dynamic CSS parts. With next-yak, you can use the exact same familiar API.
import { css, styled } from 'next-yak';
const Paragraph = styled.p`
background: ${props => props.$primary ? "#BF4F74" : "white"};
${props => props.$primary ?
css`
color: white;
` :
css`
color: #BF4F74
`};
font-size: 2rem;
font-weight: bold;
`;
const Component = () => {
return (
<>
<Paragraph $primary>Hello there primary!</Paragraph>
<Paragraph>Hello there non-primary!</Paragraph>
</>
);
}
The CSS templates create their own class which is referenced during runtime when the function returns them. The other function which returns strings directly without setting new CSS properties, will be changed to a CSS variable, which is set on the element itself directly based on the functions return value.
See transformed output
const Paragraph = styled.p`
background: ${props => props.$primary ? "#BF4F74" : "white"};
${props => props.$primary ?
css`
color: white;
` :
css`
color: #BF4F74;
`}
font-size: 2rem;
font-weight: bold;
`;
Compatible with utility-first CSS frameworks (e.g. Tailwind)
next-yak is fully compatible with utility-first CSS frameworks like Tailwind. Just use the atoms
function to
reference classes from these frameworks.
import { styled, atoms } from 'next-yak';
const Header = styled.nav`
${({$variant}) => $variant === "primary"
? atoms("mx-auto flex max-w-7xl items-center justify-between p-6 lg:px-8")
: atoms("bg-white hover:bg-gray-100 text-gray-800 font-semibold py-2 px-4 border border-gray-400 rounded shadow")
}
`
See transformed output
const Header = styled.nav`
${({$variant}) => $variant === "primary"
? atoms("mx-auto flex max-w-7xl items-center justify-between p-6 lg:px-8")
: atoms("bg-white hover:bg-gray-100 text-gray-800 font-semibold py-2 px-4 border border-gray-400 rounded shadow")
}
`
Animations
In order to create CSS animations, you can use the keyframes
API and specify the keyframes for the animation
you want to create. This can be used in your animation declarations within the same file.
import { keyframes, styled } from 'next-yak';
const fadeIn = keyframes`
0% {
opacity: 0;
}
100% {
opacity: 1;
}
`
const FadeInButton = styled.button`
animation: 1s ${fadeIn} ease-out;
`
See transformed output
const fadeIn = keyframes`
0% {
opacity: 0;
}
100% {
opacity: 1;
}
`
const FadeInButton = styled.button`
animation: 1s ${fadeIn} ease-out;
`
Mixins
Mixins are declarations of the css
utility function. You can declare a variable which holds the css declaration and
use it inside your styled
declarations.
import { css, styled } from 'next-yak';
const mixin = css`
color: green;
`;
const MyComp = styled.div`
background-color: yellow;
${mixin}
`;
You can also make it dynamic, where the props are passed to the mixin.
import { css, styled } from 'next-yak';
const mixin = css`
color: ${(props) => props.$green ? 'green' : 'blue'};
`;
const MyComp = styled.div`
background-color: yellow;
${mixin}
`;
During build time the CSS literal is converted to a class name (or multiple class names) and can be referenced by other CSS styles.
See transformed output
const mixin = css`
color: ${(props) => props.$green ? 'green' : 'blue'};
`;
const MyComp = styled.div`
background-color: yellow;
${mixin}
`;
Automatic CSS variables
You may noticed that we sometimes used css`` and sometimes just a literal string. If the property name is already present and you want to have dynamic values of that property, you can just use literal strings. These get transformed into CSS variables during build time.
import { styled } from 'next-yak';
const Box = styled.div`
font-size: ${props => props.$variant === "primary" ? "2rem" : "1rem" };
color: ${props => props.$color};
display: flex;
`
The value of the CSS variable is set via the style property of the component, ensuring no interference with potential CSS variable names that share the same name.
See transformed output
const Box = styled.div`
font-size: ${props => props.$variant === "primary" ? "2rem" : "1rem" };
color: ${props => props.$color};
display: flex;
`
Theming
As your application grows, theming becomes increasingly important as a shortcut to pass the same values to components.
Next-yak integrates it in a hassle free manner that works for both Server Components and Client Components without
a difference in usage for you. Wrap your root with the ThemeProvider and add a yak.context.ts
file to your root directory
and you're ready to go.
import { cookies } from 'next/headers'
import { cache } from "react";
const hasHighContrast = cache(() => {
const cookieStore = cookies()
return cookieStore.get("highContrast")?.value === "true"
});
export function getYakThemeContext() {
return {
// here we provide a hightContrast to all components
highContrast: hasHighContrast()
}
}
declare module "next-yak" {
export interface YakTheme extends ReturnType<typeof getYakThemeContext> { }
}
Once this context file is in place, you can access the theme props on every component.
import { styled, css } from 'next-yak';
const Button = styled.button`
display: block;
${(props) =>
props.theme.highContrast
? css`
color: #000;
`
: css`
color: #009688;
`}
`;
CSS Prop
We support out of the box the css
prop which is a shorthand for adding styles to an element. Similiar to inline-styles
it allows you to write local styles for certain elements on your page. Differently than inline-styles, it allows you to use
selectors that target wrapped elements.
import { css } from 'next-yak';
const Component = () => {
return <div css={{ color: 'red' }}>Hello there!</div>
}
It's meant for simple styling requirements, where you don't have to think about a name for a specialized component.
TypeScript
To use it with the correct types just add the following line to the top of the file
/** @jsxImportSource next-yak */
import { css } from 'next-yak';
const Component = () => {
return <div css={{ color: 'red' }}>Hello there!</div>
}
Or just add this to your tsconfig.json
and all your css props will have the correct types.
{
"compilerOptions": {
"jsxImportSource": "next-yak"
}
}