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

Idea: Properties with Object Values #9502

Open
AdamSobieski opened this issue Oct 20, 2023 · 7 comments
Open

Idea: Properties with Object Values #9502

AdamSobieski opened this issue Oct 20, 2023 · 7 comments

Comments

@AdamSobieski
Copy link

AdamSobieski commented Oct 20, 2023

Introduction

What if the value of a property could be an object?

Syntax

JSON-based Option

Let us consider the following syntax with nested curly brackets:

div { prop: { x: 123; y: 456; }; }

which intends to communicate that the element:

<div id="el" class="cls" />

would have a style property, prop, with a value that would be an object with properties. The expression prop.x would be equal to 123 and prop.y would be equal to 456.

Dotted Property Name Option

Let us consider the following syntax with dotted property names:

div { prop.x: 123; prop.y: 456; }

which intends to communicate that the element:

<div id="el" class="cls" />

would have a style property, prop, with a value that would be an object with properties. The expression prop.x would be equal to 123 and prop.y would be equal to 456.

Object Model

With respect to adding this functionality to CSS, we might want to consider the CSSStyleDeclaration interface which provides the getPropertyValue() method which is specified as returning a CSSOMString value rather than an object value.

If getPropertyValue() returned an object value, then something like the following could work:

var element = document.getElementById('el');
var prop = element.style.getPropertyValue('prop');

console.log(prop.x);
console.log(prop.y);

Conclusion

I hope that these ideas are of some interest to the group. What do you think of the capability for properties to have complex objects for their values? Do any other syntax possibilities come to mind with which to express these ideas?

@romainmenke
Copy link
Member

Hi @AdamSobieski,

It helps if you can provide very concrete examples.
Something that can't be done today or is very hard to do and that would be improved by your proposal.

@AdamSobieski
Copy link
Author

@romainmenke, thank you. My motivating use case involves a new markup language and corresponding object model that I am working on for interacting with multiple finite-state automata. It is inspired by SCXML and will support both styling and scripting.

To some HTML-related scenarios, one example of where it might be (or might once have been) convenient to have this expressiveness is the box model:

div {
  margin: { top: 10px; right: 10px; bottom: 10px; left: 10px; };
  border: { top: 1px solid blue; right: 1px solid blue; bottom: 1px solid blue; left: 1px solid blue; };
  padding: { top: 10px; right: 10px; bottom: 10px; left: 10px; };
}

Another example involves fonts:

span {
  font: { family: sans serif; size: 12pt; style: normal; weight: bold; };
}

Strings and objects are both useful and versatile. I will brainstorm on some more concrete examples.

@Loirooriol
Copy link
Contributor

Things like margin: { top: 10px; right: 10px; bottom: 10px; left: 10px; } have been proposed in the past and seem useful.

But I don't see the need to keep it as a complex value associated with the shorthand. I would just desugar at parse-time, expanding to margin-top: top: 10px; margin-right: 10px; margin-bottom: 10px; margin-left: 10px;

@tabatkins
Copy link
Member

Right, using {}-blocks just as an alternate syntax for shorthand properties potentially makes sense, tho we'd almost certainly need more justification for it. It's simply not much of a burden to repeat the prefix of the property name a few times. If CSS nested its shorthands more deeply there would be a larger argument, but we rarely go past a single level, and I don't think we ever do more than two.

For expressing JS data directly in CSS, that's much more fraught. JS syntax isn't fully compatible with CSS in several corners. You can use a custom prop for this, if you manually parse/serialize thru JSON.

@AdamSobieski
Copy link
Author

AdamSobieski commented Oct 20, 2023

Brainstorming, there appears to be ways to use {}-blocks for providing both:

  1. an alternative syntax for shorthand properties
  2. the expressiveness for JS-based objects for property values.

In these regards, three options are presented which each involve utilizing the - symbol.

One option would involve appending a - to a relevant property name:

div {
  animation-: {
    delay: 250ms;
    direction: normal;
    duration: 1s;
    fill-mode: none;
    iteration-count: 1;
    name: kf;
    play-state: paused;
    timeline: auto;
    timing-function: ease-in-out;
    blend-: { start: normal; end: normal; };
  }
}

Another option would involve prepending a - to relevant subproperty names:

div {
  animation: {
    -delay: 250ms;
    -direction: normal;
    -duration: 1s;
    -fill-mode: none;
    -iteration-count: 1;
    -name: kf;
    -play-state: paused;
    -timeline: auto;
    -timing-function: ease-in-out;
    -blend: { -start: normal; -end: normal; };
  }
}

A third option would involve both appending and prepending a - to relevant properties and subproperties:

div {
  animation-: {
    -delay: 250ms;
    -direction: normal;
    -duration: 1s;
    -fill-mode: none;
    -iteration-count: 1;
    -name: kf;
    -play-state: paused;
    -timeline: auto;
    -timing-function: ease-in-out;
    -blend-: { -start: normal; -end: normal; };
  }
}

A complication with the second and third options, which involve prepending a - symbol to relevant property names, is that keywords and property names beginning with - or _ are reserved for vendor-specific extensions.

Here are some more concrete examples in the domain of interoperation with CSS variables.

Using the first option, above, an appended - could indicate the use of alternative syntax for shorthand properties:

:root { --custom-variable-: {x: red; y: blue}; }
div { background-color: var(--custom-variable-x, green); }

and then, by not appending - onto property names, we could also provide JS-like objects:

:root { --custom-variable: {x: red; y: blue}; }
div { background-color: var(--custom-variable, {x: green}).x; }

@Crissov
Copy link
Contributor

Crissov commented Nov 6, 2023

This sounds like a solution looking for a problem to solve.

@AdamSobieski
Copy link
Author

@Crissov, hello. I was initially brainstorming about CSS selectors, CSSOM, and object graphs, e.g.:

var el = document.getElementById('el');
var x = el.style.property.subproperty;

but: (1) there might not be much Web developer demand for this expressiveness, (2) there were indicated to be some corner cases with respect to combining JS and CSS, and (3) the {}-based syntax was indicated to have been previously considered for notational shorthand conventions which can be parsed back into lengthier style property names.

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

No branches or pull requests

6 participants