2023:CSS Data Viewer Styling: Difference between revisions

From Grooper Wiki
Line 2,570: Line 2,570:


<tabs style="margin:20px">
<tabs style="margin:20px">
<tab name="Style 1 - Mixed Layout & New Caption Style" style="margin:20px">
<tab name="Style 1 - Mixed Layout and New Caption Style" style="margin:20px">


For a lot of document cases, you can't perfectly mirror a document's layout because you are processing a lot of different versions of the same kind of document.
For a lot of document cases, you can't perfectly mirror a document's layout because you are processing a lot of different versions of the same kind of document.
Line 2,638: Line 2,638:


</tab>
</tab>
<tab name="Style 2 - Inline-Block Data Sections & No Captions" style="margin:20px">
<tab name="Style 2 - Inline-Block Data Sections and No Captions" style="margin:20px">


This '''''Style Sheet''''' renders '''Data Sections''' as inline-block elements.   
This '''''Style Sheet''''' renders '''Data Sections''' as inline-block elements.   

Revision as of 14:57, 8 December 2022

The Grooper Web client's Review interface is styled using CSS (Cascading Style Sheets). This gives you a great deal of control over how Data Model elements appear and are laid out for a user during document review.

About

You may download and import the files below into your own Grooper environment (version 2023). The first contains a Project with several Content Models used as examples throughout this article. The second contains some example Batches of sample documents.

CSS is a style sheet language used to define how HTML elements appear visually. CSS style sheets are ubiquitous in the world of web design and development. Fonts, headers and other container elements can be styled to make a web page more visually appealing and and easier to read. How this content is separated and presented on a web page can be formatted using a CSS file.

In Grooper, you can style your Data Model with custom CSS. If you are using the Web Client, elements in your Data Model (Data Fields, Data Sections, etc.) are all rendered as some combination of HTML elements themselves when viewed over a browser. You can style how these elements are presented using CSS style sheets. This gives you a great deal of control over what you and your reviewers see during the Review activity.

FYI

The Review activity allows users to review various aspects of Grooper's automated document processing. What users review and how document content is presented is controlled by whichever Review Viewer UI the user is using.

  • Extracted document data is always reviewed using the Data Viewer interface.
  • All CSS styling done to your Data Model will be reflected to the user in the Data Viewer and only in the Data Viewer.
  • Because CSS styling only pertains to the Data Viewer (which is one of many possible Review Viewers accessible in the Review activity), this article may use the terms Review Viewer and Data Viewer interchangeably.


Data Elements are styled by editing a CSS file found on the Data Model.

  1. First select the Data Model you wish to style.
  2. You can then edit a CSS file using the Style Sheet property.
    • Press the ellipsis button at the end of the property to bring up the Style Sheet editor.


  1. Using the Style Sheet editor, you can enter as many CSS rules as you need to style the Data Model to meet your needs.
    • When possible, a CSS code completion window will pop up as you type, allowing you to select from a list of available elements, classes, properties, and certain values.


  1. CSS may also be edited at the Data Section and Data Table level.
  2. You will find both these Data Elements also have a Style Sheet property.

Editing CSS at the Data Section and Data Table level can be particularly helpful when dealing with larger Data Models with multiple nested levels in their heirarchy. We will discuss this further in the Global Element Styling VS Local Element Styling section of this article.

Basics

CSS styles webpage elements by defining a series of rules. Each rule defines how an HTML element looks: its text's font, its colors, its margins on the page, its alignment with other elements and more.


Each CSS rule consists of two parts:

  1. A selector.
    • This points to the HTML element you want to style.
  2. A declaration block.
    • This defines one or more style declarations, the specific ways you want the element to look.
    • Declaration blocks are surrounded by curly braces.
    • Multiple declarations are separated with semicolons.

In our case, the HTML elements we're working with correspond to our Data Model's Data Elements. The Data Fields, Data Sections, and Data Tables in the Data Model are rendered in a browser by a combination of HTML elements and their sub-elements. Each different kind of Data Element has a corresponding CSS class that can be custom styled.

For example, when a user operates the Data Viewer in the Review activity and looks at a Data Field, they're really seeing three total HTML elements.

  1. A parent div element, with a DataField class.
  2. A child label element, corresponding to the Data Field's text label.
  3. A child input element, corresponding to the editable text box that holds the Data Fields extracted and/or user entered data.


With no CSS styling applied, Data Models look pretty basic in the Review application. This is our blank canvas we start with. Using CSS, we can customize the look and feel of this user interface.


For example, let's say we want to change the font color and size of the Data Fields in our Data Model.


We want all these field labels to be "Grooper orange" and a little bigger.


We can do that with CSS style sheets. This would be the result if we added the following CSS rule to our Data Model's Style Sheet

.DataField label {
  color: rgb(248,148,32);
  font-size: 18px;
}

The selector .DataField label defines what element we want to style.

  • For all Data Fields (.DataField) we want to style their label (label)

The declaration block defines how we want to style the element.

  • color: rgb(248,148,32) changes the font color to "Grooper orange", using the RGB color value.
  • font-size: 18px changes the font's size to 18 pixels high.
  • Each declaration is separated from the next by placing a semicolon (;) at the end.


Notice the CSS rule only applied to what we told it to apply to: Data Fields' labels.

No styling was applied to the:

  1. "Address Info" Data Section's caption.
  2. "Dependents" Data Table's caption.
  3. "Dependents" Data Table's Data Column header labels.

We would need to make separate CSS rules to style these elements as we wish.

FYI

A Data Field is represented in HTML as an element with two child elements:

  • A "label" element, representing the field's label.
  • An "input" element representing the entry value textbox.


When styling Data Fields it's very important to understand which HTML element you want to style.

  • Do you want to style the Data Field's label? You'd use .DataField label as your selector.
  • Do you want to style the Data Field's input box? You'd use .DataField input as your selector.
  • Do you want to style the larger element housing both the Data Field's label and input box? You'd use .DataField as your selector.


The space character in the selector is something called a "combinator" in CSS (Specifically, the "descendent children" combinator). For more information on selecting elements and combinators, please visit the #Styling Scope: Selecting Data Elements portion of this article.

File:2023-data-model-style-sheets-basics-11.png

A Common Example: Increasing a Data Field's Label Width


By default, a Data Field's input box is jammed right up against its label in the Data Viewer's screen. Nearly all Grooper users are going to want to space things out a little better. This will make the Data Model more readable, ultimately making your reviewers' job easier. After all, the end goal to styling your Data Model is in service of the user's data review experience.

It's not just about making things "look good". If the Data Model is easier to read, it's easier to understand. This makes the Review experience more efficient, ultimately making the process quicker and even preventing costly data entry errors.


A common CSS rule added to the Style Sheet will be one that increases the width of all Data Field labels.

Here, we've changed the CSS styling to increase the width of all Data Field labels in the Data Model to 132 pixels wide, using the following rule:

.DataField label {
  width: 132px;
}

Now, the label widths for all Data Fields have been lengthened to 132 pixels. As a result, the Data Model is much easier to read and interact when operating the Data Viewer during a Review activity.

Styling Scope: Selecting Data Elements

In the previous examples, we styled Data Fields in a global manner. The CSS rule was applied to all Data Fields in the Data Model. Sometimes we want to be more specific. We may want to narrow a rule's scope so that it is applied to some elements, but not others.

Narrowing down the styling scope is done using one, or both, of the following methods:

  1. Selecting a specific Data Element using it's name.
    • For example, selecting and styling a Data Field named "SSN" rather than all Data Fields.
  2. Selecting a Data Element's children or sibling elements.
    • For example, selecting and styling Data Fields in a Data Section rather than all Data Fields.
    • This is done using what are called "combinators" in CSS.

Styling Named Elements

Imagine you have a specific Data Field you want to draw your users attention to. This may be a more "important" field according to some process if your organization that you really want them to pay attention to. One thing you could do is change the label's color to make it more distinct from the other fields in your Data Model.

To do this, you would select the specific element by name, rather than selecting all Data Fields.


Let's say "Hire Date" is a critical field for this Document Type's Data Model.

We're going to style just this Data Field with CSS. All we need to do is select the Data Field by name. Instead of using .DataField as the selector, we will use the specific Data Field's name.


Specific data elements are selected using its name simply by entering its name.

  • i.e. .DataElementName


The following CSS rule makes only the "Hire Date" field appear orange.

.Hire_Date label {
  color: rgb(248,148,32)
}


Please note more specific rules always "win out". If multiple rules are written at larger or narrower scopes, the style rule with the narrowest scope will always be applied.

  1. This rule has a larger scope, applying to all Data Fields.
    • The rule adjusts the label widths to 132 pixels wide and changes their color to teal.
.DataField label {
  width: 132px;
  color: rgb(54,176,167)
}
  1. This rule has a narrower scope, applying only to the "Hire Date" Data Field.
    • The rule adjusts the label's color to orange.
.Hire_Date label {
  color: rgb(248,148,32)
}


Since .Hire_Date is a more specific/narrower selector, its color styling is applied. The resulting text is orange and not teal.


Also note the width declaration assigned using the .DataField selector is still applied.

  • The .Hire_Date label declaration block said nothing about how to style the width.
  • Thus, the styling fell back on what was described by the .DataField label selector with the larger scope.

Selecting Multiple Elements

You can select and style multiple elements by creating a comma separated list of elements in the selector.


Let's say we wanted to make the "Hire Date", "Zip" and "Phone" Data Fields' labels orange. We don't have to write out three separate CSS rules. Rather we can use a single rule, separating multiple selectors with a comma.


The CSS rule below will do the trick:

.Hire_Date label,
.Zip label,
.Phone label {
  color: rgb(248,148,32);
}

FYI

You can also list elements horizontally, the two CSS rules below will operate identically.

Horizontal List

Vertical List

.Hire_Date label, .Zip label, .Phone label {
  color: rgb(248,148,32);
}
.Hire_Date label,
.Zip label,
.Phone label {
  color: rgb(248,148,32);
}

However, most would agree a vertical comma separated list of selectors is more readable.

Intro to Combinators

Styling child and sibling elements can be a great way to add more specificity to how you want to style various Data Elements in your Data Model. Child and sibling elements are selected in CSS using a "combinator".

A combinator explains the relationship between selectors. A combinator character is placed between selectors to define the relationship.

  • i.e. <element1><combinator><element2>

There are four combinators in CSS:

  •   - All descendant children selector
  • > - Immediate children selector
  • + - Adjacent (meaning "first immediately following") sibling selector
  • ~ - General (meaning "all following") sibling selector


We've actually already used a combinator in this article (the descendant children selector) when styling Data Fields.


A Data Field is represented on webpages as an element that contains two child elements:

  • A "label" element
  • An "input" element

File:2023-data-model-style-sheets-basics-11.png

When styling the width or the color of Data Fields' labels we used the following selector:

  • .DataField label


