Cibler uniquement Firefox avec CSS

616

En utilisant des commentaires conditionnels, il est facile de cibler Internet Explorer avec des règles CSS spécifiques au navigateur:

<!--[if IE 6]>
...include IE6-specific stylesheet here...
<![endif]-->

Parfois, c'est le moteur Gecko (Firefox) qui se comporte mal. Quelle serait la meilleure façon de cibler uniquement Firefox avec vos règles CSS et pas un seul autre navigateur? Autrement dit, non seulement Internet Explorer doit ignorer les règles de Firefox uniquement, mais également WebKit et Opera doivent le faire.

Remarque: je recherche une solution «propre». L'utilisation d'un renifleur de navigateur JavaScript pour ajouter une classe «firefox» à mon HTML n'est pas considérée comme propre à mon avis. J'aimerais plutôt voir quelque chose qui dépend des capacités du navigateur, un peu comme les commentaires conditionnels ne sont que «spéciaux» pour IE…

avdgaag
la source
Pourrait vouloir regarder quelques questions similaires et leurs réponses connexes ... stackoverflow.com/questions/738831/…
AnonJr
3
Existe-t-il un moyen de cibler Firefox sur une machine Windows par rapport à un Mac?
Kegan Quimby
4
<! - [if Gecko]> ... include ... <! [endif] ->
définit le

Réponses:

1252

OK, je l'ai trouvé. C'est probablement la solution la plus propre et la plus simple qui soit et ne dépend pas de l'activation de JavaScript.

@-moz-document url-prefix() {
  h1 {
    color: red;
  }
}
<h1>This should be red in FF</h1>

Il est basé sur une autre extension CSS spécifique à Mozilla. Il y a toute une liste pour ces extensions CSS ici: Mozilla CSS Extensions .

Ionuț G. Stan
la source
17
Que signifie exactement l'url-prefix () après le "@ -moz-document"? juste curieux.
Matt
17
@Matt, c'est un moyen de filtrer les sites Web sur lesquels ce CSS est appliqué. Une autre option consiste à utiliser le domain()filtre. Par exemple @-moz-document domain(google.com) {...}, appliquera les règles CSS jointes uniquement sur le domaine google.com.
Ionuț G. Stan
10
J'aime la façon dont vous n'avez pas à créer un document CSS entièrement nouveau pour cela, comme vous le faites pour IE.
JD Isaacks
7
@JohnIsaacks Vous n'avez pas besoin d'une feuille de style distincte pour les commentaires conditionnels IE. Ils peuvent être en ligne. Que vous souhaitiez procéder de cette façon est une autre question.
Dylan
4
Il convient de noter que cette solution de contournement ne fonctionne plus à partir de Firefox 59, publié en mars 2018: bugzilla.mozilla.org/show_bug.cgi?id=1035091
Jordan Grey
105

Mise à jour (du commentaire @Antoine)

Vous pouvez utiliser @supports

@supports (-moz-appearance:none) {
    h1 { color:red; } 
}
<h1>This should be red in FF</h1>

Plus @supports ici

laaposto
la source
11
C'est une solution beaucoup plus agréable que l'exemple @ -moz-document url-prefix (), elle fonctionne également bien avec l'analyseur SCSS, contrairement à l'autre.
Alastair Hodgson
1
J'utilise Firefox et il est toujours blanc, est-ce à cause de la version que j'utilise?
Antoine
3
@Antoine Vous avez raison! Cela ne fonctionnait pas pour les dernières versions de FF. J'ai mis à jour ma réponse. Cela devrait fonctionner maintenant. Merci de l'avoir signalé!
laaposto
83

Voici comment aborder trois navigateurs différents: IE, FF et Chrome

<style type='text/css'>
/*This will work for chrome */
#categoryBackNextButtons
{
    width:490px;
}
/*This will work for firefox*/
@-moz-document url-prefix() {
    #categoryBackNextButtons{
        width:486px;
    }
}
</style>
<!--[if IE]>
<style type='text/css'>
/*This will work for IE*/
#categoryBackNextButtons
{
    width:486px;
}
</style>
<![endif]-->
Waqas Ali Khan Puar
la source
66
Si je comprends bien, celui du haut n'est pas chrome, mais spécifie simplement le comportement par défaut que vous remplacez pour Firefox et IE.
Muhd
3
Très utile. En tant qu'ex amateur de Firefox, je suis dégoûté de devoir faire des hacks spécifiques à Firefox comme celui-ci, mais tant que cela fonctionne, je peux vivre avec.
SpaceBeers
La suggestion de détection d'IE ne fonctionne pas si vous souhaitez l'ajouter dans un fichier .css. Vous pouvez cependant inclure des feuilles de style de cette façon en HTML. Si vous voulez avoir IE CSS dans un fichier CSS, je vous recommande de regarder ici: keithclark.co.uk/articles/…
Biepbot Von Stirling
16

