Qual é a ordem de precedência do CSS?

109

Estou tentando descobrir por que uma das minhas classes css parece substituir a outra (e não o contrário)

Aqui eu tenho duas classes css

.smallbox { 
    background-color: white;
    height: 75px;
    width: 150px;
    font-size:20px;
    box-shadow: 0 0 10px #ccc;
    font-family: inherit;
}

.smallbox-paysummary {
    @extend .smallbox; 
    font-size:10px;
}

e na minha opinião eu chamo

<pre class = "span12 pre-scrollable smallbox-paysummary smallbox "> 

A fonte (o elemento sobreposto) aparece como 10px em vez de 20 - alguém poderia explicar por que esse é o caso?

Stephen
fonte
2
Você está usando um pré-processador CSS? Vejo que você tem isso @extend .smallbox;, que parece cSS fora do padrão.
Jared Farrish
Você realmente não deve combinar @extend- se fizer o que eu acho que faz - e usar os dois seletores no mesmo elemento.
millimoose de
SMACSS parece recomendar incluir apenas as propriedades alteradas em uma "subclasse" (ou seja .smallbox-paysummary) e, opcionalmente, tornar a declaração CSS mais claramente específica (sem depender da ordem de aparência no arquivo CSS) usando.smallbox.smallbox-paysummary { font-size: 10px; }
millimoose
1
E se você NÃO deseja que a .smallbox-paysummaryfonte tenha uma fonte menor, por que você a está diminuindo?
millimoose de
Agora estou me perguntando por que, se ambas as regras têm a mesma especificidade, aquela declarada posteriormente no atributo de classe do elemento não tem precedência, independentemente da ordem das regras CSS.
Andy

Respostas:

186

Existem várias regras (aplicadas nesta ordem):

  1. css inline (atributo de estilo html) substitui as regras css na tag de estilo e no arquivo css
  2. um seletor mais específico tem precedência sobre um menos específico
  3. as regras que aparecem posteriormente no código substituem as regras anteriores se ambas tiverem a mesma especificidade.
  4. Uma regra css com !importantsempre tem precedência.

No seu caso, aplica-se a regra 3.

