styled-svelte is a way to create Svelte components that have styles attached to them. It's available from styled-svelte. styled was heavily inspired by @emotion/styled and styled-components
styledstyledstyled propsbuild instyledSystem build inbuild inbuild in action propsThemeProvider props.theme useThemeinjectGlobalalpha darker lighten and morecss cx cache and moreGet up and running with a single import.
npm install --save styled-svelte
import styled from 'styled-svelte';
const Div = styled.div`
padding: 10px 20px;
`;
const Button = styled.button`
color: #333;
border: none;
outline: none;
padding: 10px 20px;
cursor: pointer;
backgroundcolor: #e8e8e8;
&:hover {
backgroundcolor: #d8d8d8;
}
`;
Use them like any other Svelte component – except they're styled!
<Div>
<Button>Click</Button>
</Div>
The styled function accepts tag and styles as a object or template string and returns a svelte component.
styled with html tag or component. and used object styles.
import styled from 'styled-svelte';
const Button = styled('button', {
color: '#333',
border: 'none',
outline: 'none',
padding: '10px 20px',
cursor: 'pointer',
backgroundColor: '#e8e8e8',
'&:hover': {
backgroundColor: '#d8d8d8',
},
});
styled with object styles. except you call it with an html tag
const Button = styled.button({
color: '#333',
border: 'none',
outline: 'none',
padding: '10px 20px',
cursor: 'pointer',
backgroundColor: '#e8e8e8',
'&:hover': {
backgroundColor: '#d8d8d8',
},
});
styled with css styles, except you call it with an html tag
import styled from 'styled-svelte';
const Button = styled.button`
color: #333;
border: none;
outline: none;
padding: 10px 20px;
cursor: pointer;
backgroundcolor: #e8e8e8;
&:hover: {
backgroundcolor: #d8d8d8;
}
`;
import styled from 'styled-svelte';
const Button = styled('button', {
color: '#333',
border: 'none',
outline: 'none',
padding: '10px 20px',
cursor: 'pointer',
backgroundColor: '#e8e8e8',
'&:hover': {
backgroundColor: '#d8d8d8',
},
});
const NewButton = styled(Button, {
color: '#fff',
padding: '10px 32px',
backgroundColor: '#333',
'&:hover': {
backgroundColor: '#444',
},
});
import styled, { type AnyProperties } from 'styled-svelte';
// Object Styles function return object
const Button = styled('button', (props: AnyProperties) => ({
color: props.color,
border: 'none',
outline: 'none',
padding: '10px 20px',
cursor: 'pointer',
backgroundColor: '#e8e8e8',
'&:hover': {
backgroundColor: '#d8d8d8',
},
}));
// OR
const Button = styled.button((props: AnyProperties) => ({
color: props.color,
border: 'none',
outline: 'none',
padding: '10px 20px',
cursor: 'pointer',
backgroundColor: '#e8e8e8',
'&:hover': {
backgroundColor: '#d8d8d8',
},
}));
// Object Styles function return string (look like css)
const Button = styled(
'button',
(props: AnyProperties) => `
color: ${props.color};
border: none;
outline: none;
padding: 10px 20px;
cursor: pointer;
background-color: #e8e8e8;
&:hover {
background-color: #d8d8d8;
}
`
);
// OR
const Button = styled.button(
(props: AnyProperties) => `
color: ${props.color};
border: none;
outline: none;
padding: 10px 20px;
cursor: pointer;
background-color: #e8e8e8;
&:hover {
background-color: #d8d8d8;
}
`
);
import styled, { type AnyProperties } from 'styled-svelte';
// Css Styles with Props (function return props)
const Button = styled.button`
color: ${(props: AnyProperties) => props.color};
border: none;
outline: none;
padding: 10px 20px;
cursor: pointer;
backgroundcolor: #e8e8e8;
&:hover: {
backgroundcolor: #d8d8d8;
}
`;
Use
<Button color="#333">Click</Button>
Output in HTML
<button class="styled-1hfd8np">Click</button>
*Overide styled API
*Build in props for every component
*Padding and Margin multiply by 8
p props p={2} eq. padding: 16px;
p={[2]} eq. padding: 16px;
p={[2,4]} eq. padding: 16px 32px;
p={[2,4,1]} eq. padding: 16px 32px 8px;
p={[2,4,1,0]} eq. padding: 16px 32px 8px 0px;
pt props pt={2} eq. padding-top: 16px;
pr props pr={2} eq. padding-right: 16px;
pb props pb={2} eq. padding-bottom: 16px;
pl props pl={2} eq. padding-left: 16px;
px props px={2} eq. padding-left: 16px; padding-right: 16px;
py props py={2} eq. padding-top: 16px; padding-bottom: 16px;
m props m={2} eq. margin: 16px;
m={[2]} eq. margin: 16px;
m={[2,4]} eq. margin: 16px 32px;
m={[2,4,1]} eq. margin: 16px 32px 8px;
m={[2,4,1,0]} eq. margin: 16px 32px 8px 0px;
mt props mt={2} eq. margin-top: 16px;
mr props mr={2} eq. margin-right: 16px;
mb props mb={2} eq. margin-bottom: 16px;
ml props ml={2} eq. margin-left: 16px;
mx props mx={2} eq. margin-left: 16px; margin-right: 16px;
my props my={2} eq. margin-top: 16px; margin-bottom: 16px;
className props className="btn"
*(Styles Object OR Styles Object with Props)
sx props sx={{color:'#333',padding:'16px'}} eq. color: #333; padding: '16px';
sx props sx={(props)=>({color:props.theme[props.theme.mode].color.primary,padding:'16px'})} eq. color: #1976d2; padding: '16px';
Remark: props.theme work with ThemeProvider only
<script lang="ts">
import styled from 'styled-svelte';
const Button = styled('button', {
color: '#333',
border: 'none',
outline: 'none',
padding: '10px 20px',
cursor: 'pointer',
backgroundColor: '#e8e8e8',
'&:hover': {
backgroundColor: '#d8d8d8',
},
});
</script>
<!-- Default use-->
<Button>Click<Button>
<!-- You can do this: Styles in Component -->
<Button p={[2,4]} m={0.5} sx={{color:'#fff',backgroundColor:'#333',
'&:hover':{backgroundColor:'#555'}}}>Click Me</Button>
<!-- OR Sx with Props -->
<Button p={[2,4]} m={0.5} sx={(props)=>({color:props.theme[props.theme.mode].color.primary,backgroundColor:'#333',
'&:hover':{backgroundColor:'#555'}})}>Click Me</Button>
<Button subffix="mybtn">Click</Button>
Output in HTML
<button class="styled-1hfd8np-mybtn">Click</button>
<Button className="btn">Click</Button>
Output in HTML
<button class="btn styled-1hfd8np">Click</button>
Remark: btn class from other css library (if you want to overide)
<Button
styledSystem
color="#333"
border="none"
outline="none"
padding="10px 20px"
cursor="pointer"
backgroundColor="#e8e8e8">Click
</Button>
The other props you can used theme. please see Other props in Component
*If styledSystem={true}, the other props you can used. build in, require string
alignItems alignSelf background backgroundColor backgroundImage backgroundPosition backgroundRepeat border borderColor borderWidth borderStyle borderRadius bottom boxShadow boxSizing color columns columnGap columnSpan cursor direction display flexBasis flexDirection flexGrow flexShrink flexWrap float font fontFamily fontStyle fontWeight gap grid gridArea gridAutoColumns gridAutoFlow gridAutoRows gridGap gridRow gridTemplateAreas gridTemplateColumns gridTemplateRows height justifyContent justifyItems justifySelf left letterSpacing listStyle lineHeight margin marginTop marginRight marginBottom marginLeft maxHeight maxWidth minHeight minWidth objectFit objectPosition opacity outline overflow overflowX overflowY padding paddingTop paddingRight paddingBottom paddingLeft position pointerEvents right rotate rowGap scale scrollBehavior textAlign textDecoration textIndent textJustify textOverflow textShadow textTransform top transform transition translate verticalAlign visibility whiteSpace width wordBreak wordSpacing zIndex
Build in forwordRefEvents for every component created by styled api
Build in action events props for every component created by styled api
<MyComponent action={myAction}/>
<ThemeProvider {theme}></ThemeProvider><script lang="ts">
// src/Main.svelte
import { ThemeProvider } from 'styled-svelte';
import App from './App.svelte';
import { themePallete } from './theme/themePallete';
</script>
<ThemeProvider theme={themePallete}>
<App />
</ThemeProvider>
// src/main.ts
import Main from './Main.svelte';
const main = new Main({
target: document.getElementById('app'), // vite
// target: document.body, // rollup
});
export default main;
// src/theme/themePallete.ts
// Example theme pallete
export type ThemePallete = {
light: Pallete;
dark: Pallete;
mode: string;
};
type Pallete = {
color: {
primary: string;
secondary: string;
error: string;
warning: string;
info: string;
success: string;
};
background: {
primary: string;
secondary: string;
};
text: {
primary: string;
secondary: string;
disable: string;
};
};
export const themePallete: ThemePallete = {
light: {
color: {
primary: '#1976d2',
secondary: '#9c27b0',
error: '#df2f2f',
warning: '#ed6c02',
info: '#0288d1',
success: '#2e7d36',
},
background: {
primary: '#fff',
secondary: '#f8f8f8',
},
text: {
primary: '#000000de',
secondary: '#00000099',
disable: '#00000061',
},
},
dark: {
color: {
primary: '#90caf9',
secondary: '#ce93d8',
error: '#f44336',
warning: '#ffa726',
info: '#29b6f6',
success: '#66bb6a',
},
background: {
primary: '#121212',
secondary: '#1f1f1f',
},
text: {
primary: '#fff',
secondary: '#ffffffb3',
disable: '#ffffff80',
},
},
mode: 'light',
};
props.theme or useTheme()<script lang="ts">
import styled, { type Props, useTheme, alpha } from 'styled-svelte';
import type { ThemePallate } from './theme/themePallete';
// Object Styles, access theme from Props and assign Types on styled
const Button = styled<ThemePallete>('button', (props) => ({
color: props.theme[props.theme.mode].color.primary,
border: 'none',
outline: 'none',
padding: '10px 20px',
cursor: 'pointer',
backgroundColor: alpha(props.theme[props.theme.mode].color.primary, 0.6),
'&:hover': {
backgroundColor: alpha(props.theme[props.theme.mode].color.primary, 0.5),
},
}));
// OR Access theme from Props and assign Types on props
const Button = styled('button', (props: Props<ThemePallete>) => ({
//
}));
// Css Styles, access theme from Props and assign Types on props
const Button = styled.button`
color: ${(props:Props<ThemePallete>) => props.theme[props.theme.mode].color.primary};
border: none;
outline: none;
padding: 10px 20px;
cursor: pointer;
backgroundColor: ${(props/*:Props<ThemePallete>*/) => alpha(props.theme[props.theme.mode].color.primary, 0.6)};
&:hover {
backgroundColor: ${(props/*:Props<ThemePallete>*/) => alpha(props.theme[props.theme.mode].color.primary, 0.5)};
}
}`;
// OR useTheme() API
const theme = useTheme();
const Button = styled('button', {
color: $theme[$theme.mode].color.primary,
border: 'none',
outline: 'none',
padding: '10px 20px',
cursor: 'pointer',
backgroundColor: $theme[$theme.mode].color.primary,
'&:hover': {
backgroundColor: alpha($theme[$theme.mode].color.primary, 0.2),
},
});
</script>
Remark: props.theme work with ThemeProvider only
<script lang="ts">
const theme = useTheme();
const toggleMode = () => {
theme.update((t) => {
t.mode = t.mode === 'light' ? 'dark' : 'light';
return t;
});
};
</script>
<Button on:click={toggleMode}>Toggle dark mode</Button>;
injectGlobal injects styles into the global scope and is useful for applications such as css resets or font faces.
import { injectGlobal } from 'styled-svelte';
injectGlobal({
'*': {
padding: 0,
margin: 0,
boxSizing: 'border-box',
},
});
import {
alpha,
darker,
lighten,
lightness,
saturate,
grayscale,
whiten,
blacken,
fade,
opaquer,
} from 'styled-svelte';
alpha('#1976d2', 0.8); // #1976d2cc
darker('#1976d2', 0.2); // #145EA8
lighten('#1976d2', 0.2); // #338DE7
lightness('#1976d2', 0.2); // ##000101
saturate('#1976d2', 0.5); // ##0076FF
grayscale('#1976d2'); // #646464
whiten('#1976d2', 0.8); // #2D80D2
blacken('#1976d2', 0.8); // #1964AE
fade('#1976d2', 0.2); // #0576d2cc
opaquer('#1976d2', 0.8); // #1976d2
such as css cx injectGlobal flush hydrate merge getRegisteredStyles keyframes sheet cache can read from @emotion/css
import {
flush,
hydrate,
cx,
merge,
getRegisteredStyles,
injectGlobal,
keyframes,
css,
sheet,
cache
} = from 'styled-svelte';