{"id":2825,"date":"2021-05-10T14:34:23","date_gmt":"2021-05-10T14:34:23","guid":{"rendered":"https:\/\/rengga.dev\/blog\/?p=2825"},"modified":"2023-02-28T04:40:50","modified_gmt":"2023-02-28T04:40:50","slug":"css-tutorial-conditionally-styling-selected-elements-in-a-grid-container","status":"publish","type":"post","link":"https:\/\/rengga.dev\/blog\/css-tutorial-conditionally-styling-selected-elements-in-a-grid-container\/","title":{"rendered":"CSS Tutorial &#8211; Conditionally Styling Selected Elements in a Grid Container"},"content":{"rendered":"<p>Calendars, shopping carts, galleries, file explorers, and online libraries are some situations where selectable items are shown in grids (i.e. square lattices). You know, even those security checks that ask you to select all images with crosswalks or whatever.<\/p>\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-366253 jetpack-lazy-image jetpack-lazy-image--handled aligncenter\" src=\"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2022\/06\/catpcha-crosswalks.png?resize=302%2C461&amp;ssl=1\" sizes=\"auto, (min-width: 735px) 864px, 96vw\" srcset=\"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2022\/06\/catpcha-crosswalks.png?w=402&amp;ssl=1 402w, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2022\/06\/catpcha-crosswalks.png?resize=196%2C300&amp;ssl=1 196w\" alt=\"\" width=\"302\" height=\"461\" data-recalc-dims=\"1\" data-lazy-loaded=\"1\" \/><\/figure>\n<p>I found a neat way to display selectable options in a grid. No, not recreating that reCAPTCHA, but simply being able to select multiple items. And when two or more adjoining items are selected, we can use clever\u00a0<code>:nth-of-type<\/code>\u00a0combinators, pseudo elements, and the\u00a0<code>:checked<\/code>\u00a0pseudo-class to style them in a way where they look grouped together.<br \/>\n<iframe style=\"width: 100%;\" title=\"CSS Tutorial - Conditionally Styling Selected Elements in a Grid Container\" src=\"https:\/\/codepen.io\/renggagumilar\/embed\/bGvjxyo?default-tab=result&amp;theme-id=dark\" height=\"600\" frameborder=\"no\" scrolling=\"no\" allowfullscreen=\"allowfullscreen\"><br \/>\nSee the Pen <a href=\"https:\/\/codepen.io\/renggagumilar\/pen\/bGvjxyo\"><br \/>\nCSS Tutorial &#8211; Conditionally Styling Selected Elements in a Grid Container<\/a> by Rengga Gumilar (<a href=\"https:\/\/codepen.io\/renggagumilar\">@renggagumilar<\/a>)<br \/>\non <a href=\"https:\/\/codepen.io\">CodePen<\/a>.<br \/>\n<\/iframe><\/p>\n<h3>HTML<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"html\">&lt;h4&gt;click or tap on any adjacent boxes&lt;\/h4&gt;\r\n&lt;main&gt;\r\n    &lt;input type=checkbox&gt; \r\n    &lt;input type=checkbox&gt; \r\n    &lt;input type=checkbox&gt; \r\n    &lt;input type=checkbox&gt; \r\n    &lt;input type=checkbox&gt;\r\n    &lt;input type=checkbox checked&gt;\r\n    &lt;input type=checkbox checked&gt; \r\n    &lt;input type=checkbox&gt; \r\n    &lt;input type=checkbox&gt; \r\n    &lt;input type=checkbox&gt;\r\n    &lt;input type=checkbox&gt;\r\n    &lt;input type=checkbox&gt; \r\n    &lt;input type=checkbox&gt; \r\n    &lt;input type=checkbox&gt; \r\n    &lt;input type=checkbox&gt;\r\n    &lt;input type=checkbox&gt;\r\n    &lt;input type=checkbox&gt; \r\n    &lt;input type=checkbox&gt; \r\n    &lt;input type=checkbox&gt; \r\n    &lt;input type=checkbox&gt;\r\n&lt;\/main&gt;<\/pre>\n<h3>CSS<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"css\">input {\r\n    display: grid;\r\n    width: 60px; height: 40px; margin: 0;\r\n    appearance: none; -webkit-appearance: none; \r\n    cursor: pointer;\r\n    background: #ddd;\r\n    border-radius: 20px;\r\n}\r\n\r\ninput:not(:nth-of-type(4n+1))::before,\r\ninput:nth-of-type(n+5)::after {\r\n    content: '';\t\r\n    border-radius: 20px;\r\n    pointer-events: none;\r\n    grid-area: 1\/1;\r\n}\r\n\r\ninput:not(:nth-of-type(4n+1))::before { transform: translatex(-85px); }\r\n\r\ninput:nth-of-type(n+5)::after { transform: translatey(-60px); }\r\n\r\ninput:checked { background: limegreen; }\r\n\r\n\/* a checked box's right borders *\/\r\ninput:not(:nth-of-type(4n)):checked + input:checked::before { \r\n    border-top-right-radius: 0; \r\n    border-bottom-right-radius: 0; \r\n    background: limegreen;\r\n}\r\n\/* a checked box's bottom borders *\/\r\ninput:nth-last-of-type(n+5):checked + * + * + * + input:checked::after {\r\n    border-bottom-right-radius: 0;\r\n    border-bottom-left-radius: 0;\r\n    background: limegreen;\r\n}\r\n\/* a checked box's adjacent (rightside) checked box's left borders *\/\r\ninput:not(:nth-of-type(4n)):checked + input:checked + input::before { \t\r\n    border-top-left-radius: 0; \r\n    border-bottom-left-radius: 0; \r\n    background: limegreen;\r\n}\r\n\/* a checked box's adjacent (below) checked box's top borders *\/\r\ninput:not(:nth-of-type(4n)):checked + * + * + * +  input:checked + input::before { \r\n    border-top-left-radius: 0; \r\n    border-top-right-radius: 0; \r\n    background: limegreen;\r\n}\r\n\/* a checked box's (in last column) left borders *\/\r\ninput:nth-of-type(4n-1):checked + input:checked {\r\n    border-top-left-radius: 0;\r\n    border-bottom-left-radius: 0;\r\n}\r\n\/* a checked box's (in last column) adjacent (below) checked box's top borders *\/\r\ninput:nth-of-type(4n):checked + * + * + * + input:checked {\r\n    border-top-left-radius: 0;\r\n    border-top-right-radius: 0;\r\n}\r\n\r\nmain {\r\n    display: grid;\r\n    grid:  repeat(5, 60px) \/ repeat(4, 85px);\r\n    align-items: center; justify-items: center;\r\n    margin: 0;\r\n}\r\nh4 {\r\n    font-family: courier new;\r\n    margin:0;\r\n    margin-bottom: 10px;\r\n    color:  darkslategray;\r\n}\r\nbody {\r\n    display: grid;\r\n    grid-template-rows: min-content min-content;\r\n    margin-top: 25vh;\r\n    align-items: center; justify-items: center;\r\n    user-select: none; -webkit-user-select:  none;\r\n    -webkit-tap-highlight-color: transparent;\r\n}<\/pre>\n<h2 id=\"putting-it-to-use\">Putting it to use<\/h2>\n<p>What we just looked at is the general principle and logic behind the design. Again, how useful it is in your application will depend on the grid design.<\/p>\n<p>I used rounded borders, but you can try other shapes or even experiment with background effects (Temani has you covered for ideas). Now that you know how the formula works, the rest is totally up to your imagination.<\/p>\n<p>Here\u2019s an instance of how it might look in a simple calendar:<br \/>\n<iframe style=\"width: 100%;\" title=\"CSS Tutorial - Conditionally Styling Selected Elements in a Grid Container Calender\" src=\"https:\/\/codepen.io\/renggagumilar\/embed\/jOzpvgx?default-tab=result&amp;theme-id=dark\" height=\"600\" frameborder=\"no\" scrolling=\"no\" allowfullscreen=\"allowfullscreen\"><br \/>\nSee the Pen <a href=\"https:\/\/codepen.io\/renggagumilar\/pen\/jOzpvgx\"><br \/>\nCSS Tutorial &#8211; Conditionally Styling Selected Elements in a Grid Container Calender<\/a> by Rengga Gumilar (<a href=\"https:\/\/codepen.io\/renggagumilar\">@renggagumilar<\/a>)<br \/>\non <a href=\"https:\/\/codepen.io\">CodePen<\/a>.<br \/>\n<\/iframe><br \/>\nAgain, this is merely a rough prototype using static markup. And, there would be lots and lots of accessibility considerations to consider in a calendar feature.<\/p>\n<hr class=\"wp-block-separator\" \/>\n<p>That\u2019s a wrap! Pretty neat, right? I mean, there\u2019s nothing exactly \u201cnew\u201d about what\u2019s happening. But it\u2019s a good example of\u00a0<em>selecting things<\/em>\u00a0in CSS. If we have a handle on more advanced selecting techniques that use combinators and pseudos, then our styling powers can reach far beyond the styling one item \u2014 as we saw, we can conditionally style items based on the state of another element.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Calendars, shopping carts, galleries, file explorers, and online libraries are some situations <a class=\"read-more\" href=\"https:\/\/rengga.dev\/blog\/css-tutorial-conditionally-styling-selected-elements-in-a-grid-container\/\" title=\"CSS Tutorial &#8211; Conditionally Styling Selected Elements in a Grid Container\" itemprop=\"url\"><\/a><\/p>\n","protected":false},"author":1,"featured_media":3819,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[207,200,197,206],"newstopic":[],"class_list":{"0":"post-2825","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-html-css","8":"tag-css-calender","9":"tag-css-code","10":"tag-css-tutorial","11":"tag-grid-container"},"_links":{"self":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts\/2825","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/comments?post=2825"}],"version-history":[{"count":3,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts\/2825\/revisions"}],"predecessor-version":[{"id":2828,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/posts\/2825\/revisions\/2828"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/media\/3819"}],"wp:attachment":[{"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/media?parent=2825"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/categories?post=2825"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/tags?post=2825"},{"taxonomy":"newstopic","embeddable":true,"href":"https:\/\/rengga.dev\/blog\/wp-json\/wp\/v2\/newstopic?post=2825"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}