The Opinion Stage CSS override feature was introduced to let you do advanced customizations to your widgets in a stable way.

CSS Override mechanism is inspired by BEM methodology, so understanding it will help in understanding of CSS Override approach. Basically each customize-able HTML element has general (or wrapping) CSS class (e.g. block), own CSS class (e.g. element) and modifiers CSS classes, acting as additional classes for better fine tuning. 

In order to successfully use CSS Override, one should namespace each CSS Override class with #css-api ID attribute (it exists for technical reasons, see CSS Specificity for more details).


Generally what can be done is constrained only by imagination, but there are few things which we do not recommend to abuse:

  • please do not specify tag names in CSS override (tag names could change with future releases)
  • do not over-change geometry of the widget, it is fine to tune some paddings and/or margins, but be warned, we can't guarantee 100% compatibility with future releases, especially when CSS Override is relying too much on existing markup specifics or quirks

Widget body

widget body is a html tag containing all parts of a widget, excluding logo and OpinionStage branding:

HTML markup:

<div id="css-api">
  <div class="css-api-widget-body">
    ... widget contents here ...
  </div>
</div>

CSS classes:

#css-api .css-api-widget-body - widget body

Answers area

this is where "answers" located:
regular layout:

images layout:

HTML markup:
regular (no image) answers layout:

<div class="css-api-widget-option">
  <div class="css-api-widget-option__selection_mark"></div>
  <div class="css-api-widget-option__label">choice #1</div>
</div>

images answers layout:

<div class="css-api-widget-option>
  <img class="css-api-widget-option__image" alt="image alt" src="https://image.com/pic.png">
  <div class="css-api-widget-option__label">choice #1</div>
</div>

CSS classes:
#css-api .css-api-widget-option - whole option area
#css-api .css-api-widget-option__label - text wrapper
#css-api .css-api-widget-option__selection_mark - for regular poll layout, mark showing selected answer (shows up on hover, constantly displayed when user voted)
#css-api .css-api-widget-option__image - for image layout answers, image wrapper

Widget header (title/description)

HMTL markup:

<section class="css-api-card-header">
  <h1 class="css-api-card-header__title">widget title</h1>
  <p class="css-api-card-header__description">widget description</p>
</section>

CSS classes:
#css-api .css-api-card-header - wrapper class
#css-api .css-api-card-header__title - header itself
#css-api .css-api-card-header__description - optional description

Media area (cover image, video)

HTML markup:

<div class="css-api-widget-media">
  <img class="css-api-widget-media__image" alt="image alt" src="https://image.com/pic.png">
  <div class="css-api-widget-media__image_credit">image credit</div></div>

<div class="css-api-widget-media">
  <div class="css-api-widget-media__video">
    ... youtube embedded video iframe...  
  </div>
</div>

CSS classes:
#css-api .css-api-widget-media - wrapping tag
#css-api .css-api-widget-media__image - image tag
#css-api .css-api-widget-media__image_credit - image credit tag
#css-api .css-api-widget-media__video - video iframe wrapper tag

Inputs

Each widget may have an input field (for instance answer options allowing users defined answers), which is also possible to style with CSS. Each input have same HTML structure. Inputs for widget and inputs for lead forms are separate inputs, despite share similar HTML structure and CSS classes (the only difference is the CSS classes naming are different)

Inputs (widget)

HTML markup:

<div class="css-api-widget-field">
  <input type="text" id="inpt1" class="css-api-widget__input css-api-widget__input--text">
  <div class="css-api-widget-field__err-msg">error message</div>
</div>

CSS classes:

#css-api .css-api-widget-field - class-wrapper
#css-api .css-api-widget-field__input - common input class
#css-api .css-api-widget-field__err-msg - error message class (element appears when user enters invalid data and/or format)
#css-api .css-api-widget-field__input--email - modifier for email-type fields
#css-api .css-api-widget-field__input--text - modifier for text-type fields
#css-api .css-api-widget-field__input--textarea - modifier for textare-type fields

Inputs (lead form)

HTML markup:

<div class="css-api-lead-form-field">
  <span class="css-api-lead-form-field__required-marker">*</span>
  <label class="css-api-lead-form-field__label" for="inpt1">Please enter your name</label>
  <input type="text" id="inpt1" class="css-api-lead-form-field__input css-api-lead-form-field__input--text">
  <div class="css-api-lead-form-field__hint">input hint</div>
  <div class="css-api-lead-form-field__err-msg">error message</div>
</div>

CSS classes:
#css-api .css-api-lead-form-field - class-wrapper

#css-api .css-api-lead-form-field__label - class for <label> tag
#css-api .css-api-lead-form-field__required-marker - class for marker element, signalling optional/required aspect of the input
#css-api .css-api-lead-form-field__hint - class for hind under the input
#css-api .css-api-lead-form-field__err-msg - error message class
#css-api .css-api-lead-form-field__input - <input> tag class
corresponding modifiers:
#css-api .css-api-lead-form-field__input--text
#css-api .css-api-lead-form-field__input--email
#css-api .css-api-lead-form-field__input--textarea
#css-api .css-api-lead-form-field__input--checkbox
#css-api .css-api-lead-form-field__input--dropdown

Buttons

Some widgets have explicit buttons controls, which is also possible to style with CSS

HMTL markup:

<button class="css-api-widget-btn css-api-widget-btn--submit">Vote</button>

CSS classes:
#css-api .css-api-widget-btn - button class, shared across all buttons
#css-api .css-api-widget-btn--start - start button modifier (appears on widgets' cover cards, e.g. trivia quiz, personality quiz)
#css-api .css-api-widget-btn--submit - submit button modifier (e.g. vote button in polls, submit button in quizzes, surveys, for card which allow user-defined answer submit)
#css-api .css-api-widget-btn--call2action - call-to-action buttons (usually appears on final card of widgets)

Miscellaneous

Message after option selection

HTML markup:

<div class="css-api-widget-info-msg">
  <div class="css-api-widget-info-msg__text">
    Thank you for voting!  
  </div>
  <button class="css-api-widget-info-msg__btn">Proceed to next question</button>
</div>

CSS classes:
#css-api .css-api-widget-info-msg - whole area class
#css-api .css-api-widget-info-msg__text - text class
#css-api .css-api-widget-info-msg__btn - button class (may not present in certain situations, for instance in polls)

Navigation bar

Navigation bar it the area containing different controls for widget navigation (applicable for surveys and quizzes, if turned on)

HTML markup:

<div class="css-api-widget-navbar">
  ... navbar content here
</div>

CSS classes:
#css-api .css-api-widget-navbar - navbar tag

Widget pager

pager controls including: buttons for next/previous widget card navigation, and card number

HTML markup:

<div class="css-api-widget-pager">
  <button class="css-api-widget-pager__btn css-api-widget-pager__btn--back"></button>
  <div class="css-api-widget-pager__page">1/1</div>
  <button class="css-api-widget-pager__btn css-api-widget-pager__btn--forward"></button>
</div>

CSS classes:
#css-api .css-api-widget-pager - wrapping class
#css-api .css-api-widget-pager__page - page indicator class
#css-api .css-api-widget-pager__btn - class for both (back/previous page) buttons

classes for specific buttons:
#css-api .css-api-widget-pager__btn--forward
#css-api .css-api-widget-pager__btn--backward
#css-api .css-api-widget-pager__btn--restart

Timer

Quizzes have timer option, which is timer, displaying to user how long time was spent on answering quiz
HTML markup:

<div class="css-api-widget-timer">0:11</div>

CSS classes:
#css-api .css-api-widget-timer - timer tag

Did this answer your question?