# import a cell requiring CSS

**URL:** <https://talk.observablehq.com/t/import-a-cell-requiring-css/4890>\
**Category:** Help\
**Created:** [April 7, 2021, 6:12pm UTC](https://talk.observablehq.com/t/import-a-cell-requiring-css/4890 "2021-04-07T18:12:04Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![easz](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/easz/32/4446_2.png) [@easz](https://talk.observablehq.com/u/easz)\
**Post date:** [April 7, 2021, 6:12pm UTC](https://talk.observablehq.com/t/import-a-cell-requiring-css/4890/1 "2021-04-07T18:12:04Z")

</div>

I would like to import a cell, for example a chart, from another notebook without explicitly requiring its dependent stylesheet again.

Here is the example:

I have a `chart` defined in the notebook. The `chart` depends on 3rd party libs and styles.

> **[🤔 How to: use libraries that need CSS / Cas Perl / Observable](https://observablehq.com/@easz/how-to-use-libraries-that-need-css)**
>
> Explore and visualize data. Share and publish your insights. Discover and be inspired.

and I import the `chart` in the other notebook

> **[Import a cell requiring CSS](https://observablehq.com/@easz/import-a-cell-requiring-css)**

First of all, it is not intuitive to me. Why the 3rd party lib is implicitly imported with the `chart` but not the stylesheet?

it is not rendered correctly unless I explicitly import and evaluate the `stylesheet` from the source notebook.

If I write something like this in the source notebook. It will still not work. The `html` function does not put the `<link>` into current document as I expect.

```
Chartist = {
  let stylesheet = html`<link rel='stylesheet';
  href='https://unpkg.com/chartist@0.11.0/dist/chartist.min.css' />`;
  return await require('chartist');
}

```

This will work as I expect, but it is pretty tedious…

```
Chartist = {
  var link = document.createElement("link");
  link.type = "text/css";
  link.rel = "stylesheet";
  link.href = 'https://unpkg.com/chartist@0.11.0/dist/chartist.min.css';
  document.getElementsByTagName("head")[0].appendChild(link);
  return await require('chartist');
}

```

looking for advice. Thanks 😛

---

<div class="post-metadata">

**Author:** ![tophtucker](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/tophtucker/32/4781_2.png) [@tophtucker](https://talk.observablehq.com/u/tophtucker)\
**Post date:** [April 8, 2021, 1:59am UTC](https://talk.observablehq.com/t/import-a-cell-requiring-css/4890/2 "2021-04-08T01:59:32Z")

</div>

You are totally right that the relationship between CSS and imports (and embeds) is confusing! It trips up a ton of people. I can try to help explain it, but I think in the long run we need a better way of presenting this in the product itself — we can’t expect everyone to come to the forum. : )

The `html` function creates a DOM node; it doesn’t insert it into the document. When a cell _returns_ a DOM node, the node is inserted into the document. When you have a one-line cell like:

```js
stylesheet = html`<link rel='stylesheet'
  href='https://unpkg.com/chartist@0.11.0/dist/chartist.min.css' />`

```

The DOM node is the return value, so it’s inserted into the body and the CSS properly takes effect.

In your " 🤔 How to: use libraries that need CSS" notebook, you can add one line to the definition of `chart`, like in [this suggestion](https://observablehq.com/compare/1dba7c71111d04f5@127...860409486ae976c3@128):

```js
container.appendChild(stylesheet);

```

If you didn’t want the separate `stylesheet` cell, you could also use the `html` function inline, like this:

```js
container.appendChild(html`<link rel='stylesheet'
  href='https://unpkg.com/chartist@0.11.0/dist/chartist.min.css' />`);

```

It ain’t perfect, but hopefully a little easier than all the separate statements for creating the element and setting its attributes and appending it!

> Why the 3rd party lib is implicitly imported with the `chart` but not the stylesheet?

You have a cell `Chartist`, which is like a global reactive variable, and then in the `chart` cell you reference it: `new Chartist.Line(…`. Observable tracks references to other cells, so it knows that it has to import `Chartist` in the background when you import `chart` to another notebook.

But Observable can’t parse or track what CSS applies to what. It’s rife with side effects, so it can get messy fast. I think it’s conceivable that maybe one day we could detect when an imported DOM element is affected by CSS somewhere else in the original notebook, but it might be hard or impossible to do that correctly and reliably. So, for now, we can’t automatically import the CSS you need. Which is why I typically have CSS in a named cell and then explicitly reference that named cell in any cell that needs it — like we did above.

---

<div class="post-metadata">

**Author:** ![jrus](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/jrus/32/586_2.png) [@jrus](https://talk.observablehq.com/u/jrus)\
**Post date:** [April 8, 2021, 7:52pm UTC](https://talk.observablehq.com/t/import-a-cell-requiring-css/4890/3 "2021-04-08T19:52:38Z")

</div>

You can also use shadow DOM if you want to apply CSS to just one cell and not the whole notebook. See:

> **[Hello, shadow DOM](https://observablehq.com/@fil/hello-shadow-dom)**
>
> When you want to isolate a component and make sure it doesn't get affected by outside CSS or its CSS don't affect outside elements, use the shadow DOM. (Can I use it? Yes.) Note that the root element is exposed in the DOM. If it has classes that...
