Un placeholder classique comme "Rechercher..." reste figé et n'inspire pas vraiment l'utilisateur. Comment suggérer de manière dynamique ce qu'il est possible de chercher ? Comment créer cette sensation de site "vivant" sans pour autant gêner l'expérience utilisateur ?
La réponse : une animation typewriter intelligente qui cycle entre différents termes de recherche, s'adapte aux interactions utilisateur et reste performante.
Pour créer une animation placeholder vraiment efficace, nous devons aller au-delà du simple effet visuel. L'objectif est de développer un système intelligent qui comprend le contexte utilisateur, s'adapte aux interactions en temps réel, et maintient des performances optimales même sur des appareils moins puissants.
Notre approche technique s'articule autour de trois fondements essentiels :
Effet de frappe et d'effacement réaliste
Pause pendant la saisie utilisateur
Gestion propre des timeouts et événements
Créons notre moteur d'animation dans placeholder-animation.ts
:
interface PlaceholderAnimationOptions {
typingSpeed?: number;
deletingSpeed?: number;
pauseDuration?: number;
}
export function initPlaceholderAnimation(
element: HTMLInputElement,
terms: string[],
options: PlaceholderAnimationOptions = {}
): void {
if (!terms || terms.length === 0) return;
const {
typingSpeed = 100,
deletingSpeed = 50,
pauseDuration = 1000
} = options;
let currentTermIndex = 0;
let currentCharIndex = 0;
let isDeleting = false;
let animationId: ReturnType<typeof setTimeout> | null = null;
let isActive = true;
function animate(): void {
if (!isActive) return;
const currentTerm = terms[currentTermIndex];
if (!isDeleting) {
// Typing phase: add one character
element.placeholder = currentTerm.substring(0, currentCharIndex + 1);
currentCharIndex++;
if (currentCharIndex === currentTerm.length) {
// Word complete, pause then start deleting
animationId = setTimeout(() => {
isDeleting = true;
animate();
}, pauseDuration);
return;
}
} else {
// Deleting phase: remove one character
element.placeholder = currentTerm.substring(0, currentCharIndex);
currentCharIndex--;
if (currentCharIndex < 0) {
// Deletion complete, move to next term
isDeleting = false;
currentTermIndex = (currentTermIndex + 1) % terms.length;
currentCharIndex = 0;
}
}
const speed = isDeleting ? deletingSpeed : typingSpeed;
animationId = setTimeout(animate, speed);
}
// Stop animation on focus, clear placeholder
function stopAnimation(): void {
isActive = false;
if (animationId) {
clearTimeout(animationId);
animationId = null;
}
element.placeholder = '';
}
// Restart animation on blur if input is empty
function startAnimation(): void {
if (element.value === '') {
isActive = true;
currentTermIndex = 0;
currentCharIndex = 0;
isDeleting = false;
animate();
}
}
element.addEventListener('focus', stopAnimation);
element.addEventListener('blur', startAnimation);
animate();
}
Pour garantir une intégration transparente dans vos projets existants, nous développons un système d'auto-détection qui scanne automatiquement le DOM à la recherche de formulaires configurés pour l'animation. Cette approche élimine la nécessité d'initialiser manuellement chaque champ de recherche et rend la solution facilement maintenable même sur des sites complexes avec de multiples formulaires.
La fonction helper ci-dessous automatise entièrement le processus :
export function initPlaceholderAnimations(): void {
const searchForms = document.querySelectorAll<HTMLFormElement>('[data-placeholder-terms]');
searchForms.forEach(form => {
const input = form.querySelector<HTMLInputElement>('input[type="search"]');
const termsData = form.getAttribute('data-placeholder-terms');
if (input && termsData) {
try {
const terms = JSON.parse(termsData);
if (Array.isArray(terms)) {
initPlaceholderAnimation(input, terms);
}
} catch (error) {
console.warn('Invalid placeholder terms data:', error);
}
}
});
}
L'un des atouts majeurs de cette solution est sa simplicité d'intégration. Plutôt que d'imposer une structure HTML complexe ou des classes CSS spécifiques, nous utilisons une approche basée sur les attributs data, garantissant une compatibilité maximale avec n'importe quel framework ou CMS.
Cette méthode respecte les standards web modernes et permet une séparation claire entre la logique JavaScript et le markup HTML. Voici comment l'implémenter dans vos templates :
<form class="search-form" data-placeholder-terms="<?php echo json_encode(['produits', 'services', 'documentation', 'support']); ?>">
<input type="search"
name="s"
placeholder="Rechercher..."
class="search-input">
<button type="submit">Rechercher</button>
</form>
Dans votre app.ts
principal :
import { initPlaceholderAnimations } from './lib/placeholder-animation';
// Initialize animations when DOM is ready
initPlaceholderAnimations();
Timing Réaliste
Interaction Intelligente
L'animation comprend quand l'utilisateur veut interagir :
Performance Sans Compromis
L'optimisation technique garantit une exécution fluide :
Adaptez l'animation à votre contexte :
// Animation plus lente et contemplative
initPlaceholderAnimation(input, terms, {
typingSpeed: 150,
deletingSpeed: 75,
pauseDuration: 2500
});
// Animation rapide et dynamique
initPlaceholderAnimation(input, terms, {
typingSpeed: 60,
deletingSpeed: 30,
pauseDuration: 800
});
Quelques bonnes pratiques pour le déploiement :
function get_search_placeholder_terms() {
$terms = [];
// Get popular product categories
$categories = get_terms([
'taxonomy' => 'product_cat',
'orderby' => 'count',
'order' => 'DESC',
'number' => 3,
'hide_empty' => true
]);
foreach ($categories as $category) {
$terms[] = $category->name;
}
// Add featured products
$products = wc_get_products([
'limit' => 2,
'orderby' => 'popularity',
'status' => 'publish'
]);
foreach ($products as $product) {
$terms[] = $product->get_name();
}
return array_slice($terms, 0, 5); // Limit to 5 terms
}
Cette animation typewriter pour placeholder démontre qu'une micro-interaction bien pensée peut transformer radicalement l'expérience utilisateur. En alliant performance technique et design intelligent, nous créons une solution qui guide naturellement l'utilisateur tout en maintenant une fluidité d'interaction irréprochable.
L'approche développée ici illustre parfaitement comment les détails techniques minutieux et l'attention portée à l'expérience utilisateur convergent pour créer des interfaces web modernes et engageantes. Une simple animation de placeholder devient ainsi un véritable outil de communication avec l'utilisateur, suggérant subtilement les possibilités offertes par votre site.
Cet effet fonctionne particulièrement bien sur les sites e-commerce, portfolios et plateformes de contenu où guider la recherche utilisateur est crucial pour l'engagement.
Retrouvez ci-dessous quelques articles qui pourraient vous intéresser.
ACF propose de pouvoir rajouter des champs personnalisés à un élément de menu, mais il ne propose pas de pouvoir l’assigner uniquement à un niveau de profondeur, nous allons découvrir comment le mettre en place simplement. Pour ce faire, nous allons rajouter un nouveau type de règle qui sera assigné au sous-niveau Formulaire, on lui…