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
styled
styled
styled
props
build in
styledSystem
build in
build in
build in
action props
ThemeProvider
props.theme
useTheme
injectGlobal
alpha
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';