Many application scenarios require displaying selectable items in the grid, such as calendars, shopping carts, galleries, file browsers, and online libraries, and even security checks that require you to choose all pictures with zebra crossings.
This article introduces a clever way to display optional items in the grid, instead of reCAPTCHA, you can select multiple items. When selecting two or more adjacent projects, we can cleverly design them using :nth-of-type
combiner, pseudo-element, and :checked
pseudo-class to make them look combined.
The idea of this combiner and pseudo-element to implement rounded checkboxes stems from an article I wrote earlier. That's a simple single column design:
This time, however, the rounded corner effect is applied to elements on the vertical and horizontal axes on the grid. You don't need to read my previous post on checkbox styles, because I'm going to cover everything you need to know here. However, if you are interested in a simplified version of what is done in this article, that article is worth a look.
Before you begin…
It will be very useful to note the following points. For example, for simplicity, I used static HTML and CSS in my demo. Depending on your application, you may need to dynamically generate the grid and its items within it. To focus on the effects, I omitted the actual check of the auxiliary function, but in a production environment you definitely need to consider this kind of thing.
Also, I use CSS Grid for layout. I recommend doing this, but it's just a personal preference and your experience may vary. For me, using a grid allows me to easily locate ::before
and ::after
pseudo-elements of the project using sibling selectors.
So, no matter what layout standards you might want to use in your application, make sure the pseudo-elements can still be positioned in CSS and make sure the layout remains the same across different browsers and screens.
Let's get started
As you might have noticed in previous demonstrations, selecting and unchecking the checkbox elements modify the box's design, depending on the selection status of other checkboxes around it. This is because I use the pseudo-element of the adjacent element instead of its own to style each box.
The following figure shows how the ::before
pseudo-element of the box in each column (except the first column) overlaps with the box on their left, and how the ::after
pseudo-element of the box in each row (except the first row) overlaps with the box above.
This is the basic code
Tagging is very simple:
<main></main>
There is more in the initial CSS. But first of all, the grid itself:
/* Grid*/ main { display: grid; grid: repeat(5, 60px) / repeat(4, 85px); align-items: center; justify-items: center; margin: 0; }
This is a grid of five elements and four columns containing check boxes. I decided to clear the default appearance of the checkboxes and then give them my own light grey background and hyper-rounded borders:
/* All check boxes*/ input { -webkit-appearance: none; appearance: none; background: #ddd; border-radius: 20px; cursor: pointer; display: grid; height: 40px; width: 60px; margin: 0; }
Also note that the checkbox itself is also a grid. This is the key to putting its ::before
and ::after
pseudo-elements. Having said that, let's do it now:
/* Pseudo-elements except the first column and the first row*/ input:not(:nth-of-type(4n 1))::before, input:nth-of-type(n 5)::after { content: ''; border-radius: 20px; grid-area: 1 / 1; pointer-events: none; }
We only select pseudo-elements that are not in the checkbox of the first column or row of the grid. input:not(:nth-of-type(4n 1))
starts with the first check box and select ::before
for every four items starting there. But please note that we are talking about :not()
, so what we actually do is skip the ::before
pseudo-element of each fourth checkbox starting from the first. Then, we start with the fifth checkbox and apply the style to the ::after
pseudo-element of each checkbox.
Now we can style the ::before
and ::after
pseudo-elements for each checkbox that is not in the first column or row of the grid, so that they move left or upward respectively, hiding them by default.
/* Pseudo-element except the first column*/ input:not(:nth-of-type(4n 1))::before { transform: translatex(-85px); } /* Pseudo-element except the first line*/ input:nth-of-type(n 5)::after { transform: translatey(-60px); }
Settings: checked state style
Now is the style when the checkbox is in the :checked
state. First, let's give them a color, like a lime green background:
input:checked { background: limegreen; }
A selected box should be able to restyle all adjacent selected boxes. In other words, if we select the 11th check box in the grid, we should also be able to style the boxes above, below, left and right of it.
This is done by positioning the correct pseudo-elements. How do we do this? Well, it depends on the actual number of columns in the grid. If two adjacent boxes are selected in a 5×4 grid, the CSS is as follows:
/* The right boundary of the selected box (if the element to its right is selected)*/ input:not(:nth-of-type(4n)):checked input:checked::before { border-top-right-radius: 0; border-bottom-right-radius: 0; background: limegreen; } /* The lower boundary of the selected box (if the following element is selected)*/ input:nth-last-of-type(n 5):checked * * * input:checked::after { border-bottom-right-radius: 0; border-bottom-left-radius: 0; background: limegreen; } /* The left boundary of the selected box adjacent (right) selected box*/ input:not(:nth-of-type(4n)):checked input:checked input::before { border-top-left-radius: 0; border-bottom-left-radius: 0; background: limegreen; } /* The upper boundary of the selected box (below) selected box*/ input:not(:nth-of-type(4n)):checked * * * input:checked input::before { border-top-left-radius: 0; border-top-right-radius: 0; background: limegreen; }
If you want, you can generate the above code dynamically. However, for a typical grid (such as a picture library), the number of columns will be small and may be a fixed number of items, while rows may continue to increase. Especially if designed for mobile screens. That's why this approach is still an effective approach. If for some reason your application happens to have finite rows and extended columns, consider rotating the grid to sides, because for a series of projects, the CSS Grid arranges them from left to right, top to bottom (i.e. row by row).
We also need to add styles to the last checkbox in the grid - they are not all overlaid by pseudo-elements because they are the last item in each axis.
/* The left boundary of the selected box (last column)*/ input:nth-of-type(4n-1):checked input:checked { border-top-left-radius: 0; border-bottom-left-radius: 0; } /* The upper boundary of the selected box (last column) adjacent (lower) checked box*/ input:nth-of-type(4n):checked * * * input:checked { border-top-left-radius: 0; border-top-right-radius: 0; }
These selectors are tricky! The first one...
input:nth-of-type(4n-1):checked input:checked
...It basically says this:
In the penultimate column, a selected element is next to a selected element.
The calculation method of nth-of-type
is as follows:
<code>4(0) - 1 = 无匹配项4(1) - 1 = 第3 个项目4(2) - 1 = 第7 个项目4(3) - 1 = 第11 个项目等等。</code>
So, we start with the third checkbox and select each fourth checkbox from there. If the check boxes in the sequence are selected, then if they are also selected, we also style the adjacent check boxes.
And this line:
input:nth-of-type(4n):checked * * * input:checked
It's said:
An element, provided that it is selected, directly adjacent to one element, the element is directly adjacent to another element, the element is directly adjacent to another element, and the element is directly adjacent to an element in the selected state.
This means we are selecting each fourth checkbox that is selected. If the check box in the sequence is selected, then if it is also selected, we will style the next fourth check box starting from the check box.
Use it
What we just saw was the general principles and logic behind design. Again, its practicality in your application will depend on the mesh design.
I used rounded borders, but you can try other shapes and even try background effects (Temani gives you ideas). Now that you know how formulas work, the rest depends entirely on your imagination.
Here is what it might look like in a simple calendar:
Again, this is just a rough prototype using static tags. Moreover, there are many auxiliary functions that need to be considered in the calendar function.
That's it! Very clever, right? I mean, nothing completely "new" about what happened. But it is a good example of choosing things in CSS. If we master more advanced selection techniques using combiners and pseudo-elements, our styling capabilities can go beyond styles that only set one item—as we can conditionally style items based on the state of another element.
The above is the detailed content of Conditionally Styling Selected Elements in a Grid Container. For more information, please follow other related articles on the PHP Chinese website!

Custom cursors with CSS are great, but we can take things to the next level with JavaScript. Using JavaScript, we can transition between cursor states, place dynamic text within the cursor, apply complex animations, and apply filters.

Interactive CSS animations with elements ricocheting off each other seem more plausible in 2025. While it’s unnecessary to implement Pong in CSS, the increasing flexibility and power of CSS reinforce Lee's suspicion that one day it will be a

Tips and tricks on utilizing the CSS backdrop-filter property to style user interfaces. You’ll learn how to layer backdrop filters among multiple elements, and integrate them with other CSS graphical effects to create elaborate designs.

Well, it turns out that SVG's built-in animation features were never deprecated as planned. Sure, CSS and JavaScript are more than capable of carrying the load, but it's good to know that SMIL is not dead in the water as previously

Yay, let's jump for text-wrap: pretty landing in Safari Technology Preview! But beware that it's different from how it works in Chromium browsers.

This CSS-Tricks update highlights significant progress in the Almanac, recent podcast appearances, a new CSS counters guide, and the addition of several new authors contributing valuable content.

Most of the time, people showcase Tailwind's @apply feature with one of Tailwind's single-property utilities (which changes a single CSS declaration). When showcased this way, @apply doesn't sound promising at all. So obvio

Deploying like an idiot comes down to a mismatch between the tools you use to deploy and the reward in complexity reduced versus complexity added.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft

Notepad++7.3.1
Easy-to-use and free code editor

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment