> For the complete documentation index, see [llms.txt](https://callum-hart.gitbook.io/immutable-styles/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://callum-hart.gitbook.io/immutable-styles/recipies/sharingstyles.md).

# Sharing Styles

Immutable styles provides a couple of ways to share common styles among similar rulesets:

1. [Immutable Mixins](/immutable-styles/advancedconcepts/immutablemixins.md)
2. [Detached Rulesets](/immutable-styles/itsjustjavascript.md#detached-rulesets)

Mixins are used to share styles among rulesets with the *same* element type. Whilst detached rulesets are used to share styles among rulesets with *different* element types.

This guide will feature an example of using each approach.

## Sharing Styles with Immutable Mixins

For mixins we will extend the button example first introduced in [The Basics](/immutable-styles/thebasics.md) guide. The designer has returned to the style-guide and added a few different button variations. Additionally each variation now has four UI states: a default, hover, focussed, and disabled state.

Here is our fictitious style-guide:

![](/files/-LSa_TDU0oCsgqELH3cd)

From the style-guide above we can identify common styles shared among all buttons:

* `padding`
* `border-width`
* `border-style`
* `border-radius`
* `font-size`
* `font-family`
* `cursor`

In contrast we can also identify styles unique to each button type:

* `background`
* `border-color`
* `color`

The common styles for the default state can be put into a mixin:

```jsx
/** @jsx createStyle */
import { createStyle, createMixin } from 'immutable-styles';

const button = {
  default: createMixin(
    <button>
      padding: 10px 30px;
      border-width: 1px;
      border-style: solid;
      border-radius: 4px;
      font-size: 1rem;
      font-family: 'Open Sans', sans-serif;
      cursor: pointer;
    </button>
  )
};
```

Each button variation can use the `button.default` mixin to apply the common styles shared among all buttons, and then apply its own styles unique to the button type:

```jsx
/** @jsx createStyle */
import { createStyle, createMixin } from 'immutable-styles';

const button = {
  /* ... */
};

export default [
  <button.default className="btn-primary">
    background: #4A96F8;
    border-color: #3B7AC9;
    color: #FFFFFF;
  </button.default>,

  <button.default className="btn-secondary">
    background: #D5DFEB;
    border-color: #BFCDDD;
    color: #3D4247;
  </button.default>,

  <button.default className="btn-brand">
    background: #F2C07C;
    border-color: #DFAD70;
    color: #44321B;
  </button.default>
];
```

The same approach can be applied to the different UI states. Common styles for each UI state can be assigned to its own mixin:

```jsx
/** @jsx createStyle */
import { createStyle, createMixin } from 'immutable-styles';

const button = {
  default: createMixin(
    /* ... */
  ),
  hover: createStyle(
    <button pseudo=":hover">
      cursor: pointer;
    </button>
  ),
  focus: createMixin(
    <button pseudo=":focus">
      outline: none;
      box-shadow: 0 0 0 3px #A8CBF5;
    </button>
  ),
  disabled: createMixin(
    <button pseudo=":disabled">
      opacity: 0.6;
      pointer-events: none;
    </button>
  )
};

export default [
  // Primary Button

  <button.default className="btn-primary">
    {/* ... */}
  </button.default>,
  <button.hover className="btn-primary">
    background: #3B7AC9;
  </button.hover>,
  <button.focus className="btn-primary" />,
  <button.disabled className="btn-primary" />,

  // Secondary Button

  <button.default className="btn-secondary">
    {/* ... */}
  </button.default>,
  <button.hover className="btn-secondary">
    background: #BFCDDD;
  </button.hover>,
  <button.focus className="btn-secondary" />,
  <button.disabled className="btn-secondary" />,

  // Brand Button

  <button.default className="btn-brand">
    {/* ... */}
  </button.default>,
  <button.hover className="btn-brand">
    background: #DFAD70;
  </button.hover>,
  <button.focus className="btn-brand" />,
  <button.disabled className="btn-brand" />
];
```

## Sharing Styles with Detached Rulesets

Detached rulesets allow groups of styles to be shared across different rulesets. For example:

```jsx
/** @jsx createStyle */
import { createStyle } from 'immutable-styles';

const fontSmall = `
  font-family: 'Open Sans', sans-serif;
  font-size: 0.75rem;
  line-height: 1.5rem;
`;

const fontMedium = `
  font-family: 'Open Sans', sans-serif;
  font-size: 1rem;
  line-height: 2rem;
`;

const fontLarge = `
  font-family: 'Open Sans', sans-serif;
  font-size: 1.5rem;
  line-height: 3rem;
`;

const fontExtraLarge = `
  font-family: 'Open Sans', sans-serif;
  font-size: 2rem;
  line-height: 4rem;
`;

// usage:

export default [
  <h1>
    { fontExtraLarge }
  </h1>,
  <h2>
    { fontLarge }
  </h2>,
  <h3>
    { fontMedium }
  </h3>,
  <th>
    { fontMedium }
  </th>,
  <td>
    { fontSmall }
  </td>,
  <p>
    { fontSmall }
  </p>,
  <strong>
    { fontSmall }
  </strong>
];
```

## Grouped CSS Selectors

Detached rulesets offer an alternative to grouped CSS selectors. In the [Typed Selectors](/immutable-styles/advancedconcepts/typedselectors.md) guide the `btn` class could be used by elements of types `a` and `button`:

```css
a.btn,
button.btn {
  font-family: 'Open Sans', sans-serif;
  font-size: 14px;
  background: cadetblue;
  color: ivory;
}

a.btn {
  text-decoration: none;
}

button.btn {
  border: none;
  cursor: pointer;
}
```

The equivalent rulesets in immutable styles would be:

```jsx
const btnStyles = `
  padding: 8px 12px;
  font-family: 'Open Sans', sans-serif;
  font-size: 14px;
  background: cadetblue;
  color: ivory;
`;

export default [
  <a className="btn">
    { btnStyles }
    text-decoration: none;
  </a>,

  <button className="btn">
    { btnStyles }
    border: none;
    cursor: pointer;
  </button>
];
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://callum-hart.gitbook.io/immutable-styles/recipies/sharingstyles.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
