Connaître les caractéristiques du navigateur peut s'avérer utile pour proposer des interfaces adaptées ou affiner le tracking et les statistiques.
Certains éléments ou fonctionnalités peuvent dépendre du navigateur, mais aussi du système d'exploitation.
Par exemple, vous souhaitez expliquer à un visiteur comment agrandir le texte avec des combinaisons de touches clavier. Selon qu'il utilise un clavier Apple ou classique, les raccourcis ne sont pas les mêmes.
L'agrandissement du texte peut être Touche clavier Ctrl Ctrl Touche clavier + + ou Touche clavier Command ⌘ Touche clavier + + .
Pour simplifier la consultation et la compréhension, il n'est pas nécessaire d'énumérer toutes les possibilités.
Autre application possible, le système de paiement Apple Pay n'est pas très utile si vous n'êtes pas sur iOS ou Mac OS.
Il existait autrefois une librairie jQuery.browser qui permettait d'avoir accès aux informations du navigateur. Elle n'est pas maintenue de puis 10 ans et nécessite jQuery.
Le script, natif et sans dépendance, qui suit permet de poser des attributs et/ou des classes CSS, sur deux noeuds essentiels du DOM : le root (html) et le body.
La fonction detectBrowserInfo va rattacher à window un objet browserInfo utilisable dans n'importe quel autre script.
Cette objet contient :
name, (chrome, safari, firefox, etc.) ;versionNumber, le numéro de version du navigateur ;platform, le système d'exploitation ;engine, le moteur de rendu ;browserVersion, la concaténation dename-version(safari-18 par exemple) ;deviceType, mobile ou desktop.
Il permet également d'ajouter automatiquement des classes CSS préfixées ua-*, au choix, sur le root et/ou le body.
En complément et pour faire joli, le script peut déposer des attributs data-ua-* correspondants au propriétés.
Pour choisir où appliquer les attributs et classes, la fonction est configurable par :
const applyTargets = {
root: { applyAttributes: true, applyClasses: false },
body: { applyAttributes: false, applyClasses: true }
};
Javascript
Pour visualiser l'application du script, c'est simple : ouvrez la console avec Touche clavier Ctrl Ctrl Touche clavier Majuscule ⇧ Touche clavier i i Touche clavier Command ⌘ Touche clavier Option Touche clavier i i .
Taille brute : 8,82 kilo-octets (~2,41 kilo-octets gzip)
(() => {
'use strict';
/**
* Détecte et applique les informations du navigateur au DOM.
*
* La détection du `deviceType` privilégie les Media Queries sur le UA sniffing,
* à l'exception de l'iPad post-iOS 13 qui se déclare en Macintosh,
* et des Pixel/Android qui peuvent déclarer `pointer: fine` malgré l'écran tactile.
*
* @returns {{
* name: string, - Nom du navigateur (ex: "chrome", "safari")
* versionNumber: string, - Version majeure (ex: "120")
* platform: string, - OS/plateforme (ex: "windows", "android")
* engine: string, - Moteur de rendu (ex: "blink", "gecko")
* deviceType: string, - Type d'appareil : "mobile" | "tablet" | "hybrid" | "desktop"
* browserVersion: string - Combinaison nom-version (ex: "chrome-120")
* }}
*/
const detectBrowserInfo = () => {
const ua = navigator.userAgent;
const platformRaw = navigator.platform || 'unknown';
let name = 'unknown';
let version = 'unknown';
let platform = 'unknown';
let engine = 'unknown';
/* ── Navigateur ─────────────────────────────────────────────────────────
* Ordre important : Edge, Opera et Brave incluent aussi "Chrome/" dans
* leur UA — ils doivent être testés avant Chrome.
* SamsungBrowser et les variantes iOS (CriOS, FxiOS) avant leurs parents.
* ──────────────────────────────────────────────────────────────────── */
if (ua.includes('Edg/')) {
name = 'Edge';
version = ua.match(/Edg\/(\d+)/)?.[1] ?? version;
} else if (ua.includes('OPR/') ||
ua.includes('Opera')) {
name = 'Opera';
version = ua.match(/(OPR|Opera)\/(\d+)/)?.[2] ?? version;
} else if (ua.includes('Brave')) {
name = 'Brave';
version = ua.match(/Chrome\/(\d+)/)?.[1] ?? version;
} else if (ua.includes('SamsungBrowser')) {
name = 'Samsung Internet';
version = ua.match(/SamsungBrowser\/(\d+)/)?.[1] ?? version;
} else if (ua.includes('CriOS')) {
name = 'Chrome iOS';
version = ua.match(/CriOS\/(\d+)/)?.[1] ?? version;
} else if (ua.includes('FxiOS')) {
name = 'Firefox iOS';
version = ua.match(/FxiOS\/(\d+)/)?.[1] ?? version;
} else if (ua.includes('Chrome/')) {
name = 'Chrome';
version = ua.match(/Chrome\/(\d+)/)?.[1] ?? version;
} else if (ua.includes('Safari/') &&
!ua.includes('Chrome/')) {
name = 'Safari';
version = ua.match(/Version\/(\d+)/)?.[1] ?? version;
} else if (ua.includes('Firefox/')) {
name = 'Firefox';
version = ua.match(/Firefox\/(\d+)/)?.[1] ?? version;
} else if (ua.includes('MSIE') ||
ua.includes('Trident/')) {
name = 'Internet Explorer';
version = ua.match(/(MSIE\s|rv:)(\d+)/)?.[2] ?? version;
}
/* ── Plateforme ──────────────────────────────────────────────────────── */
platform = ua.includes('CrOS') || platformRaw.includes('CrOS') ? 'chrome os'
: ua.includes('Android') ? 'android'
: /iPhone|iPad|iPod/.test(ua) ? 'ios'
: platformRaw.includes('Win') ? 'windows'
: platformRaw.includes('Mac') ? 'macos'
: platformRaw.includes('Linux') ? 'linux'
: ua.includes('KaiOS') ? 'kaios'
: ua.includes('X11') ? 'unix'
: platform;
/* ── Moteur de rendu ─────────────────────────────────────────────────── */
engine = ua.includes('AppleWebKit')
? (/Chrome|Edg\/|OPR\/|Brave/.test(ua) ? 'blink' : 'webkit')
: (ua.includes('Gecko/') && ua.includes('Firefox')) ? 'gecko'
: (ua.includes('Trident/') || ua.includes('MSIE')) ? 'trident'
: ua.includes('Presto') ? 'presto'
: ua.includes('Servo') ? 'servo'
: engine;
/* ── Type d'appareil ─────────────────────────────────────────────────
* Priorité aux Media Queries (pointer, hover) sur le UA sniffing.
*
* Cas particuliers :
* - iPad post-iOS 13 : se déclare en "Macintosh", combinaison UA + any-pointer
* - Pixel et certains Android : déclarent `pointer: fine` malgré l'écran
* tactile — `maxTouchPoints` + UA Android comme filet de sécurité
*
* Valeurs possibles :
* "mobile" → pointeur grossier + écran ≤ 768px (ou Android tactile ≤ 768px)
* "tablet" → pointeur grossier + écran > 768px (ou iPad, ou Android tactile > 768px)
* "hybrid" → tout pointeur grossier ET hover disponible (Surface, iPad + Magic Keyboard…)
* "desktop" → pointeur fin ou hover disponible
* ──────────────────────────────────────────────────────────────────── */
const mq = q => window.matchMedia(q).matches;
const coarse = mq('(pointer: coarse)');
const noHover = mq('(hover: none)');
const anyCoarse = mq('(any-pointer: coarse)');
const anyHover = mq('(any-hover: hover)');
const screenMax = Math.max(window.screen.width, window.screen.height);
const screenMin = Math.min(window.screen.width, window.screen.height);
const isIPadUA = /iPad/i.test(ua) || (/Macintosh/i.test(ua) && anyCoarse);
const isAndroidTouch = /Android/i.test(ua) && navigator.maxTouchPoints > 0;
const deviceType = isIPadUA ? 'tablet'
: (coarse && noHover && screenMin <= 600) ? 'mobile'
: (coarse && noHover) ? 'tablet'
: (isAndroidTouch && screenMin <= 600) ? 'mobile'
: (isAndroidTouch) ? 'tablet'
: (anyCoarse && anyHover) ? 'hybrid'
: 'desktop';
/* ── Application au DOM ──────────────────────────────────────────────── */
const sanitize = str => str.replace(/\s+/g, '-');
const nameFinal = name.toLowerCase();
const versionFinal = version.toLowerCase();
const platformFinal = platform.toLowerCase();
const engineFinal = engine.toLowerCase();
const attributes = {
'data-ua-name': nameFinal,
'data-ua-version': versionFinal,
'data-ua-platform': platformFinal,
'data-ua-engine': engineFinal,
'data-ua-device': deviceType
};
const classes = [
`ua-${sanitize(nameFinal)}`,
`ua-${sanitize(platformFinal)}`,
`ua-${engineFinal}`,
`ua-${sanitize(nameFinal)}-${versionFinal}`,
`ua-${deviceType}`
];
/**
* Applique attributs data-ua-* et/ou classes CSS à un élément DOM.
*
* @param {HTMLElement} element
* @param {{ applyAttributes: boolean, applyClasses: boolean }} config
*/
const applyInfoToDOM = (element, config) => {
if (!element) return;
if (config.applyAttributes)
Object.entries(attributes).forEach(([k, v]) => {
v && typeof v === 'string' && element.setAttribute(k, v);
});
if (config.applyClasses)
element.classList.add(...classes);
};
applyInfoToDOM(document.documentElement, {applyAttributes: true, applyClasses: true});
applyInfoToDOM(document.body, {applyAttributes: false, applyClasses: true});
return {
name: nameFinal,
versionNumber: versionFinal,
platform: platformFinal,
engine: engineFinal,
deviceType,
browserVersion: `${nameFinal}-${versionFinal}`
};
};
/* ── Init ────────────────────────────────────────────────────────────────
* Si le DOM est déjà disponible on exécute immédiatement,
* sinon on attend DOMContentLoaded.
* ──────────────────────────────────────────────────────────────────── */
document.readyState === 'loading'
? document.addEventListener('DOMContentLoaded', () => {
window.browserInfo = detectBrowserInfo();
})
: window.browserInfo = detectBrowserInfo();
})();
Télécharger kortic-browserInfo.js
Usage avec CSS
On peut créer, par exemple, deux classes applicables uniquement sur terminaux Apple.
.no-apple et .is-apple. Les éléments du DOM qui portent la classe no-apple seront masqués sur tout appareil qui n'est pas de la marque, quelque soit le navigateur.
Vous lisez ce texte car vous n'êtes pas sur un appareil Mac OS ou iOS.
Avec des classes CSS sur body.
body:is(.ua-macos, .ua-ios) .no-apple {
display: none;
}
body:not(:is(.ua-macos, .ua-ios)) .is-apple {
display: none;
}
Usage via Javascript
En utilisant les attributs data-ua-*, on peut cibler des versions spécifiques minimales pour exploiter des fonctionnalités.
Vérifie si le navigateur est Chrome sur Windows, version ≥ 130
That's all, Folks !