Voici quelques hacks de navigateur pour cibler uniquement le navigateur Firefox,

Utilisation de hacks de sélection.

_:-moz-tree-row(hover), .selector {}

Hacks JavaScript

var isFF = !!window.sidebar;

var isFF = 'MozAppearance' in document.documentElement.style;

var isFF = !!navigator.userAgent.match(/firefox/i);

Hacks de requêtes multimédias

Ça va marcher sur Firefox 3.6 et versions ultérieures

@media screen and (-moz-images-in-menus:0) {}

Si vous avez besoin de plus d'informations, veuillez visiter browserhacks

Hbirjand
la source
1
Pourriez-vous nous en dire un peu plus sur «l'utilisation de hacks de sélecteur» et sur le fonctionnement spécifique de l'exemple que vous avez fourni? Merci.
jj_
1
Très bien, je l'ai moi-même: fondamentalement, il cache le deuxième sélecteur à d'autres navigateurs qui ne comprennent pas le premier. Dans ce cas, seul Mozilla comprend _:moz-tree-row(hover), il sera donc le seul à pouvoir traiter le .selector{}suivant. Ce piratage spécifique fonctionne actuellement sur toutes les versions de Firefox, consultez browserhacks.com pour en savoir plus.
jj_
1
J'ai utilisé l'écran Media Query Hack: \ @media et (-moz-images-in-menus: 0) {} Cela va bien avec l'écran \ @media et (-webkit-min-device-pixel-ratio: 0) et Visual Studio ne lance pas d'avertissement en l'utilisant.
Dan Randolph
1
Veuillez noter -moz-images-in-menus: 0 a été supprimé dans Firefox 52 - bugzilla.mozilla.org/show_bug.cgi?id=1302157
jonathanKingston
13

Tout d'abord, un avertissement. Je ne préconise pas vraiment la solution que je présente ci-dessous. Le seul CSS spécifique au navigateur que j'écris est pour IE (en particulier IE6), bien que je souhaite que ce ne soit pas le cas.

Maintenant, la solution. Vous lui avez demandé d'être élégant, donc je ne sais pas à quel point il est élégant, mais il ciblera certainement les plates-formes Gecko uniquement.

L'astuce ne fonctionne que lorsque JavaScript est activé et utilise des liaisons Mozilla ( XBL ), qui sont largement utilisées en interne dans Firefox et tous les autres produits basés sur Gecko. À titre de comparaison, cela ressemble à la propriété CSS de comportement dans IE, mais beaucoup plus puissant.

Trois fichiers sont impliqués dans ma solution:

  1. ff.html: le fichier à coiffer
  2. ff.xml: le fichier contenant les liaisons Gecko
  3. ff.css: style spécifique à Firefox

ff.html

<!DOCTYPE html>

