HTML Views Blending Guidelines
Introduction
In order to harness the full power of Starcounter, applications should be built to accomodate for complete visual and functional interoperability. To make this process easier for developers, we provide these guidelines for HTML views which, when followed, will allow applications to achieve seamless visual integration with other applications.
To get a technical background, the article Layout compositions for HTML partials covers more of the underlying ideas of what's presented here. It may also be worth to take a look at the following articles:
CompositionProvider has to run for the code in these guidelines to work. There are two ways to start CompositionProvider
: follow the instructions in the README file, or, when Starcounter is running, go to http://localhost:8181/#/databases/default/appstore
, click on the download button next to CompositionProvider
, and click Start
at http://localhost:8181/#/databases/yourDatabase
. This requirement is temporary.
Guideline 1: Separation of Layout and Content
To make applications look great when running independently while also allowing them to visually blend with other applications, it is beneficial to separate the layout and the content. This is accomplished using the <template is="declarative-shadow-dom">
element.
The basic boilerplate of a Starcounter HTML view, which is created by adding a Starcounter HTML template with dom-bind
file in Visual Studio, looks like this:
To separate the layout and content in this file, the element mentioned above, <template is="declarative-shadow-dom">
should be used. This element should contain the layout of the HTML view while the <template is="dom-bind">
should contain the content. Note that this only applies when using Polymer as a templating engine. When using other frameworks, it will not use dom-bind
, although, the principle of separating the layout from the content will stay constant. In code, this is how it looks:
The content are the elements that either contain information for the user, such as <h1>
, <span>
, and <a>
, or elements that create some kind of interaction between the user and the application, such as <button>
and <input>
.
Keep in mind that the only elements that have to be in the <template is="dom-bind">
are the ones that use Polymer bindings, as denoted with double curly-bracket syntax: {{model.SomeProperty}}
.
The content of the HTML view is distributed using a Shadow DOM concept called slots, as explained in guideline 4.
Guideline 2: Defining the Content
When defining the content of a view, it is important to keep in mind that the slotable elements, which are the ones that will be exposed for blending, have to be on the root of the HTML view. Consider the following HTML view:
Here, every element is at the root of the document and will be exposed for blending after they are attached to slots and distributed in the Shadow DOM. In some cases, putting every element on the root of the view, like we do in the example above, might not be desired. Then, the goal should still be to place as many elements as possible on the root of the view, especially elements like <img>
, <table>
, and custom elements that are visually obtrusive and might require blending to create a high level of interoperability.
Additionally, there might be situations where the developer would like to have a higher level of abstraction on some of his or her content. For example, consider this pagination bar:
Here, it would not make sense to break it up into the respective parts because they do not have any real meaning when presented individually. It would rather make sense to put the parent on the root level so that the whole bar is exposed for blending, and not the individual buttons.
Guideline 3: Attaching the Content to Slots
To have better flexibility in blending - to be able to distribute an element individually - the element needs to be assigned to named slots, like <button slot="myapp/submitbutton">Submit</button>
. Such an element could be distributed via <slot name="myapp/submitbutton"></slot>
in the Shadow DOM. Prefix slot names with the app name, to avoid collisions.
When no slot name is provided for an element it will be distributed in the default slot: <slot></slot>
.
The first slot in a shadow tree, in tree order, whose name is the empty string, is sometimes known as the "default slot".
Text nodes are also distributed in the default slot.
Use explicit slot names instead of relying on the default slot. The solution owner can remove the default slot from a view composition with the CompositionEditor. As a result, all elements from the view that don't have a slot
attribute are not rendered.
It's not necessary to declare the default slot in the declarative-shadow-dom
part of your view. The Starcounter's HTML merger automatically adds a default slot at the bottom of the composition of your view for fallback reasons.
Guideline 4: Create the Layout in declarative-shadow-dom
declarative-shadow-dom
As outlined in guideline 1, the layout of the HTML view should be included within the <template is="declarative-shadow-dom">
.
There is one exception to this. Both slot attributes and declarative-shadow-dom
can be omitted if the view only contains non-visual elements or if all elements should be bulked together in the default slot. The latter is rarely the case but may be useful for example for prototyping.
The <slot>
element is used to distribute the content in the Shadow DOM: <slot name="appname/elementname"></slot>
.
Consider the following HTML view definition:
To add declarative-shadow-dom
to this HTML view, something like this can be done:
Here, the elements are distributed in the way that the view will look when no blending is applied or when the app is running in standalone mode.
Guideline 5: Apply Styling to Avoid Conflicts and Allow Blending
Regarding styling, there are two ways to make the application easier to visually integrate with other apps:
Prefix all class names with the name of the app, as outlined in Avoiding CSS Conflicts.
Keep styling that will affect the layout inside the
declarative-shadow-dom
.To avoid writing the same Shadow DOM CSS on different pages, it can be imported with the CSS
import
rule. The syntax for this is<style>@import url("/yourapp/css/style.css");</style>
. In the example above it would be done this way:
Additional Resources
To find more information about creating HTML View definitions, take a look at the article linked above and the People app which fully adheres to these guidelines.
Last updated