Segmentando apenas o Firefox com CSS

616

Usando comentários condicionais, é fácil segmentar o Internet Explorer com regras CSS específicas do navegador:

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

Às vezes, é o mecanismo Gecko (Firefox) que se comporta mal. Qual seria a melhor maneira de segmentar apenas o Firefox com suas regras de CSS e não um único outro navegador? Ou seja, não apenas o Internet Explorer deve ignorar as regras somente do Firefox, mas também o WebKit e Opera.

Nota: Estou procurando uma solução 'limpa'. Usar um sniffer de navegador JavaScript para adicionar uma classe 'firefox' ao meu HTML não se qualifica como limpo na minha opinião. Eu gostaria de ver algo que depende dos recursos do navegador, assim como comentários condicionais são apenas 'especiais' para o IE…

avdgaag
fonte
Pode querer olhar algumas perguntas semelhantes e vários daqueles respostas relacionadas ... stackoverflow.com/questions/738831/...
AnonJr
3
existe alguma maneira de direcionar o firefox em uma máquina windows vs um mac?
Página Inicial>
4
<! - [if Gecko]> ... include ... <! [endif] ->
define

Respostas:

1252

OK, eu encontrei. Essa é provavelmente a solução mais limpa e fácil existente e não depende do JavaScript ativado.

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

É baseado em mais uma extensão CSS específica da Mozilla. Há uma lista completa dessas extensões CSS aqui: Extensões Mozilla CSS .

Ionuț G. Stan
fonte
17
O que exatamente significa o prefixo url () após o "@ -moz-document"? apenas curioso.
Matt
17
@ Matt, essa é uma maneira de filtrar os sites nos quais esse CSS é aplicado. Outra opção é usar o domain()filtro. Por exemplo @-moz-document domain(google.com) {...}, as regras CSS incluídas serão aplicadas apenas no domínio google.com.
Ionuț G. Stan
10
Eu gosto de como você não precisa criar um documento CSS totalmente novo para isso, como você faz para o IE.
JD Isaacks #
7
@JohnIsaacks Você não precisa de uma folha de estilo separada para os comentários condicionais do IE. Eles podem estar em linha. Se você deseja fazer dessa maneira é outra questão.
Dylan
4
Vale ressaltar que esta solução alternativa não funciona mais no Firefox 59, lançada em março de 2018: bugzilla.mozilla.org/show_bug.cgi?id=1035091
Jordan Gray
105

Atualizado (do comentário de @Antoine)

Você pode usar @supports

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

Mais @supports aqui

laaposto
fonte
11
Essa é uma solução muito melhor do que o exemplo @ -moz-document url-prefix (), mas também funciona bem com o analisador SCSS, enquanto o outro não.
Alastair Hodgson
1
Estou usando o Firefox e ele ainda está branco, é por causa da versão que estou usando?
Antoine
3
@Antoine Você está certo! Não funcionou nas versões mais recentes do FF. Eu atualizei minha resposta. Deve funcionar agora. Thanx por apontar isso!
laaposto
83

Veja como lidar com três navegadores diferentes: IE, FF e 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
fonte
66
Se eu entendi isso corretamente, o principal não é o Chrome, mas apenas especifica o comportamento padrão que você substitui no Firefox e IE.
23412 Muhd
3
Muito útil. Como um ex-amante do Firefox, estou estressado por ter que fazer hacks específicos para o Firefox como este, mas, desde que funcione, posso viver com ele.
SpaceBeers
A sugestão para a detecção do IE não funcionará se você quiser adicioná-lo a um arquivo .css. Você pode incluir folhas de estilo dessa maneira no HTML. Se você quer ter IE CSS em um arquivo CSS, eu recomendo a olhar para aqui: keithclark.co.uk/articles/...
Biepbot Von Stirling
16

Aqui estão alguns hacks do navegador para segmentar apenas o navegador Firefox,

Usando hackers seletores.

_:-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 consulta de mídia

Isso vai funcionar no Firefox 3.6 e posterior

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

Se precisar de mais informações, visite browserhacks

Hbirjand
fonte
1
Você poderia elaborar um pouco mais sobre "usar hackers de seletor" e sobre como o exemplo que você forneceu especificamente funciona? Obrigado.
jj_
1
Tudo bem, entendi: basicamente, o que ele faz é ocultar o segundo seletor para outros navegadores que não entendem o primeiro. Nesse caso, apenas a Mozilla entende _:moz-tree-row(hover)que será o único capaz de processar o que .selector{}vem depois. Atualmente, este hacks específico funciona em todas as versões do Firefox, consulte browserhacks.com para saber mais sobre isso.
Jj_
1
Usei o Media Query Hack: \ @media screen e (-moz-images-in-menus: 0) {} isso combina muito bem com \ @media screen e (-webkit-min-device-pixel-ratio: 0) e O Visual Studio não lança um aviso usando-o.
Dan Randolph
1
Observe que -moz-images-in-menus: 0 foi removido no Firefox 52 - bugzilla.mozilla.org/show_bug.cgi?id=1302157 #
jonathanKingston
13

