from official styled components documentation
For complex selector patterns, the ampersand (&) can be used to refer back to the main component. Here are some more examples of its potential usage:
const Thing = styled.div.attrs({ tabIndex: 0 })`
color: blue;
&:hover {
color: red; // <Thing> when hovered
}
& ~ & {
background: tomato; // <Thing> as a sibling of <Thing>, but maybe not directly next to it
}
& + & {
background: lime; // <Thing> next to <Thing>
}
&.something {
background: orange; // <Thing> tagged with an additional CSS class ".something"
}
.something-else & {
border: 1px solid; // <Thing> inside another element labeled ".something-else"
}
`
Answer from Mulli on Stack Overflowfrom official styled components documentation
For complex selector patterns, the ampersand (&) can be used to refer back to the main component. Here are some more examples of its potential usage:
const Thing = styled.div.attrs({ tabIndex: 0 })`
color: blue;
&:hover {
color: red; // <Thing> when hovered
}
& ~ & {
background: tomato; // <Thing> as a sibling of <Thing>, but maybe not directly next to it
}
& + & {
background: lime; // <Thing> next to <Thing>
}
&.something {
background: orange; // <Thing> tagged with an additional CSS class ".something"
}
.something-else & {
border: 1px solid; // <Thing> inside another element labeled ".something-else"
}
`
You can use the ampersand to chain nested selectors.
.btn_1 {
&.full-width {
display: block;
width: 100%;
}
}
You need to reference the current selector using &, otherwise any nested selectors will be interpretated as child selectors.
You are in Javascript here.
'data-ison'='true' is an assignment that is evaluated to true.
so you Code actually means "assign the styles at the key true".
Also, you should always use lowercase data attributes, see this answer https://stackoverflow.com/a/25033330/2438494
Your styled components example in regular CSS would be:
.switch true {
justify-content: flex-end;
}
Try this instead:
const Switch = styled('div')({
cursor: 'pointer',
["&[data-ison='true']"]: {
justifyContent: 'flex-end',
},
});
Should be:
const Switch = styled.div`
cursor: pointer;
&[data-ison='true'] {
justify-content: flex-end;
}
`
You can test this on the editable example:

${Link} is pointing to const Link i.e.: "Hovering my parent changes my style" which gets a class of sc-kAzzGY.
& is kinda like saying "And add this to the current class(es)/id(s)/etc."
So,
.my-class {
some-css: awesomeness;
&:hover {
more-css: extra-cool;
}
}
is equivalent to:
.my-class {
some-css: awesomeness;
}
.my-class:hover {
more-css: extra-cool;
}
Therefore, & points to the containing element const Icon i.e. the speech bubble and gets a class of kDmLky.
When Link is hovered, cause Icon to have fill: rebeccapurple
EDIT:
Just to clarify things a bit more:
When you have a declaration block inside of another declaration block like the example below, that inner declaration block becomes an independent one.
const Icon = styled.svg`
flex: none;
transition: fill 0.25s;
width: 48px;
height: 48px;
${Link}:hover & { // This declaraition block becomes an independent one
fill: rebeccapurple;
}
`;
And the result, in this case, is a declaration block with a selection that says:
When you have a class & which is descendent of the class ${Link} which is in the hover state, apply these rules:
fill: rebeccapurple;
NOTE: ${Link} refers to the Link class and & refers to the Icon class (svg).
${Link}:hover &
Here the ampersand & is the short hand way for referring to the top level component being defined, so I would read it as
${Link}:hover ${Icon}
i.e. it is referring to an Icon component contained inside of a Link component being hovered over
I would also recommend this link to see the more general use case for component selectors with styled components, where it's used in a parent child configuration for selection, and applied to the child