Opinion Stage supports a feature that lets you perform advanced design customization using the CSS language. In this article, you can find instructions on how to use CSS within Opinion Stage:
Enabling The Feature
The CSS settings feature can be found in the item creation form: Design > Edit/Duplicate Theme > CSS Override. After creating your CSS, copy it to the text box and click save.
Setup Options
It's possible to either write your CSS directly into the "CSS Overwrite" input box, or embed an external CSS file with the following CSS @import statement:
@import url('https://mysite.com/opinionstage-widgets.css');
Please note: Opinion Stage widgets work only with "https" please make sure the url is https-accessible.
Please note: the CSS code you add should be based on the #css-api classes only, any other classes you use may not be supported in the future.
If you are already familiar with this feature and want full details, please go to the CSS Override reference.
Otherwise, if you are new to the feature, we recommend starting by viewing the usage examples below.
Usage Examples
Let's create a simple poll like this:
Let's say we want to remove the border, set the font to be the infamous Comic Sans, and then set some cool background color. This is how it can be done with CSS override:
#css-api .css-api-widget-body {
font-family: "Comic Sans MS", cursive, sans-serif;
border: none;
background-color: #ccceff;
}
Here is the result:
Now let's change the title and options text color to a different one (by appending the following code into the CSS overwrite box):
#css-api .css-api-card-header__title, .css-api-widget-option__label {
color: #2519ce;
}
Now it should look like this:
And finally, let's change the options color:
#css-api .css-api-widget-option {
background-color: #fbf3f32e;
}
#css-api .css-api-widget-option__selection_mark {
background-color: #f9f218;
}
Following are some more popular css override examples:
Change title and text color on widgets cover:
#css-api .css-api-card-header__title { color: yellow; }
#css-api .css-api-card-header__description { color: yellow; }
Change the background and text color of the button on the widgets cover:
#css-api css-api-widget-btn--start {
color: red;
background-color: blue;
}
Change call to action button color:
#css-api .css-api-widget-btn--call2action {
color: yellow;
background: red;
}
Change the background and text color of the widget's option:
#css-api .css-api-widget-option { background-color: white; }
#css-api .css-api-widget-option__label { color: black; }
Change the background and text color of the widget's option, when the user hovers the mouse over it:
#css-api .css-api-widget-option:hover { background-color: black !important; }
#css-api .css-api-widget-option:hover .css-api-widget-option__label { color: white; }
Change the background and text color of the widget's option, which is already selected by user:
#css-api .selected .css-api-widget-option { background-color: blue; }
#css-api .selected .css-api-widget-option .css-api-widget-option__label { color: yellow; }
Change the background and text color of the widget's option, which is already selected by the user (user hovers mouse over it):
#css-api .selected .css-api-widget-option:hover { background-color: green; }
#css-api .selected .css-api-widget-option:hover .css-api-widget-option__label { color: red; }
There are many more things you can do with the CSS override feature, for a full-featured example see the CSS overwrite demo file: https://www.opinionstage.com/css-api-example.css.
For advanced users, there is a sass source of the demo file: https://www.opinionstage.com/css-api-example.css.scss
Customizing Item Parts
CSS Override mechanism is inspired by BEM methodology, so understanding it will help understand the CSS Override approach. Basically each customizable 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
Fonts
Want to change the 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 urls 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 sharing similar HTML structure and CSS classes (the only difference is the CSS classes names 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 */
}
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 in 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 the quiz.
HTML markup:
<div class="css-api-widget-timer">0:11</div>
CSS classes:
#css-api .css-api-widget-timer - timer tag