Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Margin shorthands are not patched correctly #441

Closed
fdietze opened this issue Aug 7, 2019 · 5 comments
Closed

Margin shorthands are not patched correctly #441

fdietze opened this issue Aug 7, 2019 · 5 comments
Assignees

Comments

@fdietze
Copy link

fdietze commented Aug 7, 2019

When merging and patching margin/padding shorthands, the result is wrong:

var vnode = h('div#root', h('div',{style: {
    margin: '10px 20px 40px',   // top | horizontal | bottom (https://developer.mozilla.org/en-US/docs/Web/CSS/padding#Syntax)
    marginRight: '20px'
  }},'A'));
patch(container, vnode);

var newVnode = h('div#root', h('div',{style: {
    margin : '10px 20px 40px',
  }}, 'B'));
patch(vnode, newVnode); // marginRight will be removed here. This is wrong.

Fiddle: https://jsfiddle.net/m7t4xj12/1/

@fdietze fdietze changed the title Margin shorthands are not patched properly Margin shorthands are not patched correctly Aug 7, 2019
@fdietze
Copy link
Author

fdietze commented Aug 7, 2019

Here are the pure dom operations:

var node = document.createElement('div')
container.appendChild(node)
node.style.margin = '10px 20px 40px';
node.style.marginRight = '30px';
node.style.marginRight = '';

Result:

<div style="margin-top: 10px; margin-bottom: 40px; margin-left: 20px;"></div>

The shorthand itself is the problem... 😢

https://jsfiddle.net/6uhtronb/

@fdietze
Copy link
Author

fdietze commented Aug 7, 2019

React issue: facebook/react#6348
Vue: vuejs/vue#7756

@nojvek
Copy link

nojvek commented Sep 29, 2019

I don't think this is a problem of snabbdom. As shown from your pure dom operations that browser still behaves quirky with

var node = document.createElement('div')
container.appendChild(node)
node.style.margin = '10px 20px 40px';
node.style.marginRight = '30px';
node.style.marginRight = '';

because two different properties are being diffed.

The workaround soln is to use

var vnode = h('div#root', h('div',{style: {
    marginRight: '20px',
    marginLeft: '20px',
    marginTop: '10px',
    marginBottom: '40px',
  }},'A'));
patch(container, vnode);

var newVnode = h('div#root', h('div',{style: {
    marginLeft: '20px',
    marginTop: '10px',
    marginBottom: '40px',
  }},'B'));
patch(vnode, newVnode); 

@fdietze
Copy link
Author

fdietze commented Oct 1, 2019

Correct. The solution is to not use shorthands. This should be clearly noted in the readme, else people get unexpected behavior.

@mightyiam mightyiam self-assigned this Jun 10, 2020
@mightyiam
Copy link
Contributor

Closing this in favor of #815.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants