Docs

Everything You Need to Know

Components

Styles

Since version 4.1.0, you can style your component with a style object. Most of the time you probably won't need anything more than a tiny snippet of CSS in your document. However, if you want to override the default styles for some serious customization, using the component's styles object is the way to go. Similarly, if you are creating a totally new layout for a component, you can use the styles object to provide the component's styles. When you define your component with a styles property, ChocolateChip-UI creates a virtual stylesheet with a selector based on the component's element selector. Any child elements will be styled as descendants of that selector.

When you have a highly customized or specialized layout for a component, it makes sense to include styles in the component itself. The advantage to this is that if you intended to reuse the component in other projects, the styles will accompany the component automatically. No need to dig around for styles in other places.

To add a style to a component, you use the styles property and assign it an object of styles. Note: Because this is object notation, CSS definitions do not end with a semi-colon but with a comma. Putting a semi-colon after your CSS value will throw an error.

const myComponent = new Component({
  element: '#list1',
  render: (data) => html`
    <li> 
      <h3>${ data.name }</h3>
    </li>`,
  styles: {
    // your styles here
  } 
});

ChUI Style Notation

ChocolateChip-UI uses a special object notation to define the styles for a component. Because it is an object, hyphenated CSS properties must be either quoted or changed to camel case.

The syntax uses hierarchical relationships, like SASS and LESS. You indicate child elements based on the component's element. Let's look at a style example:

const myComponent = new Component({
  element: '#list1',
  render: (person) => html`
    <li> 
      <h3>${ person.name }</h3>
    </li>`,
  styles: {
    // Add border to list:
    border: 'solid 1px red'
  } 
});

In the above example, ChocolateChip-UI will create the following style definition:

#list {
  border: solid 1px red;
}

Child Selectors

In the above example, the style border: 'solid 1px red' will get applied to the CSS selector #list1, because that is the root of the component. If we want to style the list items, we will need to use a CSS child selector and nest it inside the list definition. Remember that when providing style selectors, they need to be quoted, and that they are style with their own object of properties and values:

const myComponent = new Component({
  element: '#list1',
  render: (person) => html`
    <li> 
      <h3>${ person.name }</h3>
    </li>`,
  styles: {
    // Add border to list:
    border: 'solid 1px red',
    // Add child selector for list items:
    li: {
      backgroundColor: 'red',
      color: '#fff'
    }
  } 
});

The above component style object will result in the following stylesheet definition:

#list {
  border: solid 1px red;
}
#list li {
  background-color: red;
  color: #fff;
}

In the above example, the list background color will be red. However, since the text is inside of an H3, the color value will not affect them, instead we will need to add their styles as child elements of the list item. We do this by adding another child selector nested in the list item property definition:

const myComponent = new Component({
  element: '#list1',
  render: (person) => html`
    <li> 
      <h3>${ person.name }</h3>
    </li>`,
  styles: {
    // Add border to list:
    border: 'solid 1px red',
    // Add child selector for list items:
    li: {
      'background-color': 'red',
      h3: {
        color: '#fff'
      }
    }
  } 
});

The above component style object will result in the following stylesheet definition:

#list {
  border: solid 1px red;
}
#list li {
  background-color: red;
  color: #fff;
}
#list li h3 {
  color: #fff;
}

Pseudo Elements

You can define pseudo selectors using the ":" or "::" directly on a selector's root level:

const myComponent = new Component({
  element: '#list1',
  render: (person) => html`
    <li> 
      <h3>${ person.name }</h3>
    </li>`,
  styles: {
    // Add child selector for list items:
    li: {
      backgroundColor: 'red',
      // Add a pseudo element:
      '::after': {
        content: 'This is a pseudo element!',
        display: 'block',
        position: 'relative',
        top: '100%'
      }
      // Add a hover state to list item:
      ':hover': {
        'background-color': 'red'
        // color for h3 with hover:
        '> h3': {
          color: '#fff'
        }
      }
    }
  } 
});

The above style object will result in the following stylesheet definition:

#list li::after {
  content: 'This is a pseudo element!';
  display: block;
  position: relative;
  top: 100%;
}
#list li:hover {
  background-color: red;
}
#list li:hover > h3 {
  color: #fff;
}

Automatic Pixel Values

If you're defining a simple numeric pixel value, you can simply provide the value as a number:

const myComponent = new Component({
  element: '#list1',
  render: (person) => html`
    <li> 
      <h3>${ person.name }</h3>
    </li>`,
  styles: {
    // Give list margin of 20px on all sides:
    margin: 10,
    // Give list a width of 200px:
    width: 200
  } 
});

If you need to provide different values for compound values, you'll need to provide the pixel length and quote the value:

const myComponent = new Component({
  element: '#list1',
  render: (person) => html`
    <li> 
      <h3>${ person.name }</h3>
    </li>`,
  styles: {
    // Give list margin of  5px 20px:
    margin: '5px 20px'
  } 
});

Similarly, if you want a value other than pixels, you'll need to provide the desired length identifier and quote the value:

const myComponent = new Component({
  element: '#list1',
  render: (person) => html`
    <li> 
      <h3>${ person.name }</h3>
    </li>`,
  styles: {
    // Give list margin of  1em:
    margin: '1em'
  } 
});

And here are two examples of styled components:

See the Pen Styled Component V5 by Robert Biggs (@rbiggs) on CodePen.