Group selectors allow child elements to respond to interactions on a parent element. This is useful for creating interactive cards, list items, and other composite components.
Add role="group" to a parent element, then use _groupHover, _groupFocus, or _groupActive on children:
1<Box bg="$background" borderRadius="8px" p={4} role="group"> 2 <Text _groupHover={{ color: '$primary' }}> 3 This text changes color when parent is hovered 4 </Text> 5 <Box _groupHover={{ bg: '$primaryAlpha10' }} p={2}> 6 This box changes background on parent hover 7 </Box> 8</Box>1<Box bg="$background" borderRadius="8px" p={4} role="group"> 2 <Text _groupHover={{ color: '$primary' }}> 3 This text changes color when parent is hovered 4 </Text> 5 <Box _groupHover={{ bg: '$primaryAlpha10' }} p={2}> 6 This box changes background on parent hover 7 </Box> 8</Box>
| Selector | Triggered when |
|---|---|
_groupHover | Parent with |
_groupFocus | Parent with |
_groupActive | Parent with |
_groupFocusWithin | Any element inside the group receives focus |
1<Box 2 _hover={{ boxShadow: '0 4px 12px rgba(0,0,0,0.15)' }} 3 bg="white" 4 borderRadius="8px" 5 boxShadow="0 1px 3px rgba(0,0,0,0.1)" 6 cursor="pointer" 7 p={4} 8 role="group" 9> 10 <Box 11 bg="$backgroundMuted" 12 borderRadius="4px" 13 h="200px" 14 overflow="hidden" 15 w="100%" 16 > 17 <Image 18 _groupHover={{ transform: 'scale(1.05)' }} 19 src="/image.jpg" 20 transition="transform 0.2s" 21 /> 22 </Box> 23 24 <Text _groupHover={{ color: '$primary' }} fontWeight={600} mt={3}> 25 Card Title 26 </Text> 27 28 <Text color="$textMuted" fontSize="14px"> 29 Card description goes here 30 </Text> 31 32 <Box 33 _groupHover={{ opacity: 1 }} 34 mt={3} 35 opacity={0} 36 transition="opacity 0.2s" 37 > 38 <Button>View Details</Button> 39 </Box> 40</Box>1<Box 2 _hover={{ boxShadow: '0 4px 12px rgba(0,0,0,0.15)' }} 3 bg="white" 4 borderRadius="8px" 5 boxShadow="0 1px 3px rgba(0,0,0,0.1)" 6 cursor="pointer" 7 p={4} 8 role="group" 9> 10 <Box 11 bg="$backgroundMuted" 12 borderRadius="4px" 13 h="200px" 14 overflow="hidden" 15 w="100%" 16 > 17 <Image 18 _groupHover={{ transform: 'scale(1.05)' }} 19 src="/image.jpg" 20 transition="transform 0.2s" 21 /> 22 </Box> 23 24 <Text _groupHover={{ color: '$primary' }} fontWeight={600} mt={3}> 25 Card Title 26 </Text> 27 28 <Text color="$textMuted" fontSize="14px"> 29 Card description goes here 30 </Text> 31 32 <Box 33 _groupHover={{ opacity: 1 }} 34 mt={3} 35 opacity={0} 36 transition="opacity 0.2s" 37 > 38 <Button>View Details</Button> 39 </Box> 40</Box>
1<Box as="ul" listStyle="none" m={0} p={0}> 2 {items.map((item) => ( 3 <Box 4 key={item.id} 5 _hover={{ bg: '$backgroundMuted' }} 6 as="li" 7 borderBottom="1px solid $border" 8 p={3} 9 role="group" 10 > 11 <Flex align="center" justify="space-between"> 12 <Text _groupHover={{ color: '$primary' }}>{item.title}</Text> 13 <Box _groupHover={{ opacity: 1 }} opacity={0}> 14 <Button size="sm">Edit</Button> 15 </Box> 16 </Flex> 17 </Box> 18 ))} 19</Box>1<Box as="ul" listStyle="none" m={0} p={0}> 2 {items.map((item) => ( 3 <Box 4 key={item.id} 5 _hover={{ bg: '$backgroundMuted' }} 6 as="li" 7 borderBottom="1px solid $border" 8 p={3} 9 role="group" 10 > 11 <Flex align="center" justify="space-between"> 12 <Text _groupHover={{ color: '$primary' }}>{item.title}</Text> 13 <Box _groupHover={{ opacity: 1 }} opacity={0}> 14 <Button size="sm">Edit</Button> 15 </Box> 16 </Flex> 17 </Box> 18 ))} 19</Box>
1<Box as="nav"> 2 <Box 3 _hover={{ bg: '$backgroundMuted' }} 4 borderRadius="4px" 5 p={2} 6 role="group" 7 > 8 <Flex align="center" gap={2}> 9 <Box 10 _groupHover={{ bg: '$primary' }} 11 bg="$textMuted" 12 borderRadius="50%" 13 h="8px" 14 w="8px" 15 /> 16 <Text _groupHover={{ color: '$primary' }}>Menu Item</Text> 17 <Box _groupHover={{ opacity: 1 }} ml="auto" opacity={0}> 18 → 19 </Box> 20 </Flex> 21 </Box> 22</Box>1<Box as="nav"> 2 <Box 3 _hover={{ bg: '$backgroundMuted' }} 4 borderRadius="4px" 5 p={2} 6 role="group" 7 > 8 <Flex align="center" gap={2}> 9 <Box 10 _groupHover={{ bg: '$primary' }} 11 bg="$textMuted" 12 borderRadius="50%" 13 h="8px" 14 w="8px" 15 /> 16 <Text _groupHover={{ color: '$primary' }}>Menu Item</Text> 17 <Box _groupHover={{ opacity: 1 }} ml="auto" opacity={0}> 18 → 19 </Box> 20 </Flex> 21 </Box> 22</Box>
Group selectors can be combined with responsive arrays:
1<Box p={[2, null, 4]} role="group"> 2 <Text 3 _groupHover={{ 4 color: ['$primary', null, '$secondary'], 5 fontSize: ['16px', null, '18px'], 6 }} 7 > 8 Responsive group hover 9 </Text> 10</Box>1<Box p={[2, null, 4]} role="group"> 2 <Text 3 _groupHover={{ 4 color: ['$primary', null, '$secondary'], 5 fontSize: ['16px', null, '18px'], 6 }} 7 > 8 Responsive group hover 9 </Text> 10</Box>
For nested groups, the selector applies to the nearest parent with role="group":
1<Box bg="white" p={4} role="group"> 2 <Text _groupHover={{ color: 'blue' }}>Responds to outer group</Text> 3 4 <Box bg="$backgroundMuted" mt={2} p={2} role="group"> 5 <Text _groupHover={{ color: 'red' }}>Responds to inner group</Text> 6 </Box> 7</Box>1<Box bg="white" p={4} role="group"> 2 <Text _groupHover={{ color: 'blue' }}>Responds to outer group</Text> 3 4 <Box bg="$backgroundMuted" mt={2} p={2} role="group"> 5 <Text _groupHover={{ color: 'red' }}>Responds to inner group</Text> 6 </Box> 7</Box>
1<Box role="group"> 2 <Box _groupHover={{ bg: 'red' }} /> 3</Box>1<Box role="group"> 2 <Box _groupHover={{ bg: 'red' }} /> 3</Box>
Generates CSS like:
1[role='group']:hover .a { 2 background-color: red; 3}1[role='group']:hover .a { 2 background-color: red; 3}
role="group" to semantically appropriate elementstransition prop for smooth state changes