CSS Grid ±â¹ÝÀ¸·Î ±¸¼ºµÈ À̹ÌÁö °¶·¯¸®¿¡¼ ƯÁ¤ ¿ä¼Ò hover ½Ã ÇØ´ç ¿µ¿ªÀÌ È®ÀåµÇµµ·Ï ±¸ÇöµÈ ÀÎÅÍ·¢¼ÇÀÌ´Ù.
:has() ¼±ÅÃÀÚ¸¦ Ȱ¿ëÇÏ¿© ºÎ¸ð ¿ä¼Ò¿¡¼ ÀÚ½Ä hover »óŸ¦ °¨ÁöÇÏ°í ·¹À̾ƿôÀ» µ¿ÀûÀ¸·Î º¯°æÇÑ´Ù.
À̹ÌÁö´Â °ãÄ¡´Â grid ±¸Á¶¿Í ºñÀ² º¯È¸¦ ÅëÇØ ÀÚ¿¬½º·´°Ô È®ÀåµÇ¸ç ½Ã°¢ÀûÀÎ ¸ôÀÔ°¨À» Á¦°øÇÑ´Ù.
º°µµÀÇ JavaScript ¾øÀÌ ¼ø¼ö CSS¸¸À¸·Î ±¸ÇöµÈ ±¸Á¶·Î, ÃֽŠºê¶ó¿ìÀú ȯ°æ¿¡¼ Ȱ¿ë °¡´ÉÇÑ UI ÆÐÅÏÀÌ´Ù.
@import url(https://fonts.bunny.net/css?family=jura:300,500);
@layer base, demo;
@layer demo {
/* demo code goes here */
.wrapper{
--border-size: 5px;
--border-color: var(--bg-light);
/* default gid columns - note, to animatbale we need to defined them individually */
--grid-cols: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr ;
display: grid;
grid-template-columns: var(--grid-cols);
width:min(100%,800px);
margin-inline: auto;
aspect-ratio: 2/1;
transition: grid 300ms ease-in-out;
counter-reset: --card-counter;
/* define grid columns according to which one has hover */
&:has(:nth-child(1):hover){ --grid-cols: 6fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr; }
&:has(:nth-child(2):hover){ --grid-cols: 1fr 1fr 1fr 6fr 1fr 1fr 1fr 1fr 1fr; }
&:has(:nth-child(3):hover){ --grid-cols: 1fr 1fr 1fr 1fr 1fr 6fr 1fr 1fr 1fr; }
&:has(:nth-child(4):hover){ --grid-cols: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 6fr 1fr; }
& > *{
position: relative;
overflow: hidden;
border-radius: 0 0 0 30%/ 0 0 0 50% ;
&:first-child{
border-radius: 0 0 0 0/ 0 0 0 200px ;
}
corner-shape:notch;
transition: all 300ms ease-in-out;
border: var(--border-size) solid var(--border-color);
background-image: var(--bg-img);
background-size: 450px 100%; /* requires fixed width to maintain size and aspect */
/* remove notch from current and next sibling on hover*/
&:hover,
&:hover + div{
border-radius: 0 0 0 0;
}
/* define grid position - each element overlaps by 1 column */
grid-row: 1;
&:nth-child(1){ grid-column: 1 / span 3; }
&:nth-child(2){ grid-column: 3 / span 3; }
&:nth-child(3){ grid-column: 5 / span 3; }
&:nth-child(4){ grid-column: 7 / span 3; }
/* image counter - could easily be a title */
&::after{
content: counter(--card-counter) ".";
counter-increment: --card-counter;
position: absolute;
top: .5rem;
left: 1rem;
font-size: 2rem;
transition: scale 150ms ease-in-out;
scale: 0;
}
&:hover::after{
scale: 1;
}
}
}
}
/* general styling not relevant for this demo */
@layer base {
* {
box-sizing: border-box;
}
:root {
color-scheme: light dark;
--bg-dark: rgb(16, 24, 40);
--bg-light: rgb(248, 244, 238);
--txt-light: rgb(10, 10, 10);
--txt-dark: rgb(245, 245, 245););
--line-light: rgba(0 0 0 / .25);
--line-dark: rgba(255 255 255 / .25);
--clr-bg: light-dark(var(--bg-light), var(--bg-dark));
--clr-txt: light-dark(var(--txt-light), var(--txt-dark));
--clr-lines: light-dark(var(--line-light), var(--line-dark));
}
body {
background-color: var(--clr-bg);
color: var(--clr-txt);
min-height: 100svh;
margin: 0;
padding: 2rem;
font-family: "Jura", sans-serif;
font-size: 1rem;
line-height: 1.5;
display: grid;
place-items: center;
gap: 2rem;
}
}