Position & Placement: Where to Put Your Feedback Buttons
Pick a corner, move the buttons off the edge, stack them in a column, mount them inside your page, and settle stacking fights with other fixed things.
The buttons sit 16 pixels in from the bottom-right corner of the window, in a row. position, offset and direction move and turn them; container mounts them inside an element of yours instead. zIndex (script attribute data-zindex) is 50 and sets the layer for both the buttons and the message box.
Five options decide where the buttons go. Everything else about their look is on the styling page, and every option is listed in one table.
| Option | Values | Default | Script attribute |
|---|---|---|---|
position |
"bottom-right", "bottom-left", "top-right", "top-left" |
"bottom-right" |
data-position |
offset |
{ x, y } in pixels |
{ x: 16, y: 16 } |
data-offset-x, data-offset-y |
direction |
"horizontal", "vertical" |
"horizontal" |
data-direction |
container |
CSS selector | none | data-container |
zIndex |
number | 50 |
data-zindex |
Move the buttons to another corner
<script
src="https://unpkg.com/@qaiddev/thumbs-embed/dist/embed.js"
defer
data-api-key="YOUR_PROJECT_KEY"
data-endpoint="https://qaid.dev/api/feedback"
data-position="bottom-left"
></script>
In JavaScript it is position: "bottom-left". The buttons stay fixed to the window as the page scrolls. The × that hides them sits first in the row, to the left of the thumbs, and shows when the pointer is over the row.
Bottom-right is where most chat launchers live. If yours does, bottom-left is usually free. Check the top corners against your header before you use them.
Move them off the edge
offset is the distance in pixels from the two edges nearest the corner. For bottom-right, x is from the right edge and y from the bottom.
new QaidFeedback({
endpoint: "https://qaid.dev/api/feedback",
apiKey: "YOUR_PROJECT_KEY",
position: "bottom-right",
offset: { x: 24, y: 88 },
});
A larger y lifts the buttons over a cookie bar, a bottom navigation bar or a chat launcher in the same corner. The buttons do not pad themselves for a phone’s home bar, so on a phone layout give y room for it too; see What changes on a phone.
Stack them in a column
direction: "vertical" (data-direction="vertical") turns the row into a column. The × moves to the top.
A column takes less width, which helps next to a sidebar or on a narrow screen.
Put them inside your page
container takes a CSS selector. The widget adds its buttons at the end of that element, in the normal flow of your page, where they scroll with the content.
<div class="article-footer">
<p>Was this page helpful?</p>
<div id="article-feedback"></div>
</div>
<script
src="https://unpkg.com/@qaiddev/thumbs-embed/dist/embed.js"
defer
data-api-key="YOUR_PROJECT_KEY"
data-endpoint="https://qaid.dev/api/feedback"
data-container="#article-feedback"
data-skip-targeting="true"
></script>
Inside a container:
positionandoffsethave no effect. Lay the row out with your own CSS on the element.- There is no ×, and a visitor’s earlier choice to hide the widget is ignored.
- The message box, the targeting marks and the markup editor still cover the whole window. They live in a second layer at the end of
<body>. - The element must exist when the widget starts. If the selector matches nothing, the buttons go to the corner instead.
skipTargeting fits here, since a “Was this helpful?” vote is about the page, not one element on it.
A client-side router that re-renders the container takes the buttons with it, or they turn up at the bottom of the page. On those pages, destroy the widget before the change and create a new one after it; see Conditional display.
Settle stacking fights
zIndex (data-zindex, with no hyphen in the middle) is the stacking level of both of the widget’s layers: the buttons, and the layer that holds the targeting marks, the message box and the markup editor. It is 50 by default.
<script
src="https://unpkg.com/@qaiddev/thumbs-embed/dist/embed.js"
defer
data-api-key="YOUR_PROJECT_KEY"
data-endpoint="https://qaid.dev/api/feedback"
data-zindex="1000"
></script>
| What happens | What to do |
|---|---|
| A sticky header covers the message box when it opens near the top | Raise zIndex above the header’s |
| A chat launcher or cookie bar covers the buttons | Move the buttons to another corner, or raise offset.y past it |
| The buttons float over your own dialogs | Keep zIndex below your dialogs, which is where 50 usually puts it |
In a container, the buttons stack with the container, so zIndex only moves the covering layer.
Share a corner with a chat widget
Move the buttons to a free corner if there is one. If both must share, give the one on top enough offset.y to clear the other.
incognito does not free the space. The buttons turn invisible until the pointer reaches them, but they still sit there and still catch clicks meant for whatever is under them. To keep the widget off a page altogether, don’t start it there; see Conditional display.
Choose options by window width
The options are read once, when the widget starts, and nothing moves when the window is resized. Check the width first:
const narrow = window.matchMedia("(max-width: 640px)").matches;
new QaidFeedback({
endpoint: "https://qaid.dev/api/feedback",
apiKey: "YOUR_PROJECT_KEY",
position: narrow ? "top-right" : "bottom-right",
direction: narrow ? "vertical" : "horizontal",
});
The buttons do not shrink on a phone. The message box does change: under 640 pixels wide it opens as a sheet along the bottom. What changes on a phone has the rest.