v4
Ask or search…
K
Links
💫

Nested selectors (ex $ syntax)

tss-react unlike jss-react doesn't support the $ syntax but is a better alternative.

With the Modern API and makeStyles API

In JSS you can do:
//WARNING: This is legacy JSS code!
{
"parent": {
"padding": 30,
"&:hover $child": {
"backgroundColor": "red"
},
},
"child": {
"backgroundColor": "blue"
}
}
//...
<div className={classes.parent}>
<div className={classes.child}>
Background turns red when the mouse is hovering over the parent
</div>
</div>
This is how you would achieve the same result with tss-react
Modern API
makeStyles
export function MyComponent() {
const { classes } = useStyles();
return (
<div className={classes.parent}>
<div className={classes.child}>
Background turns red when the mouse is hovering over the parent.
</div>
</div>
);
}
const useStyles = tss
.withName("MyComponent") // It's important to set a name in SSR setups
.withNestedSelectors<"child">()
.create(({ classes }) => ({
"parent": {
"padding": 30,
[`&:hover .${classes.child}`]: {
"backgroundColor": "red"
}
},
"child": {
"backgroundColor": "blue"
},
}));
Another example:
export function MyComponent() {
const { classes, cx } = useStyles({ "color": "primary" });
return (
<div className={classes.root}>
<div className={classes.child}>
The Background takes the primary theme color when the mouse is
hovering over the parent.
</div>
<div className={cx(classes.child, classes.small)}>
The Background takes the primary theme color when the mouse is
hovering over the parent. I am smaller than the other child.
</div>
</div>
);
}
const useStyles = tss
.withName("MyComponent")
.withNestedSelectors<"child" | "small">()
.withParams<{ color: "primary" | "secondary" }>()
.create(({ theme, color, classes })=> ({
root: {
padding: 30,
[`&:hover .${classes.child}`]: {
backgroundColor: theme.palette[color].main
}
},
small: {},
child: {
border: "1px solid black",
height: 50,
[`&.${classes.small}`]: {
height: 30
}
}
}));
export function App() {
const { classes } = useStyles();
return (
<div className={classes.parent}>
<div className={classes.child}>
Background turns red when the mouse is hovering over the parent.
</div>
</div>
);
}
const useStyles = makeStyles<void, "child">()(
(_theme, _params, classes) => ({
"parent": {
"padding": 30,
[`&:hover .${classes.child}`]: {
"backgroundColor": "red"
}
},
"child": {
"backgroundColor": "blue"
},
})
);
Another example:
export function App() {
const { classes, cx } = useStyles({ "color": "primary" });
return (
<div className={classes.root}>
<div className={classes.child}>
The Background takes the primary theme color when the mouse is
hovering over the parent.
</div>
<div className={cx(classes.child, classes.small)}>
The Background takes the primary theme color when the mouse is
hovering over the parent. I am smaller than the other child.
</div>
</div>
);
}
const useStyles = makeStyles<
{ color: "primary" | "secondary" },
"child" | "small"
>()((theme, { color }, classes) => ({
"root": {
"padding": 30,
[`&:hover .${classes.child}`]: {
"backgroundColor": theme.palette[color].main
}
},
"small": {},
"child": {
"border": "1px solid black",
"height": 50,
[`&.${classes.small}`]: {
"height": 30
}
}
}));
The render of the above code
WARNING: Nested selectors requires ES6 Proxy support which IE doesn't support. It can't be polyfilled (this will not work) but don't worry, if Proxy is not available on a particular browser, no error will be thrown and TSS will still do its work. Only nested selectors won't work.

withStyles

SSR

NOTE: This does not apply to the Modern API
In SSR setups, on stylesheets using nested selectors, you could end up with warnings like:
Warning: Prop className did not match. Server: "tss-XXX-root-ref" Client: "tss-YYY-root-ref".
Example of error you may run against with Next.js
You can fix this error by providing a unique id when calling makeStyles or withStyles (It will set XXX and YYY).
Short unique identifiers can be generated with this website.
const useStyles = makeStyles<
{ color: "primary" | "secondary" },
"child" | "small"
>({
name: "MyComponent"
+ uniqId: "QnWmDL"
})((theme, { color }, classes) => ({
"root": {
"padding": 30,
[`&:hover .${classes.child}`]: {
"backgroundColor": theme.palette[color].main
}
},
"small": {},
"child": {
"border": "1px solid black",
"height": 50,
[`&.${classes.small}`]: {
"height": 30
}
}
}));
const MyBreadcrumbs = withStyles(
Breadcrumbs,
(theme, _props, classes) => ({
"ol": {
[`& .${classes.separator}`]: {
"color": theme.palette.primary.main
}
}
}),
{
name: "MyBreadcrumbs",
+ uniqId: "vZHt3n"
}
);
withStyles:
const MyDiv = withStyles("div", {
"root": {
/* ... */
}
}, {
name: "MyDiv",
+ uniqId: "xDTt4n"
});