0

I'm trying to attach a custom css stylesheet to style my shiny app. However I haven't had much success. I know that there is many ways to do it, but according to chapter 4 of Outstanding UI with Shiny (right after figure 4.3) the best way to do so seems to be with htmlDependency() and tagList().

I have created my dependency as shown below:

css_dependency <- function() {
  htmlDependency(
    name = "css dep",
    version = "1.0",
    src = "./www",
    stylesheet = "styles.css"
  )
}

However I am not sure how to attach it and where to attach it. With my browser developer tool, I can see that most dependencies seems to be in the <head> tag. Should I attach it like that?

tagList(head, css_dependency())

Also, I am not quite sure where I should call the tagList() function. Would that be directly in ui?

I can't seem to find many information on that method so any help would be appreciated. Thank you.

1 Answers1

0

I think htmlDependency() is designed to be use with package. It constructs path to the file using passed arguments, but I think it won't work if there is no package. I made some experiments and it looks like it locates library directory and constructs path using name, version etc. So it doesn't make sense (at least because version is included in the path) without package.

Let's now divide the answer if we have a package or not:

1. A package.

You are close, but I would:

css_dependency <- function() {
  htmlDependency(
    name = "css_dep",
    version = utils::packageVersion("name_of_your_package"),
    package = "name_of_your_package",
    src = "./www",
    stylesheet = "styles.css"
  )
}

Assuming styles.css file is inside www directory and www directory is inside inst directory (inst directory is use to install elements inside as is when package is installed by user), I have changed:

  • space from name - replaced by _ (just for safe);
  • hard-coded version number - now the version number will be the same as package version number (for convenience);
  • new argument added - package name;

And how to use it?

tagList() makes it possible to return (e.g. by a function) multiple tags - it is e.g. needed in modules, without tagList() the function would return only the last tag. The usage is:

library(shiny)

tagList(tags$h1("h1"), tags$h2("h2"))

And it returns:

<h1>h1</h1>
<h2>h2</h2>

i.e. both tags at once.

I'm talking about this, because your example (tagList(head, css_dependency())) is wrong, inside tagList() you need to use tags in the same way like in the UI part of app directly.

How to include dependency then? It will be just:

tags$head(css_dependency())

Because you are right that dependencies should be inside head tag. And there is no need to use tagList() directly in the UI part (use it if you need to return multiple tags by some function which will be used in the UI part)

2. Not a package.

We should use different approach than htmlDependency(). I would say:

tags$head(tags$link(rel = "stylesheet", type = "text/css", href = "path_to_the_file"))

"path_to_the_file" is:

  • relative to the directory where is a root of the application (i.e. where app.R or server.R and ui.R lives), so if you made a directory css/my_stylesheet.css, then it will be: tags$head(tags$link(rel = "stylesheet", type = "text/css", href = "css/my_stylesheet.css"));
  • however if you - the same as in your example - put your css file in www directory and www directory will be in the same directory where is a root of the application (i.e. not in some subdirectories), then you won't include www in path, because Shiny is designed to detect www directory automatically as a directory where will be css and js files., so in this case if my_stylesheet.css will be in www directory, the path will be: tags$head(tags$link(rel = "stylesheet", type = "text/css", href = "my_stylesheet.css"))
gss
  • 1,334
  • 6
  • 11