Question
I found this CSS selector and want to understand what the ~ character means:
.copy.check:checked ~ .content {
}
What does the ~ selector do in CSS, and how does it affect which elements are matched?
Short Answer
By the end of this page, you will understand that ~ in CSS is the general sibling combinator. It selects elements that share the same parent and appear after another matching element. You will also see how it differs from other selectors like > and +, and how it is commonly used for UI states such as toggles, checkboxes, and show/hide interactions.
Concept
In CSS, the ~ symbol is called the general sibling combinator.
It is used to select an element that:
- shares the same parent as another element
- appears later in the HTML
- matches the selector on the right side of
~
For example:
A ~ B
This means:
- find an element matching
A - then select every sibling matching
B - but only if those
Belements come afterA
So in your example:
.copy.check:checked ~ .content {
}
CSS is saying:
- find an element with classes
copyandcheck - that element must also be
:checked
Mental Model
Think of siblings in CSS like items in the same row of seats.
- They must be in the same row = same parent element
~means “look to the right”- It can match one or many siblings after the starting element
So if one person in a row raises their hand (:checked), ~ lets you affect people sitting later in the same row.
It does not:
- look backward
- jump into children
- match elements with different parents
A simple way to remember it:
+= the next sibling only~= any later sibling
Syntax and Examples
The core syntax is:
A ~ B {
/* styles */
}
This selects all B elements that:
- are siblings of
A - come after
A - share the same parent
Basic example
<div>
<p class="note">First paragraph</p>
<p>Second paragraph</p>
<p>Third paragraph</p>
</div>
.note ~ p {
color: blue;
}
What gets selected?
- The second paragraph
- The third paragraph
The first paragraph is not selected, because it is the element on the left side of , not the right side.
Step by Step Execution
Consider this HTML and CSS:
<div class="box">
<input type="checkbox" id="menu-toggle" checked>
<label for="menu-toggle">Open menu</label>
<div class="menu">Menu content</div>
</div>
.menu {
display: none;
}
#menu-toggle:checked ~ .menu {
display: block;
}
Here is what happens step by step:
- CSS first looks for an element matching
#menu-toggle:checked. - It finds the checkbox with
id="menu-toggle". - Because the checkbox is checked, the left side of the selector matches.
- CSS then looks for siblings after that checkbox.
- It checks whether any of those later siblings match
.menu.
Real World Use Cases
The ~ selector appears often in UI code where one element controls the style of another nearby element.
Common uses
- Checkbox-based show/hide panels
- Accordion sections
- Dropdown menus without JavaScript
- Mobile navigation toggles
- Form hints or validation messages
- Theme or preference switches
Example: show a help message
<div class="field">
<input type="checkbox" id="help-toggle">
<label for="help-toggle">Show help</label>
<p class="help">Your password should be at least 8 characters.</p>
</div>
.help {
display: none;
}
#help-toggle:checked ~ .help {
: block;
}
Real Codebase Usage
In real projects, developers use ~ when HTML structure makes sibling-based styling convenient.
Common patterns
State-driven UI
A stateful element such as a checkbox, radio button, or input controls later siblings:
.sidebar-toggle:checked ~ .sidebar {
transform: translateX(0);
}
Conditional messages
A validation state on one element affects a related message block:
input:invalid ~ .error-message {
display: block;
}
Progressive enhancement
Even when JavaScript exists, CSS sibling selectors can handle simple visual state changes cleanly.
Why developers like it
- reduces simple JavaScript-driven toggles
- keeps state-based styling in CSS
- works well for small interactive components
Limits in real code
Developers must design the HTML structure carefully. If the controlled element is not a later sibling with the same parent, ~ will not help.
Because of that, teams often combine ~ with:
Common Mistakes
Here are the most common beginner mistakes with ~.
1. Expecting it to match previous siblings
Broken example:
<div>
<div class="content"></div>
<input type="checkbox" id="toggle" checked>
</div>
#toggle:checked ~ .content {
display: block;
}
This does not work because .content comes before #toggle.
Fix
Place .content after the checkbox, or use a different structure.
2. Forgetting that both elements need the same parent
Broken example:
<div>
Comparisons
Here is how ~ compares to related CSS combinators.
| Selector | Meaning | Must be same parent? | Must come after? | Matches how many? |
|---|---|---|---|---|
A B | descendant selector | No | No | any matching descendants |
A > B | child selector | Yes, direct child | No | direct children only |
A + B | adjacent sibling selector | Yes | Yes | next sibling only |
A ~ B | general sibling selector |
Cheat Sheet
A ~ B {
/* styles for later sibling(s) B */
}
Rules
~is the general sibling combinatorBmust come afterAin the HTMLAandBmust share the same parent- it can match multiple later siblings
- it does not match previous siblings
- it does not match children unless they are also siblings in the right place
Common example
input:checked ~ .content {
display: block;
}
Quick comparison
A + B→ next sibling onlyA ~ B→ any later matching siblingA > B→ direct childA B→ any descendant
Easy memory trick
FAQ
What is the ~ symbol called in CSS?
It is called the general sibling combinator.
What does A ~ B mean in CSS?
It selects every B element that is a sibling of A, comes after A, and has the same parent.
What is the difference between + and ~ in CSS?
+ selects only the immediately next sibling. ~ selects any matching siblings that appear later.
Does the ~ selector work on previous siblings?
No. It only works on siblings that come after the first element in the HTML.
Do the elements need the same parent for ~ to work?
Yes. The two elements must be siblings under the same parent element.
Why is :checked ~ .content common in CSS?
It is often used to show, hide, or restyle content based on a checkbox or radio button state without JavaScript.
Can ~ select multiple elements?
Mini Project
Description
Build a simple FAQ toggle using only HTML and CSS. This project demonstrates how the ~ general sibling selector can reveal content when a checkbox is checked. It is a practical example of state-based styling without JavaScript.
Goal
Create a toggleable answer panel that appears when the user checks a checkbox.
Requirements
- Add a checkbox input to control the panel state.
- Add a label that the user can click.
- Add a content block that starts hidden.
- Use the
:checked ~ .contentpattern to show the content. - Keep the checkbox, label, and content under the same parent element.
Keep learning
Related questions
Angular ngClass Conditional Class Binding Explained
Learn how to use Angular ngClass for conditional classes, fix common binding mistakes, and understand why this template error happens.
CSS :not() Selector for Elements Without a Class or Attribute
Learn how to use the CSS :not() selector to target elements that do not have a specific class or attribute, with examples and common pitfalls.
CSS Font Scaling Relative to Container Size: %, em, rem, vw, and Responsive Text
Learn how CSS font scaling really works and how to make text responsive using %, em, rem, vw, clamp(), and media queries.