<html>
<head>
<style type="text/css">
body {
 -moz-binding: url(ff.xml#load-mozilla-css);
}
</style>
</head>
<body>

<h1>This should be red in FF</h1>

</body>
</html>

ff.xml

<?xml version="1.0"?>

<bindings xmlns="http://www.mozilla.org/xbl">
    <binding id="load-mozilla-css">
        <implementation>
            <constructor>
            <![CDATA[
                var link = document.createElement("link");
                    link.setAttribute("rel", "stylesheet");
                    link.setAttribute("type", "text/css");
                    link.setAttribute("href", "ff.css");

                document.getElementsByTagName("head")[0]
                        .appendChild(link);
            ]]>
            </constructor>
        </implementation>
    </binding>
</bindings>

ff.css

h1 {
 color: red;
}

Mise à jour: la solution ci-dessus n'est pas si bonne. Il serait préférable qu'au lieu d'ajouter un nouvel élément LINK, il ajoute cette classe "firefox" à l'élément BODY. Et c'est possible, simplement en remplaçant le JS ci-dessus par ce qui suit:

this.className += " firefox";

La solution est inspirée des comportements moz de Dean Edwards .

Ionuț G. Stan
la source
11

L'utilisation de règles spécifiques au moteur garantit un ciblage efficace du navigateur.

<style type="text/css">

    //Other browsers
    color : black;


    //Webkit (Chrome, Safari)
    @media screen and (-webkit-min-device-pixel-ratio:0) { 
        color:green;
    }

    //Firefox
    @media screen and (-moz-images-in-menus:0) {
        color:orange;
    }
</style>

//Internet Explorer
<!--[if IE]>
     <style type='text/css'>
        color:blue;
    </style>
<![endif]-->
Rayjax
la source
7

Une variante de votre idée consiste à en avoir un server-side USER-AGENT detectorqui déterminera la feuille de style à joindre à la page. De cette façon, vous pouvez avoir un firefox.css, ie.css, opera.css, etc.

Vous pouvez accomplir une chose similaire dans Javascript lui-même, bien que vous ne puissiez pas le considérer comme propre.

J'ai fait une chose similaire en ayant un default.cssqui inclut all common styles and then specific style sheetssont ajoutés pour remplacer ou améliorer les valeurs par défaut.

Kekoa
la source
Cela ressemble à une approche agréable et stable & mdash; merci & mdash; bien que cela dépende du reniflement du navigateur. Je préfère utiliser quelque chose qui dépend de la capacité, comme une règle CSS uniquement Gecko ou quelque chose. J'utilise la même approche de base: les styles par défaut et les modules complémentaires spécifiques au navigateur.
avdgaag
1
@avdaag: La détection des capacités est préférée dans la plupart des cas, mais lorsque vous essayez d'injecter un hack pour "corriger" un bogue spécifique d'un moteur de rendu, cibler l'agent utilisateur est, en théorie, la solution optimale. Vous ne faites pas de discrimination contre les navigateurs inconnus; et le champ user-agent est censé vous dire quel moteur de rendu le navigateur utilise, donc même si un navigateur Gecko rare arrive, il recevra toujours le correctif. Cela dit, de nombreux navigateurs simulent désormais leurs chaînes d'agent utilisateur en raison d'une utilisation inappropriée de la détection de navigateur. Donc, en pratique, cela pourrait ne pas fonctionner si bien.
Lèse majesté
6

Maintenant que Firefox Quantum 57 est sorti avec des améliorations substantielles - et potentiellement cassantes - de Gecko collectivement connues sous le nom de Stylo ou CSS Quantum, vous pouvez vous retrouver dans une situation où vous devez faire la distinction entre les versions héritées de Firefox et Firefox Quantum.

De ma réponse ici :

Vous pouvez utiliser @supportsune calc(0s)expression conjointement avec @-moz-documentpour tester Stylo - Gecko ne prend pas en charge les valeurs de temps dans les calc()expressions, mais Stylo le fait:

@-moz-document url-prefix() {
  @supports (animation: calc(0s)) {
    /* Stylo */
  }
}

Voici une preuve de concept:

body::before {
  content: 'Not Fx';
}

@-moz-document url-prefix() {
  body::before {
    content: 'Fx legacy';
  }

  @supports (animation: calc(0s)) {
    body::before {
      content: 'Fx Quantum';
    }
  }
}

Cibler les versions héritées de Firefox est un peu délicat - si vous êtes uniquement intéressé par les versions qui prennent en charge @supports, qui sont Fx 22 et plus, @supports not (animation: calc(0s))c'est tout ce dont vous avez besoin:

@-moz-document url-prefix() {
  @supports not (animation: calc(0s)) {
    /* Gecko */
  }
}

... mais si vous devez prendre en charge des versions encore plus anciennes, vous devrez utiliser la cascade , comme démontré dans la preuve de concept ci-dessus.

BoltClock
la source
3

La seule façon de le faire est via divers hacks CSS, ce qui rendra votre page beaucoup plus susceptible d'échouer lors des prochaines mises à jour du navigateur. Si quoi que ce soit, ce sera MOINS sûr que d'utiliser un renifleur js-browser.

jvenema
la source
0

Le code suivant a tendance à lancer des avertissements de style lint:

@-moz-document url-prefix() {
    h1 {
        color: red;
    }
}

Utilisez plutôt

@-moz-document url-prefix('') {
    h1 {
        color: red;
    }
}

M'a aidé! Vous avez la solution pour l'avertissement de peluches de style d' ici

Kailas
la source