WordPress 7.0 just dropped, and the new Block Visibility in WordPress 7.0 features are a massive win for responsive design. For years, we’ve been hacking together custom CSS classes or using third-party plugins just to hide a hero image on mobile or a sidebar on desktop. Now, it’s native. But as with anything in Core, there is a technical “gotcha” regarding how these blocks are rendered that you need to understand before you ship your next update.
The Technical Distinction: DOM vs. CSS
In previous versions, specifically since 6.9, we had a binary choice. You could hide a block entirely using blockVisibility: false in the metadata. This was absolute; the block simply didn’t render in the DOM. It was efficient for performance because the browser never saw the markup.
However, Block Visibility in WordPress 7.0 introduces viewport-based rules (mobile, tablet, desktop) that behave differently. When you hide a block for a specific device, the block is still rendered in the DOM. The actual hiding happens via CSS (display: none). Specifically, WordPress now injects responsive utility classes based on your selection.
Why does this matter? If you are hiding a heavy 10MB video block on mobile via these new viewport settings, the browser still downloads that asset. It just doesn’t show it. For true performance-based exclusion, the global blockVisibility: false is still your best friend.
Decoding the New Metadata Structure
If you are building custom blocks or parsing block markup server-side, your logic likely just broke. The blockVisibility key is no longer a simple boolean. It has evolved into a nested object to support these new breakpoints.
{
"metadata": {
"blockVisibility": {
"viewport": {
"mobile": false,
"tablet": true,
"desktop": true
}
}
}
}
The viewport key is nested specifically to leave room for future rules like user roles or time-based visibility, which are expected in WordPress 7.1. You can follow the progress on the official Gutenberg issue #75707.
Refactoring Your Server-Side Logic
If your theme or plugin transforms block markup on the server, you probably have code that checks if $metadata['blockVisibility'] === false. In WordPress 7.0, that check will fail because the value might now be an array. You need to refactor your code to handle both the legacy scalar value and the new object.
Here is how I’ve been handling the refactor in my recent client projects to ensure compatibility:
<?php
/**
* Safely check if a block should be visible based on WP 7.0 metadata.
*
* @param array $block_attributes The block attributes array.
* @return bool
*/
function bbioon_is_block_visible_server_side( $block_attributes ) {
$metadata = $block_attributes['metadata'] ?? [];
if ( ! isset( $metadata['blockVisibility'] ) ) {
return true;
}
// Handle legacy boolean (WP 6.9 style)
if ( is_bool( $metadata['blockVisibility'] ) ) {
return $metadata['blockVisibility'];
}
// Handle WP 7.0 viewport object
if ( is_array( $metadata['blockVisibility'] ) && isset( $metadata['blockVisibility']['viewport'] ) ) {
// Note: Viewport hiding is usually handled via CSS classes.
// We only return false here if the block is hidden globally.
return true;
}
return true;
}
Furthermore, if you are looking for more technical deep dives into the next generation of the editor, check out my recent breakdown of Top WordPress 7.0 Features for Developers.
What’s Coming in WordPress 7.1?
The implementation in 7.0 uses fixed breakpoints. While this covers 90% of use cases, it’s a bit rigid for high-end agency work. The roadmap for 7.1 includes theme.json integration, allowing us to define custom viewport labels and specific pixel widths. This is the level of control we’ve been asking for since the first iteration of the Site Editor.
Look, if this Block Visibility in WordPress 7.0 stuff is eating up your dev hours, let me handle it. I’ve been wrestling with WordPress since the 4.x days, and I’ve seen these API shifts happen dozens of times.
Final Takeaway for Developers
Don’t assume “hidden” means “not there.” In Block Visibility in WordPress 7.0, hidden usually means “hidden with CSS.” If you are optimizing for Core Web Vitals, be careful about what you hide. A hidden image still contributes to your LCP if it’s the largest element in the DOM, even if the user can’t see it on their phone. Refactor your metadata parsers now, and keep an eye on 7.1 for the custom breakpoint integration.
“},excerpt:{raw: