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

#666 support css variables #827

Closed
wants to merge 10 commits into from

Conversation

tkh44
Copy link

@tkh44 tkh44 commented Aug 22, 2017

This is most likely unacceptable as far as size goes, but I wanted to get the process started.

Note that PhantomJS does not support cssText with custom properties in it. No idea what to do about this other than to drop css vars from that test.

fixes #666

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 8a8e685 on tkh44:666-support-css-variables into 0dea3b7 on developit:master.

src/dom/index.js Outdated
@@ -52,10 +52,21 @@ export function setAccessor(node, name, old, value, isSvg) {
}
if (value && typeof value==='object') {
if (typeof old!=='string') {
for (let i in old) if (!(i in value)) node.style[i] = '';
for (let i in old) if (!(i in value)) {
if (i.indexOf('--') === 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can always use setProperty() / removeProperty() here, which saves a bunch of bytes. AFAIK style.setProperty('color', 'red') is equivalent to style.color='red'.

Copy link
Member

@developit developit Aug 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just re-read the original thread, i was wrong since setProperty() uses CSS case rather than camelCase. poop! one option would be if (~i.indexOf('-')), which might be neat since it also enables support for css-case in general.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Damn GitHub collapsing comments. Missed this

@developit
Copy link
Member

Awesome.

Regarding the testing, it's probably a good time to switch the default launcher to be Headless Chrome, I don't really use Phantom for Preact anymore since the performance numbers are unreliable.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 7273c81 on tkh44:666-support-css-variables into 0dea3b7 on developit:master.

@developit
Copy link
Member

developit commented Aug 23, 2017

the bundle size thing didn't kick in, but it looks like this goes from 3444 -> 3482 (+38b). Honestly that's not too bad, and I really want CSS variables support.

One size thing I thought of - do you think style.setProperty('--foo', '') would work like style.removeProperty('--foo')? Would cut a few bytes after gzip.

@tkh44
Copy link
Author

tkh44 commented Aug 24, 2017

do you think style.setProperty('--foo', '') would work like style.removeProperty('--foo')?

According to MDN this should work style.setProperty('--foo'), but it errors in chrome. style.setProperty('--foo', '') works fine though and is mentioned in the spec: If value is the empty string, invoke removeProperty() with property as argument and terminate this algorithm so 👍

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling b98bc18 on tkh44:666-support-css-variables into 0dea3b7 on developit:master.

@coveralls
Copy link

coveralls commented Aug 24, 2017

Coverage Status

Coverage remained the same at 100.0% when pulling b2c742e on tkh44:666-support-css-variables into 73866a4 on developit:master.

@jveyssie100614
Copy link

What about using the ternary operator ?

	 ~i.indexOf('-')
		 ? node.style.setProperty(i, value[i]) 
		 : node.style[i] = typeof value[i]==='number' && IS_NON_DIMENSIONAL.test(i)===false 
			? (value[i]+'px') 
			: value[i];

@lionralfs
Copy link

@JeremyVSR pretty sure it gets minified like that anyways.

But I think removing the ===false check and flipping the ternary on the Regex check might save a few bytes.

Copy link
Member

@lukeed lukeed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Untested -- assumes everything can be set via setProperty, which looks to be the case at quick glance.

@@ -58,10 +58,21 @@ export function setAccessor(node, name, old, value, isSvg) {
}
if (value && typeof value==='object') {
if (typeof old!=='string') {
for (let i in old) if (!(i in value)) node.style[i] = '';
for (let i in old) if (!(i in value)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Challenge: https://twitter.com/preactjs/status/998981752130588673

if (value && typeof value==='object') {
  let i; // placeholder
  if (typeof old!=='string') {
    for (i in old) {
      if (!(i in value)) node.style.setProperty(i, '');
    }
  }
  for (i in value) {
    node.style.setProperty(i, typeof value[i]==='number' && IS_NON_DIMENSIONAL.test(i)===false ? (value[i]+'px') : value[i]);
  }
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be backwards incompatible. Doesn't work for properties that are defined using camel-casing.

node.style.backgroundColor = value; // works
node.style['background-color'] = value; // works
node.style.setProperty('background-color', value); // works
node.style.setProperty('backgroundColor', value); // doesn't work

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PepsRyuu aye, saw this after 🙈 /delete

@andrewiggins
Copy link
Member

@tkh44 Do we need the if checks at all? I removed the if statements (shown below) and the PR size was reduced by 17 bytes, so its size is now only +9 bytes on top of master. All tests pass. I quickly checked in a handful in browsers and I think this should work. It appears setProperty doesn't throw an error on invalid property names (which will happen if a component defines something like backgroundColor like you've pointed out).

if (value && typeof value==='object') {
	if (typeof old!=='string') {
		for (let i in old) if (!(i in value)) {
			node.style.setProperty(i, '');
			node.style[i] = '';
		}
	}
	for (let i in value) {
		node.style.setProperty(i, value[i]);
		node.style[i] = typeof value[i]==='number' && IS_NON_DIMENSIONAL.test(i)===false ? (value[i]+'px') : value[i];
	}
}

@tkh44
Copy link
Author

tkh44 commented May 29, 2018

@andrewiggins that should work. There was a bug in the older code that I just realized.

typeof value[i] ===
				'number' &&
				IS_NON_DIMENSIONAL.test(i) === false ? (value[i] + 'px') : value[i])

needs to be in both the setProperty and the assignment.

abstracting it would look like

function a(b) { typeof b ===
				'number' &&
				IS_NON_DIMENSIONAL.test(i) === false ? (b + 'px') : b)

Not sure where this puts us in terms of bytes.

@@ -83,10 +83,21 @@ export function setAccessor(node, name, old, value, isSvg) {
}
if (value && typeof value==='object') {
if (typeof old!=='string') {
for (let i in old) if (!(i in value)) node.style[i] = '';
for (let i in old) if (!(i in value)) {
if (~i.indexOf('-')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should check what the size is when doing if (i[0]=='-') - we only care about using setProperty for custom properties, so it'll always be a leading --.

@marvinhagemeister
Copy link
Member

Closing, we finally have support for css variables in Preact X 🎉💯

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

Successfully merging this pull request may close these issues.

Add support for CSS Custom Properties
9 participants