What is the safest no-plugin method?
Put a small function in an active child theme's functions.php file and attach it to WordPress's wp_footer action. This keeps the customization out of the parent theme and avoids copying an entire footer template just to add one link.
Do not use this route if you are uncomfortable recovering from a PHP error. Use a snippet manager or ask the person maintaining the site. “No plugin” is not automatically safer when dashboard editing is the only workflow the team understands.
Choose the method by maintenance needs
| Method | Best for | Main tradeoff |
|---|---|---|
| Child theme + wp_footer hook | Developer-maintained sites | Requires safe PHP editing and a child theme |
| Snippet manager | Dashboard-managed sites | Adds one general-purpose plugin |
| Dedicated floating-button plugin | Rules, analytics, multiple actions | More runtime and configuration |
| Parent footer.php edit | Nothing | Theme updates can overwrite it; template copies can drift |
Why use a child theme?
WordPress recommends placing custom code in a child theme rather than changing the parent theme directly. Parent updates can replace edited files. A child theme's functions.php loads alongside the parent theme's file, so you can add behavior without copying the parent's functions.
Before editing, confirm that the child theme is active, take a backup, and use staging if the site is commercially important. A syntax error in functions.php can break the front end until the file is corrected.
What code should you add?
Replace the URL and label, then add this to the child theme's functions.php. The function prints one link and its CSS near the closing body tag through wp_footer. The unique function name reduces the chance of colliding with theme or plugin code.
<?php
add_action( 'wp_footer', 'cta_generator_render_floating_button' );
function cta_generator_render_floating_button() {
?>
<a class="site-floating-cta" href="https://example.com/book">Book a Call</a>
<style>
.site-floating-cta {
position: fixed;
right: 24px;
bottom: 24px;
z-index: 1000;
display: inline-flex;
min-height: 48px;
align-items: center;
padding: 0 22px;
border-radius: 999px;
background: #166534;
color: #fff;
font: 700 16px/1.2 system-ui, sans-serif;
text-decoration: none;
box-shadow: 0 10px 28px rgb(0 0 0 / 20%);
transition: transform 160ms ease;
}
.site-floating-cta:hover { transform: translateY(-2px); }
.site-floating-cta:focus-visible { outline: 3px solid #facc15; outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
.site-floating-cta { transition: none; }
.site-floating-cta:hover { transform: none; }
}
</style>
<?php
}Why does the wp_footer hook work?
The official WordPress reference says the wp_footer action runs near the closing body tag when the theme calls wp_footer(). That makes it a practical place for small front-end output without editing the footer template itself.
The hook is theme-dependent, although well-supported. If the button does not appear, first confirm that the theme includes wp_footer rather than moving the code randomly into another template.
Does this work with block themes?
The functions.php file is available to classic themes, block themes, and child themes. The hook approach therefore avoids relying on a traditional footer.php file, which a block theme may not use in the familiar way.
The real requirement is that the active theme calls the footer hook. Most production themes do because plugins depend on it, but custom themes can omit it.
When is a snippet manager better?
Use a snippet manager when the site owner needs to enable, disable, or edit the CTA from the dashboard and does not maintain theme files. A general snippet tool is still a plugin, but it is a more honest operational choice than pretending that occasional PHP edits are maintenance-free.
Use a dedicated floating-button plugin only when you need its actual features: page rules, schedules, analytics, multiple actions, or a visual editor that remains connected after launch.
How should you test the WordPress button?
Test before clearing the task:
- Open the homepage, posts, pages, archives, and any shop or checkout templates.
- Confirm the destination URL and keyboard focus state.
- Test mobile widths with the cookie banner and admin bar visible.
- Enable reduced motion and confirm the hover movement disappears.
- Clear page, plugin, CDN, and browser caches if the old markup remains.
- Update the parent theme on staging and confirm the child-theme code survives.
To remove the button, delete the action and function together. Do not leave an unused callback or an orphaned style block behind.
Ready to build your button?
Design it visually, export clean code, and paste it into your site.
Open the GeneratorFrequently Asked Questions
Is editing WordPress theme files safe?
It is manageable in a child theme with a backup and recovery access. Editing a parent theme directly is fragile because updates can overwrite the change.
What if my theme has no footer.php?
Use the wp_footer hook from the child theme's functions.php. The method does not require you to locate or copy a traditional footer template.
Will caching stop the floating button from working?
Caching should not break the button, but it can keep an older page version visible. Purge relevant WordPress, server, CDN, and browser caches after changing the snippet.
Sources and contextual notes
- CSS positioning: MDN reference used to distinguish fixed positioning from sticky positioning.
- WCAG 2.2 target size minimum: W3C guidance used for the 24 by 24 CSS pixel Level AA minimum and its exceptions.
- WCAG contrast minimum: W3C guidance used for the 4.5:1 normal-text and 3:1 large-text contrast requirements.
- prefers-reduced-motion: MDN reference used for respecting a visitor's reduced-motion preference.
- WordPress child themes: Official Theme Handbook guidance used for update-safe customization and child-theme functions.php behavior.
- WordPress wp_footer hook: Official hook reference used for output placement and the theme-dependency caveat.
- WordPress theme functions: Official Theme Handbook guidance used for hooks and functions.php context.