CSS visibility is a fundamental property that controls whether elements are visible on a webpage. Understanding how visibility works--and how it differs from other hiding techniques--is essential for building responsive, performant websites. This guide covers everything from basic visibility values to advanced performance optimization with the content-visibility property.
What you'll learn:
- How the CSS visibility property works with different values
- Key differences between visibility: hidden and display: none
- Performance optimization with content-visibility
- Practical code examples and use cases
- Accessibility considerations for each approach
Understanding the CSS Visibility Property
The CSS visibility property controls whether an element is displayed on the page without removing it from the document flow. This property accepts several values, each with distinct behavior affecting how elements render and interact with surrounding content.
Visibility Values Explained
| Value | Behavior | Layout Impact |
|---|---|---|
visible | Element displays normally | Full participation |
hidden | Element invisible but occupies space | Space preserved |
collapse | Hides table/flex elements, removes space | Variable by element type |
inherit | Inherits from parent | Depends on parent |
The visibility property works differently from other CSS hiding techniques because it preserves the element's space in the layout while making the element itself invisible. This behavior makes visibility particularly useful for certain UI patterns where you want to hide content temporarily without shifting surrounding elements.
The visible Value
The visible value is the default state for all elements. When an element has visibility: visible, it displays normally on the page, and users can interact with it as expected. Elements with visibility: visible are focusable and can receive keyboard events, making them fully accessible to users navigating with assistive technologies.
The hidden Value
The visibility: hidden value makes an element invisible while preserving its space in the layout. When you apply this value, the element is not rendered visually, but it continues to occupy the same amount of space as it would when visible.
Key characteristics:
- Element remains in the DOM and layout
- Screen readers cannot discover hidden content
- Cannot receive focus or keyboard events
- Children inherit hidden state (can override with
visibility: visible)
The collapse Value
The visibility: collapse value has specialized behavior:
- Tables: Hides rows/columns and removes their space
- Flex items: Hides element and removes space
- Other elements: Behaves like
hidden
Note: Browser support varies for collapse on non-table elements.
For more advanced CSS selectors like :first-child and :last-child that work alongside visibility patterns, explore our CSS First Child and CSS Last Child guides.
Visibility vs Display: Understanding the Key Differences
One of the most common sources of confusion in CSS is the difference between visibility: hidden and display: none. While both properties can hide elements, they have fundamentally different effects on document layout and rendering performance.
Layout Behavior Comparison
| Aspect | visibility: hidden | display: none |
|---|---|---|
| Space in layout | Preserved | Removed |
| Element in rendering tree | Yes | No |
| Surrounding elements | Do not shift | Shift to fill void |
| Browser performance | Slight overhead | Better for hidden content |
Code Example: Side by Side
/* visibility: hidden - keeps space */
.element-hidden {
visibility: hidden;
}
/* display: none - removes element entirely */
.element-gone {
display: none;
}
<div class="container">
<div class="box visible">Visible</div>
<div class="box visibility-hidden">Hidden but occupies space</div>
<div class="box display-none">Removed entirely</div>
<div class="box visible">Shifts when display:none used</div>
</div>
When you apply display: none, the element is removed from the rendering tree entirely. The browser does not render the element, and it does not occupy any space in the layout. Surrounding elements flow as if the hidden element never existed.
With visibility: hidden, the element remains in the rendering tree and continues to participate in layout calculations. The browser calculates the element's box model and reserves space for it in the layout.
Performance Implications
display: none: Skips all rendering work, but toggling triggers layout recalculationvisibility: hidden: Still participates in layout, but visibility transitions are faster- Performance tip: Use visibility for frequent state changes, display for permanent removal
When combining visibility with animations, understanding the difference between CSS transitions and animations becomes essential for creating smooth visual effects.
Advanced Performance Optimization with content-visibility
The CSS content-visibility property represents a modern approach to optimizing rendering performance for long documents. This property enables dramatic performance improvements by allowing user agents to defer rendering of off-screen content until it approaches the viewport.
What is content-visibility?
With content-visibility: auto, browsers apply layout, style, and paint containment automatically:
- Layout containment: Descendants don't affect external layout
- Style containment: Properties affecting only descendants stay contained
- Paint containment: Descendants don't display outside element bounds
- Size containment: For off-screen elements, browser skips size calculations
Performance Benchmarks
Google's research demonstrates impressive gains:
| Page Type | Before content-visibility | After content-visibility | Improvement |
|---|---|---|---|
| Travel blog | 232ms rendering | 30ms rendering | 7x faster |
| Long article | Baseline | Auto | 50%+ reduction |
| Content feed | Variable | Auto | Significant boost |
Results from web.dev performance testing
Browser Support
| Browser | Version | Status |
|---|---|---|
| Chrome | 85+ | Full support |
| Edge | 85+ | Full support |
| Firefox | 125+ | Full support |
| Safari | 18+ | Full support |
Practical Implementation
/* Apply to section containers */
article, section, .content-chunk {
content-visibility: auto;
contain-intrinsic-size: auto 500px;
}
The contain-intrinsic-size property provides an estimated size for the element when collapsed, preventing layout shifts as users scroll.
Best Use Cases
Ideal for:
- Blog posts with multiple sections
- News article pages
- Documentation pages
- Social media feeds
- Long-scroll landing pages
Avoid for:
- Small UI components
- Frequently changing content
- Above-the-fold content
For additional CSS optimization techniques, including CSS animation delay strategies that improve perceived performance, explore our comprehensive web development services.
1/* Basic visibility toggle for accordion */2.accordion-content {3 visibility: hidden;4 height: 0;5 overflow: hidden;6 transition: visibility 0.3s ease;7}8 9.accordion-content.visible {10 visibility: visible;11 height: auto;12}13 14/* Table row collapse */15tr.collapsed {16 visibility: collapse;17}18 19/* Performance optimization */20.content-section {21 content-visibility: auto;22 contain-intrinsic-size: auto 500px;23}24 25/* Visually hidden but accessible (for screen readers) */26.visually-hidden {27 position: absolute;28 width: 1px;29 height: 1px;30 padding: 0;31 margin: -1px;32 overflow: hidden;33 clip: rect(0, 0, 0, 0);34 white-space: nowrap;35 border: 0;36}Accessibility Considerations
Visibility properties have significant implications for accessibility. Elements hidden with CSS remain in the DOM but may or may not be accessible to assistive technologies depending on which property you use.
Accessibility Behavior Matrix
| Property | Screen Readers | Keyboard Navigation | Find in Page |
|---|---|---|---|
visibility: hidden | Not announced | Cannot focus | Not found |
display: none | Not announced | Cannot focus | Not found |
content-visibility: auto | Announced | Can focus | Found |
opacity: 0 | Announced | Can interact | Found |
When Hiding Should Preserve Accessibility
For content that should remain discoverable by screen readers but invisible to sighted users:
/* Screen reader only content */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
Use cases for sr-only content:
- Skip navigation links (before visible on focus)
- Live region announcements
- Form error messages
- Additional context for screen readers
content-visibility and Accessibility
Unlike visibility: hidden, content-visibility: auto maintains accessibility for off-screen content. Elements remain in the accessibility tree, so screen readers can search for and navigate to content even when it hasn't rendered yet.
Note: If using content-visibility: hidden, add aria-hidden="true" to prevent landmark elements from appearing in the accessibility tree when off-screen.
Understanding how text wrapping affects content accessibility is another important consideration--see our guide on CSS wrap text for best practices.
Choose the right visibility approach for your specific use case
Use visibility: hidden for temporary hiding
Ideal for accordions, collapsible sections, and UI patterns where surrounding content should not shift. Combine with transitions for smooth animations.
Use display: none for complete removal
Appropriate for hidden modals, removed list items, or content that should not affect layout. Be aware of layout recalculation overhead.
Use content-visibility: auto for long pages
Apply to section containers on content-heavy pages. Provides significant performance benefits by deferring off-screen rendering.
Consider accessibility at each step
Test with keyboard navigation and screen readers. Use sr-only patterns when hiding visually but not from assistive technologies.