Change:
I a "bug" today that made me spent 1h figuring out what was going on: I'm using an external component that accepts a prop in order to set the of the root element, but this same component also accepts a prop which I wasn't passing, and by default, it was set to . The result: React didn't throw an error nor a warning, however, the resulting element in the DOM didn't contain either or , and since the element had a default coming from a CSS class, it took me a while to figure out why the color that I was passing wasn't being applied, and instead it was using the one from the CSS class. See: What I reported above was the case. I other cases as a bonus, as when I was playing with this they also seemed weird to me. On I define the same properties, but because I change the order, it works. On the toggleable ones, initially I can see the background, but after changing it never appears anymore. I'm not sure if I created those extra "test cases" correctly. My main concern is really around static1 not outputting anything on the console as a warning. Related issues: I wonder if ( should have covered this?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution.
Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please create a new issue with up-to-date information. Thank you!
it seems that the bot automatically closed the issue, but this still needs action. I took a time to investigate it, and I realized that the work Sophie has done covers this case, but there's just one problem: it's disabled under a . I built it locally and flipped the flag, and it works: I can see the helpful warning. It was flagged in , and as per the PR, the original intention was to unflag it on the next minor. Since then we had at least 4 new minor versions, but it is still flagged. Is there a special reason for that or was it just forgotten? tagging you since you this flag, so I'm hoping you can give context here.
Can we unflag this?
This was released.

Discussion:
<del> /** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @emails react-core */ 'use strict'; describe('ReactDOMShorthandCSSPropertyCollision', () => { let ReactFeatureFlags; let React; let ReactDOM; beforeEach(() => { jest.resetModules(); ReactFeatureFlags = require('shared/ReactFeatureFlags'); ReactFeatureFlags.warnAboutShorthandPropertyCollision = true; React = require('react'); ReactDOM = require('react-dom'); }); it('should warn for conflicting CSS shorthand updates', () => { const container = document.createElement('div'); ReactDOM.render(<div style={{font: 'foo', fontStyle: 'bar'}} />, container); expect(() => ReactDOM.render(<div style={{font: 'foo'}} />, container), ).toErrorDev( 'Warning: Removing a style property during rerender (fontStyle) ' + 'when a conflicting property is set (font) can lead to styling ' + "bugs. To avoid this, don't mix shorthand and non-shorthand " + 'properties for the same value; instead, replace the shorthand ' + 'with separate values.' + 'n    in div (at **)', ); // These updates are OK and don't warn: ReactDOM.render(<div style={{font: 'qux', fontStyle: 'bar'}} />, container); ReactDOM.render(<div style={{font: 'foo', fontStyle: 'baz'}} />, container); expect(() => ReactDOM.render( <div style={{font: 'qux', fontStyle: 'baz'}} />, container, ), ).toErrorDev( 'Warning: Updating a style property during rerender (font) when ' + 'a conflicting property is set (fontStyle) can lead to styling ' + "bugs. To avoid this, don't mix shorthand and non-shorthand " + 'properties for the same value; instead, replace the shorthand ' + 'with separate values.' + 'n    in div (at **)', ); expect(() => ReactDOM.render(<div style={{fontStyle: 'baz'}} />, container), ).toErrorDev( 'Warning: Removing a style property during rerender (font) when ' + 'a conflicting property is set (fontStyle) can lead to styling ' + "bugs. To avoid this, don't mix shorthand and non-shorthand " + 'properties for the same value; instead, replace the shorthand ' + 'with separate values.' + 'n    in div (at **)', ); // A bit of a special case: backgroundPosition isn't technically longhand // (it expands to backgroundPosition{X,Y} but so does background) ReactDOM.render( <div style={{background: 'yellow', backgroundPosition: 'center'}} />, container, ); expect(() => ReactDOM.render(<div style={{background: 'yellow'}} />, container), ).toErrorDev( 'Warning: Removing a style property during rerender ' + '(backgroundPosition) when a conflicting property is set ' + "(background) can lead to styling bugs. To avoid this, don't mix " + 'shorthand and non-shorthand properties for the same value; ' + 'instead, replace the shorthand with separate values.' + 'n    in div (at **)', ); ReactDOM.render( <div style={{background: 'yellow', backgroundPosition: 'center'}} />, container, ); // But setting them  at the same time is OK: ReactDOM.render( <div style={{background: 'green', backgroundPosition: 'top'}} />, container, ); expect(() => ReactDOM.render(<div style={{backgroundPosition: 'top'}} />, container), ).toErrorDev( 'Warning: Removing a style property during rerender (background) ' + 'when a conflicting property is set (backgroundPosition) can lead ' + "to styling bugs. To avoid this, don't mix shorthand and " + 'non-shorthand properties for the same value; instead, replace the ' + 'shorthand with separate values.' + 'n    in div (at **)', ); // A bit of an even more special case: borderLeft and borderStyle overlap. ReactDOM.render( <div style={{borderStyle: 'dotted', borderLeft: '1px solid red'}} />, container, ); expect(() => ReactDOM.render(<div style={{borderLeft: '1px solid red'}} />, container), ).toErrorDev( 'Warning: Removing a style property during rerender (borderStyle) ' + 'when a conflicting property is set (borderLeft) can lead to ' + "styling bugs. To avoid this, don't mix shorthand and " + 'non-shorthand properties for the same value; instead, replace the ' + 'shorthand with separate values.' + 'n    in div (at **)', ); expect(() => ReactDOM.render( <div style={{borderStyle: 'dashed', borderLeft: '1px solid red'}} />, container, ), ).toErrorDev( 'Warning: Updating a style property during rerender (borderStyle) ' + 'when a conflicting property is set (borderLeft) can lead to ' + "styling bugs. To avoid this, don't mix shorthand and " + 'non-shorthand properties for the same value; instead, replace the ' + 'shorthand with separate values.' + 'n    in div (at **)', ); // But setting them  at the same time is OK: ReactDOM.render( <div style={{borderStyle: 'dotted', borderLeft: '2px solid red'}} />, container, ); expect(() => ReactDOM.render(<div style={{borderStyle: 'dotted'}} />, container), ).toErrorDev( 'Warning: Removing a style property during rerender (borderLeft) ' + 'when a conflicting property is set (borderStyle) can lead to ' + "styling bugs. To avoid this, don't mix shorthand and " + 'non-shorthand properties for the same value; instead, replace the ' + 'shorthand with separate values.' + 'n    in div (at **)', ); }); }); </del>

<ins> /** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @emails react-core */ 'use strict'; describe('ReactDOMShorthandCSSPropertyCollision', () => { let React; let ReactDOM; beforeEach(() => { jest.resetModules(); React = require('react'); ReactDOM = require('react-dom'); }); it('should warn for conflicting CSS shorthand updates', () => { const container = document.createElement('div'); ReactDOM.render(<div style={{font: 'foo', fontStyle: 'bar'}} />, container); expect(() => ReactDOM.render(<div style={{font: 'foo'}} />, container), ).toErrorDev( 'Warning: Removing a style property during rerender (fontStyle) ' + 'when a conflicting property is set (font) can lead to styling ' + "bugs. To avoid this, don't mix shorthand and non-shorthand " + 'properties for the same value; instead, replace the shorthand ' + 'with separate values.' + 'n    in div (at **)', ); // These updates are OK and don't warn: ReactDOM.render(<div style={{font: 'qux', fontStyle: 'bar'}} />, container); ReactDOM.render(<div style={{font: 'foo', fontStyle: 'baz'}} />, container); expect(() => ReactDOM.render( <div style={{font: 'qux', fontStyle: 'baz'}} />, container, ), ).toErrorDev( 'Warning: Updating a style property during rerender (font) when ' + 'a conflicting property is set (fontStyle) can lead to styling ' + "bugs. To avoid this, don't mix shorthand and non-shorthand " + 'properties for the same value; instead, replace the shorthand ' + 'with separate values.' + 'n    in div (at **)', ); expect(() => ReactDOM.render(<div style={{fontStyle: 'baz'}} />, container), ).toErrorDev( 'Warning: Removing a style property during rerender (font) when ' + 'a conflicting property is set (fontStyle) can lead to styling ' + "bugs. To avoid this, don't mix shorthand and non-shorthand " + 'properties for the same value; instead, replace the shorthand ' + 'with separate values.' + 'n    in div (at **)', ); // A bit of a special case: backgroundPosition isn't technically longhand // (it expands to backgroundPosition{X,Y} but so does background) ReactDOM.render( <div style={{background: 'yellow', backgroundPosition: 'center'}} />, container, ); expect(() => ReactDOM.render(<div style={{background: 'yellow'}} />, container), ).toErrorDev( 'Warning: Removing a style property during rerender ' + '(backgroundPosition) when a conflicting property is set ' + "(background) can lead to styling bugs. To avoid this, don't mix " + 'shorthand and non-shorthand properties for the same value; ' + 'instead, replace the shorthand with separate values.' + 'n    in div (at **)', ); ReactDOM.render( <div style={{background: 'yellow', backgroundPosition: 'center'}} />, container, ); // But setting them  at the same time is OK: ReactDOM.render( <div style={{background: 'green', backgroundPosition: 'top'}} />, container, ); expect(() => ReactDOM.render(<div style={{backgroundPosition: 'top'}} />, container), ).toErrorDev( 'Warning: Removing a style property during rerender (background) ' + 'when a conflicting property is set (backgroundPosition) can lead ' + "to styling bugs. To avoid this, don't mix shorthand and " + 'non-shorthand properties for the same value; instead, replace the ' + 'shorthand with separate values.' + 'n    in div (at **)', ); // A bit of an even more special case: borderLeft and borderStyle overlap. ReactDOM.render( <div style={{borderStyle: 'dotted', borderLeft: '1px solid red'}} />, container, ); expect(() => ReactDOM.render(<div style={{borderLeft: '1px solid red'}} />, container), ).toErrorDev( 'Warning: Removing a style property during rerender (borderStyle) ' + 'when a conflicting property is set (borderLeft) can lead to ' + "styling bugs. To avoid this, don't mix shorthand and " + 'non-shorthand properties for the same value; instead, replace the ' + 'shorthand with separate values.' + 'n    in div (at **)', ); expect(() => ReactDOM.render( <div style={{borderStyle: 'dashed', borderLeft: '1px solid red'}} />, container, ), ).toErrorDev( 'Warning: Updating a style property during rerender (borderStyle) ' + 'when a conflicting property is set (borderLeft) can lead to ' + "styling bugs. To avoid this, don't mix shorthand and " + 'non-shorthand properties for the same value; instead, replace the ' + 'shorthand with separate values.' + 'n    in div (at **)', ); // But setting them  at the same time is OK: ReactDOM.render( <div style={{borderStyle: 'dotted', borderLeft: '2px solid red'}} />, container, ); expect(() => ReactDOM.render(<div style={{borderStyle: 'dotted'}} />, container), ).toErrorDev( 'Warning: Removing a style property during rerender (borderLeft) ' + 'when a conflicting property is set (borderStyle) can lead to ' + "styling bugs. To avoid this, don't mix shorthand and " + 'non-shorthand properties for the same value; instead, replace the ' + 'shorthand with separate values.' + 'n    in div (at **)', ); }); }); </ins>

// Control this behavior with a flag to support 16.6 minor releases in the meanwhile. export const exposeConcurrentModeAPIs = __EXPERIMENTAL__; <del> export const warnAboutShorthandPropertyCollision = false; </del> <ins> export const warnAboutShorthandPropertyCollision = true; </ins> // Experimental React Flare event system and event components support. export const enableDeprecatedFlareAPI = false;

export const enableSelectiveHydration = false; export const enableChunksAPI = false; export const exposeConcurrentModeAPIs = __EXPERIMENTAL__; <del> export const warnAboutShorthandPropertyCollision = false; </del> <ins> export const warnAboutShorthandPropertyCollision = true; </ins> export const enableSchedulerDebugging = false; export const debugRenderPhaseSideEffectsForStrictMode = true; export const disableJavaScriptURLs = false;

export const disableJavaScriptURLs = false; export const disableInputAttributeSyncing = false; export const exposeConcurrentModeAPIs = __EXPERIMENTAL__; <del> export const warnAboutShorthandPropertyCollision = false; </del> <ins> export const warnAboutShorthandPropertyCollision = true; </ins> export const enableSchedulerDebugging = false; export const enableDeprecatedFlareAPI = false; export const enableFundamentalAPI = false;

disableInputAttributeSyncing, enableTrustedTypesIntegration, deferPassiveEffectCleanupDuringUnmount, <ins> warnAboutShorthandPropertyCollision, </ins> } = require('ReactFeatureFlags'); // In www, we have experimental support for gathering data

export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false; export const warnAboutDeprecatedLifecycles = true; <del> export const warnAboutShorthandPropertyCollision = false; </del> export const disableLegacyContext = false; export const warnAboutStringRefs = false; export const warnAboutDefaultPropsOnFunctionComponents = false;