question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

RFC: Per-Block Namespaces

See original GitHub issue

Summary

Instead of using a single namespace state for the attributes, we will formalize the concept that the block classes and states live in a shared namespace that is defined by the block. While the namespace for a block will be the url of that block (file://...) the local references to block styles will use the locally assigned identifier to refer to it via a namespace instead of using a non-standard dotted notation.

This provides significant design benefits, improves the overall readability of the code, and reduces the amount of boilerplate syntax the authors must provide.

Syntax Example

/* section.block.css -- automatically associated with above template */
@export btn from "./buttons.block.css"; /* automatically defines the namespace associated with buttons.block.css and assigns a identifier of "btn" to it. */
:scope { /* ... */ }
:scope[enabled] { /* ... */ }
.foot { /* ... */ }
/* button.block.css */
:scope { /* ... */ }
:scope:hover { /* ... */ }
:scope:active { /* ... */ }
:scope:disabled { /* ... */ }
.icon { /* ... */ }
.icon[inverse] { /* ... */ }
{{!-- section.hbs--}}
<section block:scope block:enabled={{isEnabled}}>
  <button btn:scope>
    <div btn:class="icon" btn:inverse={{isInverse}}></div>
    {{value}}
  </button>
  <footer block:class="foot">
    Copyright (c) 2019 LinkedIn Corp.<br>
    All rights reserved.
  </footer>
</section>

Motivation

Consistent feedback that I’ve gotten about CSS Blocks is that the state namespace is “weird” and “confusing”.

We’ve used this namespace primarily as a signal that the attribute(s) belong to CSS Blocks instead of HTML so that we can confidently rewrite them.

While the word state was meant to evoke the visual state of the element, it can also be confusing with other “states” going on in a component. By using the name of the block, the code is more clearly associated with that block and so it reads better.

By taking over the html class attribute we’ve caused ourselves a lot of challenges in terms of legacy support that makes the gradual adoption of CSS Blocks more of a challenge than it needs to be. This change will allow legacy classes to coexist with css-blocks’ classes without ambiguity so we do not lose our ability to clearly error when a block class isn’t found.

How do we teach this?

Fortunately there’s not very many users of CSS Blocks yet 😅.

The “strangest” thing about this new approach is that instead of having space delimited values for the class attribute as is the custom, there can be more than one class attribute each in a different namespace. While this feels strange at first, it derives from some simple and consistent rules:

  • HTML attributes have a namespace that defaults to the html namespace.
  • CSS attribute selectors have an existing syntax for selecting attributes in a specific namespace.
  • The class selector is understood to be selecting an attribute with a certain name (class).
  • To provide safe scoping, selectors in a css blocks file are selecting document elements according to attributes that are in the namespace of the block.
  • Because html5 doesn’t formally support arbitrary namespaces like xhtml did, we rewrite all block-based attributes to be scoped classnames in the html namespace.

Detailed Design

Terminology Changes

We will change the name of state to attribute to match the authored syntax.

CSS Syntax Changes

  • The class selector will now be defined as selecting an attribute named class in the namespace of the block.
  • The default namespace for the attribute selector will be dom attributes in the namespace of the block. Therefore the state| namespace in the state attribute selector is no longer needed.
  • Selecting attributes (including the class attribute) in the html namespace will require using the attribute selector so that the html namespace can be provided explicitly. This will clearly demarcate what is a state and what is html. (This will impact the design for #10).
  • The :scope selector will select an element with the attribute of scope that is in the namespace of the block.
  • non-block namespaces will be handled by registering common names of html, svg, and math and making them forbidden names for blocks. Other non-block namespaces can be registered through configuration.

Handlebars Template Syntax Changes

  • The namespace identifier for the default block associated with the template is block.
  • If no element has an attribute of block:scope then it is automatically assigned to the template’s root element.
  • In the template, Instead of exposing all blocks that are referenced by @block, only the blocks exported by the default block are exposed to the template (with that identifier to as the namespace identifier for defining attributes in the exported blocks namespace).
  • Instead of class="foo other-block.bar" we would now write block:class="foo" other-block:class="bar".
  • The class attribute in html namespace can be forbidden or allowed based on configuration. If allowed, those classes can be used for styling with selectors defined outside of the scope of css blocks.

JSX changes

No changes to jsx will be made at this time.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
robomalocommented, Oct 1, 2019

I can’t contribute too much on feedback because my experience is limited, but my first impression is this is going to be easier for devs to digest/analyze on the first pass or three.

0reactions
chriseppsteincommented, Nov 22, 2019

This feature is on master now.

Read more comments on GitHub >

github_iconTop Results From Across the Web

RFC 2611: URN Namespace Definition Mechanisms
RFC 2611 URN Namespace Definition Mechanisms June 1999 Assumption #2: The space of URN namespaces is managed. I.e., not all syntactically correct URN ......
Read more >
Basic Forward Error Correction (FEC) Schemes RFC 5445
Watson Standards Track [Page 1] RFC 5445 Basic FEC Schemes March 2009 Table of ... indicating the maximum number of encoding symbols per...
Read more >
RFC: Modules and Extensions #434 - XOOPS/XoopsCore
It would map to the module's class directory in PSR-4 fashion. This would be implemented automatically for all active modules with a namespace...
Read more >
RFC 47: Per Dataset Caching and GDALRasterBand ...
This prevents two different threads from using memcpy on the same GDALRasterBlock at the same time. It is created on a per block...
Read more >
Namespace for an RFC
Hi SAP Gurus, I know for most of you this will be a peace of cake, I tried to find the namespace for...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found