Primeiro de tudo, um aviso. Eu realmente não defendo a solução que apresento abaixo. O único CSS específico do navegador que escrevo é para o IE (especialmente o IE6), embora eu desejasse que não fosse o caso.

Agora, a solução. Você pediu que fosse elegante, então eu não sei o quão elegante é, mas com certeza vai segmentar apenas as plataformas Gecko.

O truque só funciona quando o JavaScript está ativado e faz uso das ligações do Mozilla ( XBL ), que são muito usadas internamente no Firefox e em todos os outros produtos baseados no Gecko. Para uma comparação, isso é como a propriedade CSS de comportamento no IE, mas muito mais poderosa.

Três arquivos estão envolvidos na minha solução:

  1. ff.html: o arquivo para estilizar
  2. ff.xml: o arquivo que contém as ligações do Gecko
  3. ff.css: estilo específico do 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;
}

Atualização: A solução acima não é tão boa. Seria melhor se, em vez de anexar um novo elemento LINK, ele adicionasse a classe "firefox" ao elemento BODY. E é possível, apenas substituindo o JS acima pelo seguinte:

this.className += " firefox";

A solução é inspirada nos comportamentos moz de Dean Edwards .

Ionuț G. Stan
fonte
11

O uso de regras específicas do mecanismo garante uma segmentação eficaz do navegador.

<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
fonte
7

Uma variação da sua ideia é ter uma server-side USER-AGENT detectorque descubra qual folha de estilo anexar à página. Dessa forma, você pode ter um firefox.css, ie.css, opera.css, etc.

Você pode realizar algo semelhante no próprio Javascript, embora não o considere limpo.

Eu fiz uma coisa semelhante por ter uma default.cssque inclui all common styles and then specific style sheetssão adicionados para substituir ou melhorar os padrões.

Kekoa
fonte
Isso parece uma abordagem agradável e estável & mdash; obrigado & mdash; embora ainda dependa do cheiro do navegador. Prefiro usar algo que depende da capacidade, como uma regra CSS somente do Gecko ou algo assim. Eu uso a mesma abordagem básica: estilos padrão e complementos específicos do navegador.
avdgaag 04/06/09
1
@avdaag: A detecção de capacidade é preferida na maioria dos casos, mas quando você está tentando injetar um hack para "corrigir" um bug específico de um mecanismo de renderização, o direcionamento ao agente do usuário é, em teoria, a solução ideal. Você não está discriminando navegadores desconhecidos; e o campo user-agent deve informar qual mecanismo de renderização o navegador está usando; portanto, mesmo que um raro navegador Gecko apareça, ele ainda receberá a correção. Dito isto, muitos navegadores agora falsificam suas seqüências de agente de usuário devido ao uso inadequado da detecção de navegador. Portanto, na prática, pode não funcionar tão bem.
Lèse majesté
6

Agora que o Firefox Quantum 57 está com melhorias substanciais - e potencialmente inovadoras - para o Gecko conhecidas coletivamente como Stylo ou CSS Quantum, você pode se encontrar em uma situação em que precisa distinguir entre versões herdadas do Firefox e Firefox Quantum.

Da minha resposta aqui :

Você pode usar @supportscom uma calc(0s)expressão em conjunto com @-moz-documentpara testar o Stylo - o Gecko não suporta valores de tempo nas calc()expressões, mas o Stylo:

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

Aqui está uma prova de conceito:

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

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

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

A segmentação de versões herdadas do Firefox é um pouco complicada - se você está interessado apenas em versões compatíveis @supports, que são de FX 22 ou superior, @supports not (animation: calc(0s))é tudo o que você precisa:

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

... mas se você precisar oferecer suporte a versões ainda mais antigas, precisará usar a cascata , conforme demonstrado na prova de conceito acima.

BoltClock
fonte
3

A única maneira de fazer isso é através de vários hacks CSS, o que aumentará a probabilidade de sua página falhar nas próximas atualizações do navegador. Se for o caso, será MENOS seguro do que usar um sniffer do navegador js.

jvenema
fonte
0

O código a seguir tende a lançar avisos de estilo de fiapos:

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

Em vez disso, use

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

Me ajudou a sair! Obtenha a solução para o aviso de estilo de cotão daqui

Kailas
fonte