The space character between .DataField and label is the descendent children selector. So, by selecting .DataField label we were selecting the child label elements of all .DataField elements.

  • This means any styling we applied was done not to the larger .DataField element (representing the Data Field) but instead all descendent children label elements (representing the Data Field's label).
FYI

While technically .DataField selects all descendent label elements, .DataField elements only ever have one child label element.


Next, we'll look at other ways to use combinators.

Styling Child Elements

By far, the most common combinators you will likely use are the children combinators. This will allow you to utilize Data Sections in ways to define styles for a particular collection of Data Elements distinct from the Data Model as a whole or Data Elements in other Data Sections.

  • The   (a single space character) selects all descendant children.
  • The > selects only immediate children.


Imagine you have a collection of Data Fields in your Data Model. Some of these Data Fields are at the root of the Data Model. Others are children of a Data Section. You want to style only Data Fields in a Data Section.


We can do this with the descendent children ( ) or the immediate children (>) combinator.


Next, we will style Data Fields in the "Address Info" Data Section using the descendent children and immediate children combinators.

Descendent Children Combinator


Let's say we want to recolor the labels for Data Fields in the "Address Info" Data Section. We can do that easily with the following CSS rule:

.Address_Info .DataField label {
	color: rgb(248,148,32);
}

See here, only the Data Fields in the "Address Info" Data Section had their label text colored orange.

The selector .Address_Info .DataField label, selected all .DataField label elements in the .Address_Info element. It is the space character ( ) between elements that dictates descendent children should be selected.

FYI

Technically, the selector selected all label elements inside a .DataField element which was itself in the .Address_Info element!

This is probably overkill. The selector .Address_Info label would have worked identically. We did not have to specify all child label elements for only .DataField elements. The only label elements there are in the Data Section are those that are children of .DataField elements.


Keep in mind, the descendent children combinator selects all children elements of the parent element. This may be what you want to do. It may not. It's important to realize what's going to happen, especially with larger Data Models with more complex Data Element hierarchies.

Let's imagine we have a Data Section within a Data Section.

  1. Here, we've added a "City State Zip" Data Section to the "Address Info" Data Section.
  2. As a child Data Section of the parent "Address Info" Data Section, the Data Fields in "City State Zip" are considered descendent elements when rendered in the Review interface.


So, what's going to happen to the "City" "State" and "Zip" Data Fields' labels now that they're in the "City State Zip" Data Section?


They're still styled!


The selector we used .DataSection .DataField label selected all descended .DataField elements, including those that are now grandchildren in the "City State Zip" Data Section.


However, what if this isn't what you want to do? What if you only want to style the immediate children in the "Address Info" Data Section and leave any further descendant elements alone?

  • Or, put another way, what if you want to style only the "Street Address" field but not any of the fields in the "City State Zip" Data Section?


Next, we will look at using the immediate children combinator (>) to do just that.

Immediate Children Combinator


The immediate children combinator > selects a smaller scope of an element's children, namely only its immediate children.


If we use the following selector, .Address_Info > .DataField label, only .DataField elements that are immediate children will be styled. Put another way, only Data Fields in the first level of "Address Info" Data Section's hierarchy will be styled.

  • The "Street Address" Data Field is an immediate child. It will be styled.
  • The "City" "State" and "Zip" Data Field's are descendant children further on down the object hierarchy. They will not be styled.
  • The rest of the Data Fields in the Data Model are siblings to the "Address Info" Data Section. They are therefore out of scope entirely and will not be styled.


You can see here what happens when we use the the > combinator instead of the   combinator, in our CSS rule below:

.Address_Info > .DataField label {
	color: rgb(248,148,32);
}


Only the "Address Info" Data Section's immediate children are styled.

  • In this case only the "Street Address" Data Field's label color is changed.
FYI

The spaces on either side of the > combinator are simply added to increase readability. The following selectors would work identically:

  • .Address_Info > .DataField label
  • .Address_Info>.DataField label

Styling Sibling Elements

Less commonly, you may want to style sibling elements using the sibling combinators. This is a way of styling sibling Data Elements (existing in the same level of your Data Model's hierarchy) that come after a selected element.

  • The + selects "adjacent" siblings, selecting a single element after a specified element.
    • Put another way, the first instance of an element after a specific element.
  • The ~ selects "general" siblings, selecting any and all elements after a specified element.
    • Put another way, all instances of an element after a specific element.


For example, take the "Address Info" Data Section in the Data Model we've been using.

  • "Address Info" has a sibling relationship with all Data Elements at the same level in the Data Model.
  • "Address Info" has a parent-child relationship with every Data Element it contains.


There are two sibling Data Fields that follow the "Address Info" Data Section:

  • "Marital Status"
  • "Phone"


The adjacent combinator + would allow us to select and style the first Date Field after the "Address Info" section. The general sibling combinator ~ would select and style all Data Fields after the "Address Info" section.

  • .Address_Info + .DataField will select only the first subsequent sibling .DataField element.
    • Only "Marital Status" would be selected.
  • .Address_Info ~ .DataField will select all subsequent sibling .DataField elements.
    • Both "Marital Status" and "Phone" would be selected.


For example, the following CSS rule uses the adjacent sibling selector.

.Address_Info + .DataField label {
	color: rgb(248,148,32);
}


Only the "Marital Status" Data Field's label is styled.


For example, the following CSS rule uses the general sibling selector.

.Address_Info ~ .DataField label {
	color: rgb(248,148,32);
}


Both the "Marital Status" and "Phone" Data Fields' labels are styled.

Summary

Selection Type

CSS Rule

Selected Data Elements

Data View Result


Generic element selection

.DataField label {
  color: rgb(248,148,32);
}

Selects every Data Field's label and colors it orange.


Named element selection

.Hire_Date label {
  color: rgb(248,148,32);
}

Selects only the "Hire Date" Data Field's label and colors it orange.


Descendent children selection

  •   combinator
.Address_Info .DataField label {
  color: rgb(248,148,32);
}

Selects the Data Fields' labels for all children at every descendent level in the "Address Info" Data Section and colors them orange.


Immediate children selection

  • > combinator
.Address_Info > .DataField label {
  color: rgb(248,148,32);
}

Selects the Data Fields' labels only for children in the first level in the "Address Info" Data Section and colors them orange.


Adjacent sibling selection

  • + combinator
.Address_Info + .DataField label {
  color: rgb(248,148,32);
}

Selects the first sibling Data Field's label after the "Address Info" Data Section and colors it orange.

  • "Sibling" means the Data Elements are in the same hierarchical level of the Data Model.
  • "After" means following sequentially, in listed order from top to bottom.


General sibling selection

  • ~ combinator
.Address_Info ~ .DataField label {
  color: rgb(248,148,32);
}

Selects all sibling Data Fields' labels after the "Address Info" Data Section and colors them orange.

  • "Sibling" means the Data Elements are in the same hierarchical level of the Data Model.
  • "After" means following sequentially, in listed order from top to bottom.

Click here to return to the top of this tab.

Selector Quick Reference

Selector

Data Element Selection Information

.DataField

Selects Data Fields

.DataSection

Selects single-instance Data Sections

  • OR the elements representing the individual section instances of a multi-instance Data Section.

.DataGridCollection

Selects multi-instance Data Sections

  • This is the parent element that houses one or more DataSection elements, one for each extracted section instance.

.DataTable

Selects Data Tables

.DataColumn

Selects Data Columns

.caption

The caption class represents a Data Section or Data Table's caption label.

  • Typically this is the Data Section or Data Table object's name.
  • Less typically, this label is generated from the Data Section or Data Table's Caption property.

label

label is an HTML element used to represent a Data Field's label (its name).

th.DataColumn

This is the easiest selector to select all Data Column labels.

  • th is an HTML element representing each column's table header text in a table's header row.
  • DataColumn is the CSS class representing Data Column Grooper objects.

input

input is an HTML element used to create an editable textbox to enter single-line Data Field and Data Column values.

  • If you only want to style Data Field single-line textboxes use .DataField input as your selector.
  • If you only want to style Data Column single-line textboxes (i.e. cells in an extracted Data Table) use .DataColumn input as your selector.
  • Be aware for multi-instance Data Sections, the editable section number textbox in the navigation bar is also an input element. If you just use input as your selector you will style this element in multi-instance Data Sections as well.

div[contenteditable="true"]

Textboxes for multiline Data Fields are rendered as a content editable div element. This selector will style both multiline Data Field and Data Column values.

  • If you only want to style Data Field multiline textboxes use .DataField div as your selector.
  • If you only want to style Data Column multiline textboxes (i.e. cells in an extracted Data Table) use .DataColumn div as your selector.

select

select is an HTML element used to create dropdown selection lists Data Field and Data Column values.

  • If you only want to style Data Field textboxes use .DataField select as your selector.
  • If you only want to style Data Column textboxes (i.e. cells in an extracted Data Table) use .DataColumn select as your selector.

.DataValue

DataValue is a class attached to all types of editable textboxes (single-line, multiline, and dropdown selection lists). Use this selector if you want to style all input boxes of all types the same way.


Types of Styling Available

There is A LOT you can do with CSS. There's far too much for us to cover completely. However, there are a few common types of styling you may want to apply to your Data Model.

In this section, we will detail some basic examples as they relate to the following categories:

Font and Text Styling

Font and text formatting are some of most basic, but also most important, considerations when building a website. We will review a few of the standard CSS properties that can alter the text labels in a Data Model.


Keep your eye on the "Hire Date" field. Each of the CSS rules we demonstrate will affect its field label.

The font-size property will adjust the size (height) of the font. Font size can be adjusted using absolute values or relative values.


Using the CSS rule below, we've adjusted the "Hire Date" field's label absolutely, setting it to a specific value (21px).

.Hire_Date label {
  font-size: 21px;
}

You can also set the font size relatively by setting the font size as a percent or with an "em" value.

  • 1em = the current font size. Therefore 0.5em = half the current font size. 2em = double the current font size. And so on.
  • Many developers prefer to use relative sizing as it tends to work better across all browsers and consider using em values to be best practice.


The default size of Data Field labels is set to 14px in Grooper. Therefore, the following CSS rules should produce identical results:

.Hire_Date label {
  font-size: 21px;
}
.Hire_Date label {
  font-size: 1.5em;
}
.Hire_Date label {
  font-size: 150%;
}

The font-style allows you to italicize text.


The CSS rule below italicizes the "Hire Date" field.

.Hire_Date label {
  font-style: italic;
}

The font-style property may be set to one of the following:

  • normal
  • italic
  • oblique

If no italic or oblique face for the font is available, the browser will attempt to mimic the sloping effect. If italic is selected, but there is no italic face for the selected font, the browser will attempt to use the oblique face before mimicking effect (and visa versa if oblique is selected).

FYI

What's the difference between italic and oblique? Good question. The short answer is "not much".

  • Officially, “Italic forms are generally cursive in nature while oblique faces are typically sloped versions of the regular face.”
  • For most fonts, there is little to no difference between italic and oblique faces.

The font-weight property allows you to bolden or lighten text (when available).


The CSS rule below bolds the "Hire Date" field.

.Hire_Date label {
  font-weight: bold;
}

The font-weight property may be set to one of the following:

  • normal
  • bold
  • bolder
  • lighter

If selected and the font being used has a "bold" or "normal" version, the browser will use that. If not, it will attempt to mimic a bold or normal version. The browser will not attempt to mimic a "lighter" or "bolder" version if none are found.

The font-variant property allows you format your text in small caps.


The CSS rule below turns the "Hire Date" field to small caps.

.Hire_Date label {
  font-variant: small-caps;
}

The font-variant property may be set to either of the following:

  • normal
  • small-caps

The font-family property sets what font family should be used to render the text.


The CSS rule below changes the "Hire Date" field from the default font (Open Sans) to Courier New.

.Hire_Date label {
  font-family: Courier New;
}

Be aware a font will only display if it is installed by the browser or on the device viewing the webpage. The following fonts are considered "web-safe". These are fonts universally installed by all browsers.

(Generally) Web-Safe Fonts

  • Arial (sans-serif)
  • Verdana (sans-serif)
  • Tahoma (sans-serif)
  • Trebuchet MS (sans-serif)
  • Times New Roman (serif)
  • Georgia (serif)
  • Garamond (serif)
  • Courier New (monospace)
  • Brush Script MT (cursive)


However, there are no 100% web safe fonts. While these are "universally" installed across "all" browsers, there's always a chance the font is not installed properly or is otherwise missing. That's why it's best practice to use a fallback font.

  • Fallback fonts are separated using a comma.
  • For example: font-family: Tahoma, Verdana, sans-serif;
    • The browser would first attempt to use Tahoma.
    • If that font cannot be found, it then attempts to use Veranda.
    • If that font cannot be found it will use the generic system sans-serif font for the browser.


AT BARE MINIMUM, you should always include one of the following generic fallback fonts when declaring a font family:

  • sans-serif
  • serif
  • monospace
  • cursive
  • fantasy

The text-align property allows you to set an alignment for text inside the element.


The CSS rule below right aligns the "Hire Date" field's text within its label element.

.Hire_Date label {
  text-align: right;
}

You may choose one of the following alignments:

  • left (This is the default, in most cases)
  • right
  • center
  • justify

As we've seen in previous examples, the color property styles the element's text content's color.


Using the CSS rule below, we've adjusted text color for the "Hire Date" field's label, using the RGB color value for "Grooper orange".

.Hire_Date label {
  color: rgb(248,148,32);
}


Colors can help draw a user's attention and separate content in meaningful ways. There's also more to coloring a webpage than just coloring text. We'll talk more about color styling in the Color Styling section of this article.

Text Style

CSS Rule

Selected Data Elements

Data View Result


Font size

.Hire_Date label {
  font-size: 21px;
}

Increases the "Hire Date" Data Field's font size to 21 pixels high.


Font style (italics)

.Hire_Date label {
  font-style: italic;
}

Italicizes the "Hire Date" Data Field's label.


Font weight (bolding text)

.Hire_Date label {
  font-weight: bold;
}

Bolds the "Hire Date" Data Field's label.


Font variant (small caps)

.Hire_Date label {
  font-variant: small-caps;
}

Turns the "Hire Date" Data Field's label to small caps.


Font families

.Hire_Date label {
  font-family: Courier New, monospace;
}

Changes the "Hire Date" Data Field from the default font (Open Sans) to Courier New. If Courier New cannot be rendered, the system monospace font will be used as a fallback font.


Text alignment

.Hire_Date label {
  text-align: right;
}

Right aligns the "Hire Date" Data Field's text within its label element.


Text color

.Hire_Date label {
  color: rgb(248,148,32);
}

Changes the "Hire Date" Data Field's label's text color to "Grooper orange", using the RGB color value.

Click here to return to the top of this tab.

Styling Data Section and Data Table Caption Labels


A Data Section or Data Table's header caption is itself just another child element rendered on a webpage. All Data Section and Data Table HTML elements have a child element with a caption class styling their caption in the Review screen.

When it comes to styling Data Section and Data Table captions, you'll need to use the .caption selector. This will select any element with the caption class.

FYI

The caption's text will default to the Data Section's or Data Table's name. However, you can create custom captions using the Data Section or Data Table object's Caption property.


All captions will be styled if you simply use .caption for the CSS rule's selector, as in the rule below:

.caption {
  color: rgb(248,148,32);
  font-size: 1.75em;
  font-variant: small-caps;
}


For more specific styling, use more specific selectors. For example, the CSS rule below would style only Data Table elements' captions:

.DataTable .caption {
  color: rgb(248,148,32);
  font-size: 1.75em;
  font-variant: small-caps;
}


You can also remove a caption by using the display: none; declaration.

For example, the following CSS rule would remove the caption for any child Data Section in the "Address Info" section.

.Address_Info .DataSection .caption {
  display: none;
}


See here, the "City State Zip" caption has been entirely removed in the Review viewer.

Margin, Border, and Padding Styling

There's good reason why a div HTML element is named so. A div creates a division within a document, making it more distinct from other elements on the webpage. Margins, borders and padding help make the divisions between HTML elements visually more distinct by increasing the space between the elements (margins), outlining the elements (borders) and increasing the space within an element (padding).

Effective use of margins, borders and padding can increase the readability and accessibility of your Data Model when viewed in a Review viewer.


If you've spent any amount of time with CSS, you've probably seen the "Box Model".

This diagram is designed to help you better understand the different dimensions of an HTML element, including:

  • The content's width and height
  • The padding size
  • The border width
  • The margin size


When styling an element you can use the margin, border, padding, height and width properties to better space out and define different elements.


As this pertains to styling Data Elements, this can help make your Data Model more readable and better help create logical section divisions in the Review viewer.

FYI

Adjusting the margin, border and padding values will adjust these properties on all four sides (top, bottom, left and right) with the same measurement.

You can specifically adjust one side's value by adding -top, -bottom, -left or -right to the property, depending on which side you want to adjust.

  • For example, margin-left would only adjust the left margin, leaving the top, bottom and right margins alone.


The margin properties adjust the space between HTML elements.


One practical use of margins is to effectively indent Data Elements to better define sections of fields in the Review viewer.


This CSS rule, indents all Data Sections by increasing the left margin value.

.DataSection {
  margin-left: 24px;
}
  1. See here, the "Address Info" Data Section is now indented.
    • There is now 24 pixels of whitespace on the left boundary of the element.
  2. Since we selected all Data Sections, the "Address Info" section's child Data Section also has its left margin increased by 24 pixels.


The margin property is also often leveraged to center HTML elements.


This CSS rule effectively centers all Data Tables by assigning their left and right margins to auto.

.DataTable {
  margin-left: auto;
  margin-right: auto;
}


The border property creates a stroked border around the HTML element. When defining the border property, you can control the border's width, style (e.g. "solid" or "dashed") and color.


Borders are another way of visually separating content. When used to style Data Sections and Data Tables, this can better divide out the Data Elements within your Data Model.


Borders are always are always defined by specifying at least the border's width and style.


For example, the CSS rule below adds a solid border 1 pixel wide around all Data Tables.

.DataTable {
  border: 1px solid;
}


Once you start adding borders to elements in your Data Model, the padding,height and width properties become even more important. This is particularly the case when adding borders to Data Section elements.


Using the CSS rule below, we've added a solid 1 pixel border around all Data Sections.

.DataSection {
  border: 1px solid;
}

There is effectively no padding specified here. As it stands, having a border around Data Sections doesn't visually improve the Data Model. This doesn't really do anything to improve the users experience in Review and, frankly, looks bad.

Next, we will add some padding to these elements to vastly improve the Data Sections' styling.


The padding properties adjust the space around the HTML element, between the element and any defined border. Another way of thinking about padding is it extends the height and/or width of the element.


Padding is almost always specified when adding a border to an element. Without any padding, the border butts right up to the boundaries of the element's content. This can be visually jarring and confusing. The extra padding helps increase readability by adding some "breathing room" between the element's content and its border.


By adding just a little padding around our Data Section elements we can start to see the benefits of adding a border.

Below, the CSS rule adds a 1 pixel border around Data Sections and increases their padding by 12 pixels on all sides.

.DataSection {
  border: 1px solid;
  padding: 12px;
}

See here, the space between the element and the border are better spaced out. 12 pixels have been added to the top, bottom, left and right edges to the element, between the 1 pixel wide solid border.


If you prefer the look of rounded boxes, you should use the border-radius property.


This is the same CSS rule with a border-radius declaration added. This rounds out the borders corners using a 5 pixel radius.

.DataSection {
  border: 1px solid;
  padding: 12px;
  border-radius: 5px;
}


Next, we're going to visit the height and width properties to further style the look of our Data Sections.


Aside from adjusting margins and padding to space out an element, it can be beneficial to adjust the element's actual width and height. This can be done with height and width properties (as well as min-height/max-height and min-width/max-width).


Here's an example of an element's width gone awry.


By default, Data Field and Data Section elements take up the entire width of a single line in the Data Viewer. If you're using the standard "list layout" style, you don't really notice it, but once you start stroking Data Sections and other elements with a border, it becomes a bit of an eye sore. As you can see here, the stroke around the "Address Info" section extends to the edge of the Data Viewer.


We're going to clean things up by adjusting the width of our Data Sections.


The CSS rule below adjusts the maximum width of all Data Sections by adding a max-width specification.

.DataSection {
  border: 1px solid;
  padding: 12px;
  max-width: 400px;
}

The result is a much cleaner, more readable collection of Data Sections on the page.


Why did we use the max-width property instead of the width property? The width property sets a literal width. The max-width property is more dynamic. Elements' widths will be adjusted up to a maximum value.


In our case, one of our Data Sections is a child of another data section. If we used the CSS rule below, using the width property, the result would be less ideal in this case.

.DataSection {
  border: 1px solid;
  padding: 12px;
  width: 400px;
}

There are plenty of circumstances in which the literal width specification would be appropriate. It just was not appropriate here, given one Data Section element is a sub-element of another Data Section. Using the max-width property allows the child Data Section to be dynamically resized to fit within the parent Data Section.

There is one element width you cannot adjust with CSS, an input element's width.


To adjust the width of a Data Field or Data Column's input box, you must use the Display Width property in the object's property grid.

  1. Select the Data Field or Data Column whose input box you wish to adjust.
  2. Enter the width (in pixels) in the Display Width property.
  3. The input box's width will be adjusted to the entered value.

Style Description

CSS Rule

Selected Data Elements

Data View Result


Margins

.DataSection {
  margin-left: 24px;
}

Adds 24 pixels to all Data Sections' left margin. Effectively, this left indents all Data Section elements 24 pixels.

  • Keep in mind the "City State Zip" Data Section is a child of the "Address Info" Data Section, and thus a sub-element of the "Address Info" HTML element.
  • Therefore, the "City State Zip" Data Section is indented 24px from inside the "Address Info" Data Section.


Margins

.DataTable {
  margin-left: auto;
  margin-right: auto;
}

Sets all Data Tables' left and right margins to auto. Effectively, this centers all Data Table elements.


Borders

.DataSection {
  border: 1px solid;
}

Outlines all Data Sections with a 1 pixel wide border.


Borders and Padding

.DataSection {
  border: 1px solid;
  padding: 12px;
}

Outlines all Data Sections with a 1 pixel wide border. Adds 12 pixels of padding between the element's content and the border.


Borders and Padding

.DataSection {
  border: 1px solid;
  padding: 12px;
  border-radius: 5px;
}

Outlines all Data Sections with a 1 pixel wide border. Adds 12 pixels of padding between the element's content and the border. Rounds the corners on the borders.


Borders, Padding and Width

.DataSection {
  border: 1px solid;
  padding: 12px;
  width: 400px;
}

Outlines all Data Sections with a 1 pixel wide border. Adds 12 pixels of padding between the element's content and the border. Sets the literal width of all Data Section elements to 400 pixels wide.


Borders, Padding and Width

.DataSection {
  border: 1px solid;
  padding: 12px;
  max-width: 400px;
}

Outlines all Data Sections with a 1 pixel wide border. Adds 12 pixels of padding between the element's content and the border. Sets the maximum width of all Data Section elements to 400 pixels wide.

Click here to return to the top of this tab.

Color Styling

Colors are useful in a variety of different ways. They don't just "look pretty". They're used to call attention to different portions of a document, divide sections on a document, or distinguish between portions of a document.

There are a lot of ways you could style elements' colors in HTML (and therefore Data Elements in Grooper's Data Viewer). We're going to focus on the three most common ways colors are styled:

  • Text colors
  • Border colors
  • Background colors

First, how do you pick a color? How do you define whether something is red or blue or hot pink? There are a few different ways to define a color value in CSS.

You can specify colors in CSS in the following ways:

#FFF8DC

Hexadecimal colors

  • Ex: #FFF8DC is the color known as "cornsilk".

#FFF8DC50

Hexadecimal colors with transparency

  • Ex: #F8942050 is cornsilk with a 50% transparency.
  • The last two numbers (e.g. #F8942050) set the transparency transparency value on a scale from 00 to FF.
    • 00 indicates full transparency. FF indicates full opacity. Anything from 01 to 99 is a percentage value in between.

rgb(255, 239, 213)

RGB colors

  • Ex: rgb(255, 239, 213) is the color known as "papaya whip".
  • Colors in the RGB color model are defined by their intensity values (from 0 to 255) of red, green and blue light.

rgba(255, 239, 213, .5)

RGBA colors

  • Ex: rgba(255, 239, 213, .5) is papaya whip with a 50% transparency.
  • RGBA colors use the RGB color model with an additional alpha channel. The alpha channel (e.g. rgba(255, 239, 213, .5)) sets the color's transparency/opacity.
    • This sets the opacity value on a scale from 0 (fully transparent) to 1 (fully opaque).

hsl(36, 100%, 84%)

HSL colors

  • Ex: hsl(36, 100%, 84%) is the color known as "Navajo white".
  • The HSL color model is an alternative to the RGB color model designed by computer graphics researchers in the 1970s to more closely correlate color values to how the human eye perceives color. It represents colors based on their hue, saturation and brightness values.

hsla(36, 100%, 84%, .5)

HSLA colors

  • Ex: hsla(36, 100%, 84%, .5) is Navajo white with a 50% transparency.
  • HSLA colors use the HSL color model with an additional alpha channel. The alpha channel (e.g. hsla(36, 100%, 84%, .5)) sets the color's transparency/opacity.
    • This sets the opacity value on a scale from 0 (fully transparent) to 1 (fully opaque).

BurlyWood

Predefined color names used across browsers

  • Ex: BurlyWood is the color known as "burlywood".
  • You can find a list of color names supported across browsers here.


Which color space should you use? RGBA should be your default choice.


In the opinion of the Grooper development team, it is best practice to use RGBA color values.

We've already seen text color styling in this article, using the color property. The color property change the text's color within an element.

For example, this CSS rule will color the "Employee Name" Data Field's input box text yellow.

.Employee_Name input {
  color: rgba(255,255,50,1)
}

Something like this can be useful for a Data Field value that needs highlighting. If a user has a need to keep referencing an extracted value, this will more clearly call it out in the Review viewer.

You can style a border's color using either the border-color or border property.

If the HTML element already has a border specification, you can use the border-color property to recolor the border.

This CSS rule recolors the border around the "Employee Name" Data Field's input box.

.Employee_Name input {
  border-color: rgba(248,148,32,1);
}

Please note, if the element doesn't already have a border specified (either from an inherited class or in the CSS rule itself), the border-color property will do nothing. There is no border to color at that point.

You can use the border property as a shortcut to create a border, setting the width, style and color all with a single property.

The first description line in the following CSS rule creates the border, including coloring it orange with the RGBA color rgba(248,148,32,1)

.DataSection {
  border: 1px solid rgba(248,148,32,1);
  border-radius: 5px;
  padding: 12px;
  max-width: 400px;
}

Text is considered the "foreground" of an HTML element. Whatever is behind it counts as "background". The background-color property (appropriately enough) colors an element's background. Coloring an element's background can be a great way of drawing attention to certain Data Elements or making visual breaking points between groups of Data Elements.

This CSS rule colors the background of the "Employee Name" Data Field's input box yellow. This is another way to make an important field stand out from others.

.Employee_Name input {
  background-color: rgba(255,255,50,1);
  color: rgba(0,0,0,1);
}

Notice we also changed the text color to black (color: rgba(0,0,0,1)). If we did not, the text would have been unreadable on a yellow background.

  • Be aware once you start styling background colors, you may need to style other colors (particular text colors) in order to make your Data Model more readable in the Review viewer.

Background color styling is also a great way to make your Data Sections distinct.


We're using the following CSS rule to style our Data Sections.

  • The first description (background-color: rgba(0,0,0,.3))colors the Data Sections' backgrounds. Furthermore, we're taking full advantage of the RGBA alpha channel.
    • The rule colors the background of all Data Sections black with a 30% transparency. Effectively this slightly shades Data Sections.
    • Because the "City State Zip" Data Section is nested within the "Address Info" Data Section it is extra shaded! Its black transparency is overlaid on top of the already darkened background behind it.
.DataSection {
  background-color: rgba(0,0,0,.3);
  border: 1px solid rgba(255,255,255,.5);
  border-radius: 5px;
  padding: 8px;
  max-width: 400px;
  margin-top: 8px;
}

The combination of borders, padding and color shading really separates these Data Sections from the rest of the Data Model.

FYI

Please be aware any padding in an element is considered part of the element's background. As such, space specified by padding will be colored by a background-color specification.

  • Margins are space outside the element. Space specified by margins will not be colored by a background-color specification.
Click here to return to the top of this tab.

Layout Styling (and Mirroring a Document's Layout)

Without CSS, you'd have no control over how Data Elements are laid out in the Data Viewer. They would appear on the screen essentially as a list, with each Data Field occupying a single line. However, CSS rules give you a great deal of flexibility in terms of laying out the various elements that make up the Data Elements in your Data Model.


For example, one handy thing you can do with CSS is structure your Data Model in Review to mimic a document's layout. While you can't do this for every kind of document, for documents whose layout never changes, like structured forms, you can. These are documents where you expect to find fields, sections and tables at the same physical location with the same physical dimensions.

Using Data Sections to better group and organize sections of Data Fields and using CSS to style those Data Sections and Fields, you can get pretty close to the same layout in the Data Viewer screen in Review as you have on the page.

This can be a tremendous boon to document reviewers. If the entry fields are laid out like are on the actual document, they don't have to do nearly as much searching for what they're trying to enter. Ultimately, this saves time on data entry and can reduce error rates as well.


We describe this kind of Data Model styling as a "Mirrored Layout". The Data Model is styled to mirrors how fields, sections and tables are laid out on the physical document itself. Going from the basic "List & Card Layout" to a "Mirrored Layout" is all about styling where and how HTML elements appear next to one another in the browser.


As you can see from the "List & Card Layout" image, some styling has already been done to this Data Model. The Data Field label widths are increased, and the Data Sections and Data Table have some border and background color styling.

  • This will be our "starting point". You can click the "List & Card Layout CSS" tab below for the full text CSS.


With just a few key adjustments, we will end up with a Mirrored Layout Data Model. Where and how the Data Fields and elements are lined up more closely match where and how they're lined up on the source document.


You could spend a great deal of time pouring over the CSS getting everything to line up just right, but the basics can be boiled down to three concepts:

  1. Using Data Sections to act as parent HTML elements for more simplified styling.
  2. When to use inline vs block elements.
  3. Effectively using width and other spatial dimensions.

anchor text"

Before even touching CSS, you should think about organizing your Data Model to better lay out Data Elements in the Review Viewer. Data Sections can be extraordinarily beneficial to this end.

A Data Section can act as a simple bucket to hold other Data Elements to better organize your Data Model. They will also act as a parent HTML element holding the Data Elements. You can use CSS to physically constrain the Data Section's child elements in the browser, order a collection of elements on top of or to the side of other Data Sections and their elements. You can also use children selectors to style just the elements within a specific Data Section, distinct from the typical styling for the rest of the Data Model.


Just looking at the document, you should mentally break up collections of elements base on how they are grouped on the page and similarities in layout. These mental divisions of fields will be candidates for their own Data Sections in our Data Model.

  1. This could be considered a section.
    • All the fields have the same label/value orientation with the label on top of its value. Each field is laid out horizontally, rather than vertically.
    • We will call this the "Personal Info" section
  2. This is extremely similar to the section before it. It could be its own section, or not.
    • The fields also have the same label/value orientation as the "Personal Info". These fields could be placed in the "Personal Info" section, but we will discuss advantages to placing it in its own section.
    • Also, these fields are logically of the same "kind" if nothing else. Even if placing them in a Data Section is not required for CSS styling, it's often helpful to reviewers to group related elements together in a Data Section anyway.
    • These fields are all currently contained in a Data Section named "Address Info" currently. We will elect to keep these fields in their own "Address Info" section.
  3. This is an excellent candidate for its own section.
    • These fields are laid out differently from the rest of the document. The fields have a left to right label/value orientation and are stacked on top of each other. We can use a Data Section to style these fields differently from how we will end up styling the rest of the Data Fields in the Data Model.
    • We will call this the "Additional Info" section.
  4. Tables can go in Data Sections but often do not need to.
    • A Data Table is a kind of parent container itself with Data Columns as its children.
    • There's no real reason for us to put the Data Table in a Data Section. All the styling it needs can be applied to the Data Table itself. It would be redundant or, at the least, overkill to place the Data Table in its own Data Section then style the Data Section.

We have adjusted our Data Model to reflect these divisions by adding some Data Sections.

  1. We've placed the first four Data Fields in a new Data Section named "Personal Info"
  2. The Data Fields in the existing "Address Info" Data Section can stay put.
    • We've made no change here.
  3. These Data Fields have been placed into a new Data Section named "Additional Info"
  4. The "Dependents" Data Table is fine as is. It does not need to be placed into a Data Section.
    • We've made no change here.


Please be aware we're using Data Sections as an organizational tool not as an extraction tool (subdividing a document into one or more section instances). As such we've adjusted the following properties for our Data Sections:

  • Scope is set to SingleInstance.
  • Miss Disposition is set to Default to Parent.

This will ensure a single-instance Data Section is rendered instead of a multi-instance Data Section, and the Data Fields extractors will collect data from the parent instance, which in this case is the full document.


You should also be more cognizant than normal of which Data Fields are in which Data Sections. Because our goal is to manipulate how Data Elements are laid out over the web, we need to take extra care to ensure they are in the right spots in our Data Model to begin with.

For instance, we goofed.

  1. The "Hire Date" and "Phone" Data Fields are in the wrong spot if our goal is to mirror the document's layout.
  2. The listed hire date is on the bottom half of the page.
    • The "Hire Date" Data Field is in the "Personal Info" Data Section, which is the first Data Section in the Data Model.
    • Data Elements are displayed in the Review Viewer first to last from the top of the page to the bottom.
  3. The listed phone number is at the top of the page.
    • The "Phone" Data Field is way toward the bottom of the Data Model in the "Additional Info" Data Section.
  4. The two Data Fields simply need to be swapped.
    • "Phone" should be in the "Personal Info" Data Section.
    • "Hire Date" should be in the "Additional Info Data Section.
    • Furthermore, we've taken additional care to place these Data Fields within the right order within the Data Section itself.
      • "Phone" is the last field in the "Personal Info" section (from left to right on the page).
      • "Hire Date" is the first field in the "Additional Info" section (from top to bottom).


Now that our Data Fields are organized into Data Sections we can better tackle our next goal: changing the Data Fields' layouts to match more closely with those on the document.

For example,

  1. Our Data Fields in the "Personal Info" Data Section' are stacked on top of each other vertically.
  2. However, on the page they are laid next each other horizontally.
  3. Furthermore, several labels on the document are stacked vertically on top of their value.
  4. However, in our Data Model the value is listed to the right of its label.


Next, we will manipulate display properties to change what we see in the Data Viewer to mirror how fields are laid out on the document.

To understand how HTML elements are laid out on a webpage, you need to have a concept of "inline" and "block" elements (as well as a special type of inline element called "inline-block").

Block elements always start on a new line.

  • Put another way, they take up as much width on the screen as possible.
    • If the element is at the top of HTML hierarchy it would be as wide as the computer monitor.
    • If is contained in a parent HTML element, it would be as wide as the parent element allows).
  • Browsers will automatically add some left and right margins to block elements.
  • By default, Data Fields are rendered as block elements.

Inline elements do not start on a new line.

  • They only take up as much width as necessary.
    • Multiple inline elements in a row will be placed from left to right on a single line.
    • If the edge of the screen or parent HTML element is encountered, an element will wrap to the next line (if wrapping is enabled) or the viewer will need to use a horizontal scroll bar to view the element.
  • By default, a Data Field's label and input elements are a type of inline element.

Specifically, label and input elements are "inline-block" elements.

Inline-block elements do not start on a new line, but you can adjust the width and height of the element.

  • A true inline element's width and height is calculated automatically, only taking as much space as necessary to render the element.
  • Inline-block elements allow you to adjust the element's width and height properties in a CSS rule.


In general, when styling elements in a Data Model it is preferable to use the inline-block mode over the inline mode. Adjusting the widths and heights of elements is often critical to get your Data Model laid out the way you want in the Data Viewer.

Getting our Data Model to look more like the document's layout has a lot to do with manipulating the inline and block modes using the display property.

On our document, several of the fields' labels are stacked vertically on top of the value. We can replicate this layout by simply changing our Data Fields' label and input elements from inline-block elements to block elements.

The rule below will accomplish this goal:

.DataField * {
  display: block;
}

FYI: The * character in the selector selects all child elements. In this case, that's the Data Field's label and input elements.

File:2023-data-model-style-sheets-layout-10.png


Next, we need to change the layout of the Data Fields themselves (as the parent element containing the label and input elements).

On the document, fields are laid out horizontally next to each other, rather than being stacked vertically on top of each other. Because Data Fields are block elements by default, our Data Fields have more of a vertical layout. To get a more of a horizontal layout, we can simply change their display mode to inline-block. This will allow multiple Data Fields to be displayed across a single line.

Adding the rule below will accomplish this goal:

.DataField {
  display: inline-block;
}

What about this section of fields on the document? Their layout is different from the rest of the document. The layout is actually more like the default Data Field styling. What can we do to fix this?


Lucky for us, we organized our Data Fields into sections. Both of these fields are in a Data Section named "Additional Info". All we need to do is select the Data Fields within the "Additional Info" and re-style them to more appropriately match their layout on the document.

Adding, the following CSS rules will suffice:

.Additional_Info .DataField {
	display: block;
}
.Additional_Info .DataField * {
	display: inline-block;
}


With these CSS rules in place, the Data Model is starting to mirror the document's layout more closely. But it could still use some work.


Next, we're going to talk about using spatial dimensions (specifically elements' widths) to better lay out the Data Elements in the Data Viewer.

  1. If nothing else, we need to expand some of our input elements so we can see the full extracted values!


FYI

We did two things to make our Data Model more closely mirror the document's layout:

  1. Change the label/input orientation from horizontal to vertical.
  2. Change the Data Fields order from a vertical list to a horizontal list of Data Fields.


To accomplish this we used two CSS rules:

.DataField * {
  display: block;
}

.DataField {
  display: inline-block;
}


There are other display modes that would accomplish this same end and do so with only a single CSS rule.

We could have rendered all Data Fields as inline-grid elements using the single rule below:

.DataField {
  display: inline-grid;
}

Or, we could have rendered all Data Fields as inline-flex containers with a flex direction of "column", using the single rule below:

.DataField {
  display: inline-flex;
  flex-direction: column;
}

While there are certainly differences between these various display modes and CSS rules, the end result as far as our purposes in using CSS to style a Data Model for view during Review are often similar (if not identical).

Styling your Data Elements dimensions can be an effective way to help your Data Model mirror your document's layout. Sometimes this boils down to nothing more than adjusting the width of your Data Field's input elements.


Check out our "Employee Name" Data Field.

  1. As a practical matter, the input box is too narrow. The reviewer can't see the whole name extracted.
  2. But also, isn't the field a little wider on the document itself? At least compared to the "DOB" "SSN" and "Phone" fields?


We can kill two birds with one stone here. Widening the "Employee Name" Data Field's input label will both help our reviewer's see the full extracted value as well as mirroring the field's layout on the document a little better.


Remember, you cannot use CSS to style the width of input elements. You must adjust the width using the Data Field's Display Width property in Grooper.

  1. In the Node Tree Panel, navigate to the Data Field whose input element you wish to adjust.
  2. Select the Display Width' property and enter the desired width, in pixels.
    • We've entered 200 for our "Employee Name" Data Field's Display Width.200
  3. This will increase the input element's width in the Data Viewer.


This will help but we have some work to do still.

  1. Our "Employee Name" field is adjusted to a width that is more in line with the field's width on the document.
  2. However, you should notice some inconsistencies in the spacing between Data Fields now.
  3. This is because currently in our Style Sheet all Data Field label elements have a width of 132 pixels.

It doesn't really make sense for all our Data Fields' labels to be a set width now that most of them have a different layout orientation.

  1. It's only those label elements that are still inline-block elements that need to retain this width of 132 pixels.


Currently, we're using the following CSS rule to globally style the width of all Data Field label elements.

.DataField label{
  width: 132px;
}

In reality, the only label elements we want to behave that way are those in the "Additional Info" section. All we need to do is adjust the selector a little bit.

.Additional_Info .DataField label{
  width: 132px;
}


The result is a cleaner looking Data Model. The spacing is more even and the "Employee Name" field more accurately reflects the field's width on the document.


Next, we're going to take a look at the "Address Info" section of fields. It actually does mirror the document structure pretty well. The "Street" address field is on its own line. The "City" "State" and "Zip" fields are all on the next line together. But we've actually "overengineered" our Data Model a little bit.

As part of a previous styling discussion in this article, we added a "City State Zip" Data Section to the "Address Info" Data Section. This was purely academic and only done to illustrate some styling considerations when you have Data Sections inside of other Data Sections.


The real question is: Do we need to have this additional Data Model at all?

If nothing else, the "City State Zip" section makes the Data Model look a little clunky. If we don't need it, we should just get rid of it. Let's see what happens when we do.


At first glance, things look worse. Now all the fields are on a single line. We need to get back to where "Street Address" is on one line and the rest of the fields are on the next.


There's a number of ways we could get this to work out for us, but there are two very simple solutions:

  1. Change the "Street Address" Data Field from an inline-block element to a block element.
  2. Or, adjust the widths of one or more Data Fields so that the single line wraps correctly to two lines.

Option 1: Change "Street Address" to a Block Element

This may well be the simplest solution simply because the "Street Address" field is a single field that occupies the entire width of the document. What is a block element? It's an HTML element that occupies the entire width of whatever element its contained in. If the width of the document is analogous to the width of the Review screen, it sure seems like the "Street Address" field would be a good candidate for a block element.

All we need to do is add a CSS rule for the "Street Address" field, changing its display property to block.

.Street_Address {
  display: block;
}

Because "Street Address" is now a block element, it now takes up a whole line by itself. This is much more in line with what the document looks like.

Option 2: Adjust Input Widths and Let Elements Wrap Lines

Another option is to rely on line wrapping to get you what you want. There's only so much screen real estate for the Data Viewer to occupy. If you know roughly the size of the monitor your reviewers are using (or if you set a maximum width for a Data Section) you can control how elements wrap to subsequent lines but adjusting their widths.

We can adjust the width of one or more Data Field's input elements such that the inline collection of elements in the "Address Info" wraps to two lines instead of one.


Here, we've changed the "Street Address" Data Field's Display Width property to 536. 536 pixels is quite a bit of screen to cover. The "City" "State" and "Zip" fields are forced to wrap to the next line.


There are a few plus sides to this approach:

  1. You were probably going to increase the widths of these Data Fields' input box anyway.
    • Why does the "Street Address" field take up so much space on the document? Street addresses can be pretty long. Your reviewers will also want a wider input box so they can capture the whole address without scrolling.
  2. It more closely mirrors how the document looks.
    • If the "Street Address" field on the document takes up a whole line, and your goal is to make the Data Model look more like the document in the Review experience, why wouldn't you increase the width of the Data Field's input as much as possible?
    • Here, we've also increased the width of the "City" Data Field's input (adjusting its Display Width property to 312). That field is also longer on the document. Not as wide as the "Street Address" field. But wider than the "State" or "Zip" fields. Increasing its size just makes the Data Model look that much more like the document.


There is a downside to this approach. Because it relies on wrapping, you have to be very aware of screen sizes and how wide the Data Model is in the Data Viewer.


If we were to widen the Data Model panel in the Data Viewer, you can see the fields layout no longer mirrors the document. Given more horizontal space, the wrapping is different.


One way to resolve this issue is to set a maximum width value for the parent Data Section. If we say our Data Sections can only be up to a certain width, it won't matter how wide the screen is. We can ensure the wrapping always works the way we want by dictating the width of the HTML element containing the Data Fields.


Here we've added the following CSS rule:

.DataSection {
  max-width: 600px;
}

Now our wrapping works as expected, regardless of the width of the Data Model panel.

Below you will find the end-result CSS style sheet for our "Mirrored Layout" Data Model styling. You can copy and paste this text into the Style Sheet property of any Data Model.

  • After reading this article, can you figure out what each of these rules is doing?
.DataField * {
  display: block;
}

.DataField {
  display: inline-block;
}

.Additional_Info .DataField {
  display: block;
}

.Additional_Info .DataField * {
  display: inline-block;
}

.Additional_Info .DataField label {
  width: 132px;
}

.Address_Info {
  max-width: 600px;
}

.caption {
  margin-bottom: 12px;
}

.DataSection, 
.DataTable, 
.DataGridCollection {
  background-color: rgba(0,0,0,.3);
  border: 1px solid rgba(255,255,255,.25);
  border-radius: 5px;
  padding: 8px;
  margin-top: 12px;
  margin-bottom: 12px;
  margin-right: 12px;
  max-width: 600px;
}

.DataGridCollection .DataSection {
  border: none;
  background-color: rgba(0,0,0,0);
}

.DataTable {
  width: auto;
}

.DataTable > *:not(.caption) {
  margin-left: auto;
  margin-right: auto;
}
Click here to return to the top of this tab.

Generic Layouts

FYI

The Content Model and Data Model used to demonstrate these layouts can be found in the Grooper importable ZIP file found in the About section of this article.

The List Layout styles fields as a simple list. This type of layout will often use margins and horizontal widths to better space out a list of fields and sections of fields. Right margins are often employed to indent Data Sections to make them more visually distinct from fields at the root of the Data Model and other sections of fields.

Below is an example of a generic List Layout style sheet.

.DataField label {
  width: 152px;
}

.DataSection > .DataField,
.DataSection > .DataGridCollection,
.DataSection > .DataTable,
.DataSection > .DataSection {
  margin-left: 32px;
}

.DataTable > *:not(.caption) {
  margin-left: 32px;
}

.DataSection,
.DataTable,
.DataGridCollection {
  margin-top: 12px;
}

.DataModel > .DataSection,
.DataModel > .DataGridCollection,
.DataModel > .DataTable {
  margin-left: 32px;
}

The Flow Layout stacks labels on top of their input boxes and lists them horizontally, wrapping fields to the next line when reaching the end of the screen (or containing HTML element). This layout can pack several fields into a relatively small space, conserving screen real estate. Label widths are typically less important to specify uses this layout. Instead Data Field horizontal margins and input widths are utilized to space out fields.

Below is a generic Flow Layout style sheet.

.DataField {
  display: inline-grid;
  margin-right: 16px;
}

.DataSection,
.DataTable,
.DataGridCollection {
  margin-top: 12px;
}

The Card Layout relies heavily on Data Sections and borders to create distinct divisions between different kinds of fields on the document. Each section (or card) in the Card Layout will generally implore either a List Layout or Flow Layout within the boundaries of the card itself.

Below is a generic Card Layout style sheet.

  • This style sheet also uses the hover and focus-within pseudo-elements to lighten the borders around the card upon hovering your cursor and clicking inside the Data Section (focusing within it).
  • No background color was added to each card/section. However, that is often included in this style approach.
  • Because the fields in each card (i.e. the Data Fields in each Data Section) have a List Layout, you could call this a "List & Card Layout"
.DataField label {
  width: 152px;
}

.DataSection, 
.DataTable,
.DataGridCollection {
  max-width: 876px;
  border: 1px solid rgba(255,255,255,0.2);
  border-radius: 5px;
  margin-top: 16px;
  padding: 16px;
  padding-top: 8px;
}
	
.DataSection:hover, 
.DataTable:hover, 
.DataGridCollection:hover {
  border-color: rgba(255,255,255,.4)
}

.DataSection:focus-within, 
.DataTable:focus-within, 
.DataGridCollection:focus-within {
  border-color: rgba(255,255,255,.6)
}

Click here to return to the top of this tab.

Tips and Best Practices

Two Approaches: Global Element Styling VS Local Element Styling

Be aware you can style a Data Model in two ways:

  1. Globally - By editing the Data Model's Style Sheet.
  2. Locally - By editing any children Data Sections' or Data Tables' Style Sheets.
    • Styling a Data Section or Data Table's Style Sheet directly, simply limits the scope of accessible elements.


When configuring a Data Model's Style Sheet, you have global access to all Data Elements in the Data Model.

  • This means you can select any of them in a CSS rule.
  • Any style generically applied to a class (DataField for example), will be applied to all elements at any level in the Data Model's hierarchy.
  • You can style any specific Data Element by selecting it by name in the CSS rule.


When configuring a Data Section or Data Table's Style Sheet, you have local access to only its child Data Elements.

  • This means you can only select the child Data Elements in a CSS rule.
  • Any style generically applied to a class (DataField for example), will be applied only to child elements at the Data Section and Data Table's hierarchy.
    • Please note this means you cannot style the Data Section itself by editing its Style Sheet. You are only able to style children of the Data Section (or child HTML elements of the Data Section's HTML element).
  • You can style only specific children Data Elements by selecting them by name in the CSS rule.


Put another way, when you configure a Data Section or Data Table's Style Sheet, their name is prepended to the selectors you enter behind the scenes.

  • Question: Given a Data Section named "Header Details", what's the difference between the following two selectors:
    • Entered in the Data Model's Style Sheet: .Header_Details .DataField
    • Entered in the "Header Details" Data Section's Style Sheet: .DataField
  • Answer: Absolutely nothing! The selectors would select the same HTML elements in both cases.

So, why do one or the other? Let's look at the pros and cons.

Global Styling

Local Styling

Pros

Cons

Pros

Cons

  • All CSS rules are managed in a single style sheet.
    • Only have to go to one place in the node tree to edit your CSS.
  • Easiest way to globally apply styling to all elements of a certain type.
  • Style sheets can be lengthy and disorganized.
    • Particularly if you have a large Data Model with several Data Sections and Data Tables, each one needing more specific custom styling rather than a general style applied to all of them.
  • Can be used as an organizational tool.
    • Buckets all CSS rules applied to children of a given Data Section, creating a series of smaller style sheets instead of one big one.
    • This can be particularly helpful for larger Data Models with several Data Sections and Data Tables, all needing more specific custom styling rather than a general style applied to all of them.
  • CSS rules are managed across multiple style sheets.
    • Must go to multiple places in the node tree to edit your CSS.
  • Can be confusing to keep track of which HTML elements are accessible.
    • Only children, not self.
  • Can be confusing if styling both the Data Model and Data Section/Data Table style sheets.
    • Data Section and Data Table style sheets will always "win out". If you're expecting a CSS rule from the Data Model's style sheet to be applied but the Data Section's CSS rule says something different, the Data Section's rule is always going to be applied.

Styling Flat Data Models VS Hierarchical Data Models

Generally speaking, there are two types of Data Models:

  1. Flat Data Models.
    • All Document Types share a single Data Model at the root of the Content Model.
    • Flat Data Models are often simpler, but are intended to accommodate use cases where all Document Types share the same set of of data.
      • For example, you may have multiple Document Types for multiple vendors in an invoice processing model, but each Document Type's Data Model will collect the same set of information (invoice number, line item details, balance due, etc).
  2. Hierarchical Data Models.
    • Each Document Type executes its own unique Data Model formed by a hierarchy of inherited and children Data Elements.
    • Hierarchical Data Models are intended to accommodate situations where each Document Type has a unique or semi-unique set of data.
      • For example, a human resource document processing model may process a variety of documents (government forms like a W-4 form, internal forms, various benefits forms, etc), each with their own unique set of information you want to collect. But, they may share some information as well, such as an employee's name, date of birth or other identifying information.


Thus far in this article, we've focused on flat Data Models to keep things simpler. Once you start working with more hierarchical models, you need to be careful about where you're editing the CSS style sheet. Each Data Model in the hierarchy has a Style Sheet property. Much like the Data Elements from each Data Model are ultimately merged to form a Document Type's Data Model the CSS rules from each style sheet is merged into a single one as well.


There may be some confusion when multiple Data Models attempt to style a specific property for an element using different values. You need to keep in mind two things:

  1. The most specific selector will always be applied.
  2. In cases where the specificity is ambiguous, the highest level Data Model's style sheet will be applied.

Draft Note: #1 below is accurate and will always be accurate. #2 will change in an upcoming release


Here, we have two CSS rules that would ultimately select the same element (a Data Field's label element).

  1. The root Data Model style sheet sets the width to 400 pixels.
  2. The "Data Info" Document Types child Data Model style sheet sets the width to 140 pixels.

Which CSS rule is applied?


The child Data Model's CSS rule is applied. The label width is set to 140 pixels. Why?

  • .DataField label is a more specific selector than label
  • More specific selectors always win out.
    • When multiple Data Models' style sheets are edited, they are ultimately merged into a single style sheet for the extracted Data Model. So these multiple CSS rules end up on the same style sheet. More specific selectors always win out in any CSS style sheet.


What about where you have ambiguous selectors? Here, the two CSS rules use the exact same selector: .DataField label

Which CSS rule is applied?


The root Data Model's CSS rule is applied. The label width is set to 400 pixels. Why?

  • When multiple Data Models' style sheets use the same selector, the highest level parent Data Model's style sheet wins out.
    • The root Data Model is the highest parent in the Data Model hierarchy. When the two CSS rules are merged into a single style sheet, ultimately the root Data Model's rule is the one that is applied.

Assigning Variables

Creating and Using CSS Classes

Pseudo Elements

Examples

In this section, we will post various Data Model Style Sheet examples. Use them to get ideas for what you may be able to incorporate into your own Data Models.

Comments are included in some of these style sheets to document various CSS rules. See below for an example of a comment.

  • /*This is a comment*/

Editor's Note: Consider all the following CSS examples a "work in progress". These styles have not been extensively tested using real-world Content Models.

Generic Examples

If you have not seen them already, be sure to check out the Generic Layouts section of this article. If you're looking for simple, generic types of layout styles you will find some there.

Simple Invoice Model Examples

These are a couple different Style Sheet examples for a PO-based invoice model.

For a lot of document cases, you can't perfectly mirror a document's layout because you are processing a lot of different versions of the same kind of document.

Invoices are a good example of this. While you're always collecting (roughly) the same data from invoices (invoice number, invoice date, balance due, etc.), each different vendor is going to have a different format.

  • This Style Sheet attempts a "mixed layout" approach where the "Header Details" Data Section uses the "Flow Layout" and the "Amounts" Data Section uses a "List Layout".
  • This mixed approach styles the model to look at least more like an invoice than a flat list of fields.
  • This Style Sheet also styles the Data Section and Data Table captions differently (just for fun).

Full CSS

Data Model Preview

/*Generic Data Model styling*/

.DataSection {
  vertical-align: top;
  margin: 4px;
  height: 224px;
}

.DataField label {
  width: 120px;
}

.caption {
  text-align: center;
  border: solid rgba(255, 255, 255, .2);
  border-width: 1px 0px;
  margin-top: 16px;
  margin-bottom: 8px;
  padding: 4px 0px;
}

/*Header Details Data Section styling*/

.Header_Details {
  max-width: 416px;
  width: fit-content;	
}	
		
  .Header_Details .DataField {
    display: inline-flex;
    flex-direction: column;
  }

/*Amounts Data Section styling*/

.Amounts {
  max-width: 252px;
  text-align: right;
  margin-left: auto;
  margin-right: 24px;
}

  .Amounts .DataField label {
    margin-right: 8px;
  }

This Style Sheet renders Data Sections as inline-block elements.

  • See the difference in the two Data Model preview images where the "Amounts" Data Section is moved to come before the "Line Items" Data Table'.
  • This Style Sheet also removes all Data Section and Data Table captions to give you a look at what that looks like.


Full CSS

Data Element Order

Data Model Preview

/*Generic Data Model styling*/

.DataField label {
  width: 120px;
}

.caption {
  display: none;
}
	
.DataSection {
  border: 1px solid rgba(255,255,255,.1);
  border-radius: 5px;
  padding: 8px;
  display: inline-block;
  vertical-align: top;
  margin: 4px;
  max-height: 216px;
}

/*Header Details Data Section Styling*/

.Header_Details {
  max-width: 420px;
  width: fit-content;
}

  .Header_Details .DataField {
    display: inline-flex;
    flex-direction: column;
}

This Style Sheet attempts to completely invert the default color-scheme, going from a dark mode theme to a light mode one. Please note, this is the work of a CSS novice and may not be perfect, but should give you some ideas about how you can play around with color styling.

Full CSS

Data Model Preview

/*Variables*/

.DataModel {
  --focus-black: rgb(0,0,0);
  --unfocus-grey: rgba(0,0,0,.5);
  --hover-blue: rgba(0,0,255,.5);
}

/*Generic Data Model List Layout styling*/

.DataField label {
  width: 132px;
}

.DataSection > .DataField,
.DataSection > .DataGridCollection,
.DataSection > .DataTable,
.DataSection > .DataSection {
  margin-left: 32px;
}

.DataTable > *:not(.caption) {
  margin-left: 32px;
}

/*Color Styling. Note: "Invoice" is the name of the Content Model.*/

.Invoice {
  background-color: rgb(255,255,255);
  height: 100%;
}

.title-bar [title] {
  color: rgb(0,0,0);
}

  /*Caption Coloring*/

  .caption {
    color: var(--unfocus-grey)
  }
	
    /*Data Section Caption Colors*/
    .DataSection:focus-within h2.caption {
      color: var(--focus-black);
    }
		
    .DataSection:focus-within .DataSection h2.caption {
      color: var(--unfocus-grey);
    }
	
    .DataSection .DataSection:focus-within > h2.caption {
      color: var(--focus-black);
    }
		
    /*Multi Instance Data Section Caption Colors*/
    .DataGridCollection:focus-within .caption {
      color: var(--focus-black);
    }
		
    .DataGridCollection:focus-within .DataGridCollection .caption {
      color: var(--unfocus-grey);
    }
		
    /*There might be a simpler way to do this rule.  It accommodates a rare case where you have a parent multi-instance Data Section, a child single-instance Data Section and grandchild multi-instance Data Section.  It styles the grandchild multi-instance Data Section's caption upon focus.*/
    .DataGridCollection .DataSection .DataGridCollection:focus-within .caption {
      color: var(--focus-black);
    }
	
    /*Data Table Caption Colors*/
    .DataTable:focus-within div.caption {
      color: var(--focus-black);
    }
	
    /*Data Field and Data Column label colors*/
    .DataField label {
      color: var(--unfocus-grey);
    }

    .DataField:focus-within label {
      color: var(--focus-black);
    }
	
    th.DataColumn {
      color: var(--unfocus-grey);
    }

    th.DataColumn.focused {
      color: var(--focus-black);
    }
	
    /*Data Field and Data Column input colors. ".DataValue" is used in place of "input" to accomodate both single line and multiline fields/table cells.*/
    .DataField .DataValue,
    .DataColumn .DataValue {
      color: var(--focus-black);
      border-color: var(--unfocus-grey);
      border-width: 2px;
    }

    .DataField:focus-within .DataValue,
    .DataColumn:focus-within .DataValue, {
      color: var(--focus-black);
      border-color: var(--focus-black);
      border-width: 2px;
    }

    .DataField:hover .DataValue,
    .DataColumn:hover .DataValue {
      border-color: var(--hover-blue);
      border-width: 2px;
    }

Click here to return to the top of this tab.

Another Mirrored Layout Example


This is another example of a "mirrored layout" styled Data Model. It aims to more closely mirror the layout of the Application For Cow Ownership document, which is a much more data dense document than our example in the Layout Styling section of this article.

/*Establishes "highlight" CSS class*/

.highlight input {
  color: Yellow;
  font-weight: bold;
}

.highlight label {
  color: DeepSkyBlue;
}

/*Establishes basic styling for Data Sections and Data Tables*/

.DataSection, 
.DataTable,
.DataGridCollection {
  max-width: 876px;
  background-color: rgba(0,0,0,.2);
  border: 1px solid rgba(255,255,255,0);
  border-radius: 5px;
  margin-top: 16px;
  padding: 16px;
  padding-top: 8px;
}
	
  /*Colors borders around Data Sections and Data Tables when hovering your cursor over them (soft white) and entering fields (bright white).*/

  .DataSection:hover, 
  .DataTable:hover, 
  .DataGridCollection:hover {
    border-color: rgba(255,255,255,.3)
  }
	
  .DataSection:focus-within, 
  .DataTable:focus-within, 
  .DataGridCollection:focus-within {
    border-color: rgba(255,255,255,.6)
  }
	
/*Purely aesthetic rule to extend the background of a Data Table to the width of the widest Data Section*/

.DataTable {
  width: auto;
}
	
/*Establishes styling ONLY for Data Fields at the first level of the Data Model's hierarchy (That is to say any Data Field NOT in a Data Section).*/

.DataModel > .DataField {
  display: inline-block;
  margin-right: 32px;
  margin-top: 16px;
}

/*Aligns Data Field labels vertically on top of their input boxes for any Data Field in a Data Section and the "Comments" Data Field.*/

.DataSection .DataField, 
.Comments {
  display: inline-flex;
  flex-direction: column;
}

/*Styles the Education section and its elements. Mostly, syling is done to produce two  inline Data Tables inline beside the single Data Field in the section.*/

.Education {
  white-space: nowrap;
}

.Education .DataTable {
  display: inline-table;
  padding-left: 0px;
  padding-right: 0px;
  background-color: rgba(255,255,255,0.05);
}

.Education .DataTable .caption {
  text-align: center;
}
	
.Education .DataField {
  text-align: center;
  margin-top: 16px;
}

/*Styles Data Fields in the Signatures Data Section*/

.Signatures .DataField {
  display: grid;
  grid-template-columns: 250px auto;
}

.Signatures .Approval_Signature, 
.Signatures .Signature_Date {
  display: inline-grid;
}

Blur CSS Class: Protect PII & Protect Against Eye Strain


This is an example of a potentially beneficial CSS class we've called "blur".

What it does is simple. When assigned to a Data Section or Data Table's CSS Class property, it blurs everything except the Data Section or Data Table's caption if the user is not focused inside the section or table. Effectively, all fields will be blurred out except those in the section you're actively editing.

  • This could be used to protect PII or other sensitive data, only keeping it visible on the screen while the user is actively editing the sensitive data.
  • This could also be used to protect against eye strain. There's less noise for the user to focus on if only what they're actively editing is literally in focus.


The following CSS class would be added to your Data Model's Style Sheet text.

.blur:not(:focus-within) > *:not(.caption) {
  filter: blur(4px);
}


In the image here, we've added the blur class to each Data Section and Data Table in the Data Model.