Especificidade para seletores únicos do mais alto ao mais baixo:

  • ids (exemplo: #mainselects <div id="main">)
  • classes (ex .: .myclass), selectores de atributos (ex .: [href=^https:]) e pseudo-classes (ex .: :hover)
  • elementos (ex .: div) e pseudo-elementos (ex .: ::before)

Para comparar a especificidade de dois seletores combinados, compare o número de ocorrências de seletores únicos de cada um dos grupos de especificidade acima.

Exemplo: compare #nav ul li a:hovercom#nav ul li.active a::after

  • conte o número de seletores de id: há um para cada ( #nav)
  • conte o número de seletores de classe: há um para cada ( :hovere .active)
  • conte o número de seletores de elemento: há 3 ( ul li a) para o primeiro e 4 para o segundo ( ul li a ::after), portanto, o segundo seletor combinado é mais específico.

Um bom artigo sobre a especificidade do seletor css .

Lorenz Meyer
fonte
Como a especificidade substitui as declarações de estilo embutido?
Jared Farrish
3
"... regras css na tag de estilo ... substitui as regras no arquivo css". Eu vi esse mito algumas vezes recentemente. Não sei de onde vem, mas não faz sentido.
Alohci
@jared Troquei os dois primeiros pontos. É isso que você quer dizer?
Lorenz Meyer
Sim, foi isso que eu quis dizer.
Jared Farrish
2
@PakiPat :hovernão é um seletor de classe , mas um seletor de pseudo-classe .
Lorenz Meyer
30

Aqui está uma compilação da ordem de estilo CSS em um diagrama, no qual as regras CSS têm maior prioridade e têm precedência sobre o resto: Ordem de estilo CSS

Aviso de isenção de responsabilidade : minha equipe e eu elaboramos essa parte em conjunto com uma postagem no blog ( https://vecta.io/blog/definitive-guide-to-css-styling-order ) que acho que será útil para todos os front-end desenvolvedores.

Qin
fonte
3
Esse diagrama precisa de uma mentalidade especial. Para mim, é muito mais difícil entender esse diagrama do que a própria herança de estilo.
Lorenz Meyer
10

O que estamos vendo aqui é chamado de especificidade, conforme declarado pela Mozilla :

A especificidade é o meio pelo qual os navegadores decidem quais valores de propriedade CSS são os mais relevantes para um elemento e, portanto, serão aplicados. A especificidade é baseada nas regras de correspondência que são compostas por diferentes tipos de seletores CSS.

A especificidade é um peso aplicado a uma determinada declaração CSS, determinado pelo número de cada tipo de seletor no seletor correspondente. Quando várias declarações têm especificidade igual, a última declaração encontrada no CSS é aplicada ao elemento. A especificidade só se aplica quando o mesmo elemento é direcionado por várias declarações. De acordo com as regras CSS, os elementos direcionados diretamente sempre terão precedência sobre as regras que um elemento herda de seu ancestral.

Gosto da explicação 0-0-0 em https://specifishity.com :

insira a descrição da imagem aqui

Bastante descritivo o quadro da !importantdiretiva! Mas às vezes é a única maneira de substituir o styleatributo embutido . Portanto, é uma prática recomendada evitar os dois.

AMS777
fonte
1
excelente. É mesmo o que eu procurava. Este gráfico é excelente lol.
saran3h
7

Em primeiro lugar, com base na sua @extenddiretiva, parece que você não está usando CSS puro, mas um pré-processador como o SASS os Stylus.

Agora, quando falamos sobre "ordem de precedência" em CSS, há uma regra geral envolvida: quaisquer regras definidas após outras regras (de cima para baixo) são aplicadas. No seu caso, apenas especificando .smallboxdepois, .smallbox-paysummaryvocê poderá alterar a precedência de suas regras.

No entanto, se você quiser ir um pouco mais longe, sugiro esta leitura: CSS cascade W3C especificação . Você verá que a precedência de uma regra é baseada em:

  1. O tipo de mídia atual;
  2. Importância;
  3. Origem;
  4. Especificidade do seletor e, finalmente, nossa regra bem conhecida:
  5. Qual é o último especificado.
Renato
fonte
5

AS é o estado em W3: W3 Cascade CSS

a orden que as diferentes folhas de estilo são aplicadas é a seguinte (citação da seção em cascata W3):

  1. declarações do agente do usuário

  2. declarações normais do usuário

  3. declarações normais do autor

  4. autor declarações importantes

  5. declarações importantes do usuário

Mais informações sobre isso no referido documento W3

freeeveloper
fonte
4

A ordem em que as classes aparecem no elemento html não importa, o que conta é a ordem em que os blocos aparecem na folha de estilo.

No seu caso, .smallbox-paysummaryé definido após, .smallboxportanto, a precedência de 10px.

LifeQuery
fonte
4
Element, Pseudo Element: d = 1  (0,0,0,1)
Class, Pseudo class, Attribute: c = 1  (0,0,1,0)
Id: b = 1  (0,1,0,0)
Inline Style: a = 1  (1,0,0,0)

CSS embutido (atributo de estilo html) substitui as regras de css na tag de estilo e no arquivo css

Um seletor mais específico tem precedência sobre um menos específico.

As regras que aparecem posteriormente no código substituem as regras anteriores se ambas tiverem a mesma especificidade.

Lucky Chaturvedi
fonte
Aqui está uma boa explicação: vanseodesign.com/css/css-specificity-inheritance-cascaade
akostadinov
1
@Mahi Eu acenei com sua sugestão de edição desta vez, mas no futuro, por favor, não adicione lixo a uma edição apenas para torná-la longa o suficiente. Ter uma segunda edição que "desfaça" o dano de uma primeira é uma prática muito ruim, muito pouco intuitiva para os revisores e cria mais trabalho do que o necessário. Em vez disso, apenas procure outras coisas que podem ser melhoradas (como ortografia ou gramática).
Siguza
0

Também é importante observar que quando você tem dois estilos em um elemento HTML com precedência igual, o navegador dará precedência aos estilos que foram gravados no DOM por último ... portanto, se estiver no DOM:

<html>
<head>
<style>.container-ext { width: 100%; }</style>
<style>.container { width: 50px; }</style>
</head>
<body>
<div class="container container-ext">Hello World</div>
</body>

... a largura do div será de 50 px

P. Avery
fonte
Isso não é realmente precedência, é a parte em cascata das folhas de estilo em cascata.
TylerH de