diff --git src/wp-includes/customize/class-wp-customize-selective-refresh.php src/wp-includes/customize/class-wp-customize-selective-refresh.php
index 0b5c446131..b0a8f77452 100644
--- src/wp-includes/customize/class-wp-customize-selective-refresh.php
+++ src/wp-includes/customize/class-wp-customize-selective-refresh.php
@@ -65,6 +65,8 @@ final class WP_Customize_Selective_Refresh {
 		require_once( ABSPATH . WPINC . '/customize/class-wp-customize-partial.php' );
 
 		add_action( 'customize_preview_init', array( $this, 'init_preview' ) );
+		add_action( 'customize_preview_init', [ $this, 'check_transport_of_settings_with_partials' ] );
+		add_action( 'customize_controls_init', [ $this, 'check_transport_of_settings_with_partials' ] );
 	}
 
 	/**
@@ -72,7 +74,7 @@ final class WP_Customize_Selective_Refresh {
 	 *
 	 * @since 4.5.0
 	 *
-	 * @return array Partials.
+	 * @return WP_Customize_Partial[] Partials.
 	 */
 	public function partials() {
 		return $this->partials;
@@ -211,6 +213,49 @@ final class WP_Customize_Selective_Refresh {
 		echo sprintf( '<script>var _customizePartialRefreshExports = %s;</script>', wp_json_encode( $exports ) );
 	}
 
+	/**
+	 * Ensure that settings associated with partials use the 'postMessage' transport.
+	 */
+	public function check_transport_of_settings_with_partials() {
+		foreach ( $this->partials() as $partial ) {
+			/*
+			 * It's possible to register a partial for a setting while intending
+			 * to use the partial in only certain circumstances. Before
+			 * enforcing the 'postMessage' transport for such settings, check
+			 * that the partial is configured to request a full refresh of the
+			 * preview if the selective refresh fails because the partial isn't
+			 * actually used in the preview.
+			 */
+			if ( ! $partial->fallback_refresh ) {
+				continue;
+			}
+
+			foreach ( $partial->settings as $setting_id ) {
+				$setting = $this->manager->get_setting( $setting_id );
+
+				if ( $setting instanceof WP_Customize_Setting ) {
+					// Change only the 'refresh' transport, not custom transports.
+					if ( 'refresh' !== $setting->transport ) {
+						continue;
+					}
+
+					/*
+					 * If the partial is unsupported, don't change any settings.
+					 *
+					 * Save this check until the end to avoid unnecessarily
+					 * re-checking the capabilities for partials and all their
+					 * settings when the settings already use 'postMessage'.
+					 */
+					if ( ! $partial->check_capabilities() ) {
+						continue 2;
+					}
+
+					$setting->transport = 'postMessage';
+				}
+			}
+		}
+	}
+
 	/**
 	 * Registers dynamically-created partials.
 	 *
