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 understand the 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. 

To successfully use CSS Override, one should namespace each CSS Override class with the #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 the 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 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

Example:

Let's see how to make the title more compact:

#css-api .css-api-card-header__title {
font-size: 17px; /* sets font size, making it smaller */
line-height: 1; /* this value is related to spacing between line */
padding: 12px 0; /* sets top & bottom paddings to 12px, while removing left & right padding, by setting them to zero */
}

Widget body

widget body is an 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

Examples:

Change font for a widget from default to a custom one.

As a first step, please make sure you have downloaded web-enabled font file formats: .eot, .woff (or .woff2), .ttf and .svg. Not all of the font types are mandatory: it depends on browser support needed, for most cases .woff/woff2 or .ttf would work. Please consult the font website for information on which file formats they support.

Font files should be uploaded to a server, allowing to serve font file(s) publicly, for this example we will be using "https://my.font-hosting.co/my-font.ttf" as an example. Enabling font with CSS override is done by specifying the following "@font-face" CSS rule (please note different url for different font file types, absent file types can be omitted):

@font-face {
font-family: 'MyCustomWebFont';
src: url('https://my.font-hosting.co/my-font.eot');
src: url('https://my.font-hosting.co/my-font.eot?#iefix') format('embedded-opentype'),
url('https://my.font-hosting.co/my-font.woff2') format('woff2'),
url('https://my.font-hosting.co/my-font.woff') format('woff'),
url('https://my.font-hosting.co/my-font.ttf') format('truetype'),
url('https://my.font-hosting.co/my-font.svg#svgFontName') format('svg');
}

and in order to use the font in a widget:

#css-api .css-api-widget-body {
font-family: 'MyCustomWebFont', "Open Sans", OpenSans, Helvetica, sans-serif;
}

For more detailed information about adding fonts consider reading this article about @font-face

Change default widget background color

#css-api .css-api-widget-body {
background-color: #000;
}

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

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

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 has the 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)

Example:

If we want to make the buttons smaller:

#css-api .css-api-widget-btn {
padding: 7px; /* makes internal margin between text and button borders of specified size */
font-size: 16px; /* makes font size smaller */
}

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 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 include: 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 a timer option, which is a timer, displaying to a 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?