Skip to contents

In this vignette, we’ll explore how to effectively style a quiz in Shiny using CSS. We’ll cover the basic structure of the quiz divs, illustrate with example CSS, and delve into specific aspects like the progress bar and div width adjustments.

Understanding the Div Structure

Before diving into CSS, it’s important to understand the DOM structure of the quiz. Here, we generate the quiz and its DOM structure using the quiz_ui() function.

quiz <- create_quiz(
  create_question(
    'What is the capital of Illinois?',
    add_choice('Chicago'),
    add_choice('Paw Paw'),
    add_choice('Spingfield', correct = TRUE)
  ),
  create_question(
    'Which elements are gases at room temperature? Select all that apply.',
    add_choice('Hydrogen', correct = TRUE),
    add_choice('Mercury'),
    add_choice('Nitrogen', correct = TRUE),
    label = 'Select Hydrogen and Nitrogen'
  ),
  create_question(
    'At what temperature does water boil at sea level?',
    add_slider(min = 90, max = 150, default_position = 120, correct = 100),
    label = 'Select 100'
  )
)

quiz_ui(quiz)

The main container quiz-container encapsulates the entire quiz UI. Inside, you’ll find various nested divs, each with a specific class or id that can be targeted with CSS for styling.

<div id="quiz-quiz-container" class="quiz-container">
  <div id="quiz-UI_quiz" class="shiny-html-output"></div>
</div>

The inner div is rendered by the Shiny server and will have a DOM structure of:

<div id="quiz-quiz-container" class="quiz-container">
  <div id="quiz-UI_quiz" class="shiny-html-output">
    <div class="progress">
      <div class="progress-bar" ...></div>
    </div>
    <div>
      <div class="quiz-header">...contents of quiz header...</div>
      <div class="quiz-prompt">
        <div>...contents of the quiz prompt...</div>
      </div>
    </div>
    <button id="quiz-submit_button" class='submit-button btn btn-default'>Submit</button>
    <button id="quiz-skip_button" class='skip-button btn btn-default'>Skip quiz</button>
  </div>
</div>

Note that the id’s will change if you provide a different namespace value to the quiz options. “quiz-” is the default prefix.


Basic CSS Styling

Let’s start with some basic styling to enhance the visual appeal of our quiz. We’ll add some background colors, padding, and shadows. If you’re new to CSS, the guides provided by Mozilla and w3 schools have excellent introductions. CSS is straightforward to learn and, in many cases, only a basic understanding is necessary to effectively style Shiny applications.

.quiz-container {
  background-color: #f7f7f7;
  padding: 20px;
  border-radius: 5px;
}

.quiz-header {
  margin-bottom: 15px;
}

.quiz-prompt {
  background-color: #fff;
  padding: 15px;
  border-radius: 4px;
  box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
}


Styling the Progress Bar

The progress bar is an important element as it provides visual feedback to the user. The fill color can be easily adjusted through set_quiz_options() but we can further style it to be more visually appealing and aligned with the quiz theme.

.progress-bar {
  height: 10px;
  border-radius: 5px;
}


Adjusting Div Width

Altering the width of the quiz container or its elements can significantly impact the layout. Below, we adjust the width of the quiz container to ensure the quiz is neither too cramped nor too stretched.

.quiz-container {
  max-width: 400px;
  margin: auto;
}


Interactive Elements

Style buttons, sliders, or choice selectors to make them more interactive and engaging.

.submit-button, .skip-button {
  background-color: #007bff;
  color: white;
  border: none;
  padding: 10px 20px;
  margin-top: 10px;
}

.submit-button:hover, .skip-button:hover {
  background-color: #0056b3;
}


Incorporating CSS into Your Quiz

Shiny supports a number of methods of incorporating CSS into the application. Inline CSS is the easiest but can become messy if you have many styles. For larger projects, using the file-based method and putting a .css file into the /www folder is recommended.

CSS is a powerful tool that can transform a basic quiz into a visually appealing and engaging experience. Experiment with different styles and adjustments to find what works best for your quiz.