Uma classe CSS pode herdar uma ou mais outras classes?

736

Sinto-me idiota por ter sido um programador da web por tanto tempo e por não saber a resposta para essa pergunta, espero que seja possível e simplesmente não soubesse do que eu acho que é a resposta (o que é que não é possível) .

Minha pergunta é se é possível criar uma classe CSS que "herda" de outra classe CSS (ou mais de uma).

Por exemplo, digamos que tivemos:

.something { display:inline }
.else      { background:red }

O que eu gostaria de fazer é algo como isto:

.composite 
{
   .something;
   .else
}

onde a classe ".composite" seria exibida em linha e teria um fundo vermelho

Joel Martinez
fonte
3
pensar mais em cascata, em vez de herança, não se aplica aqui
blu

Respostas:

427

Existem ferramentas como LESS , que permitem compor CSS em um nível mais alto de abstração, semelhante ao que você descreve.

Menos chama esses "mixins"

Ao invés de

/* CSS */
#header {
  -moz-border-radius: 8px;
  -webkit-border-radius: 8px;
  border-radius: 8px;
}

#footer {
  -moz-border-radius: 8px;
  -webkit-border-radius: 8px;
  border-radius: 8px;
}

Você poderia dizer

/* LESS */
.rounded_corners {
  -moz-border-radius: 8px;
  -webkit-border-radius: 8px;
  border-radius: 8px;
}

#header {
  .rounded_corners;
}

#footer {
  .rounded_corners;
}
Larsenal
fonte
37
wow, menos é muito bonito exatamente o que estou procurando ... é uma pena que não é suportado nativamente, e que ele é escrito em Ruby (estou usando o ASP.NET MVC)
Joel Martinez
1
Sim, também estou no mundo do ASP.NET, por isso não o mudei para o meu fluxo de trabalho de produção.
Larsenal
Menos é bonito e tentador ... mas não tive muito sucesso usando-o com o CSSEdit no mesmo fluxo de trabalho - por isso ainda não o adotei totalmente.
22919 Ryan Florence
1
Sim, MENOS é muito doce, não é? Na verdade, eu estou trabalhando em uma porta .NET aqui: nlesscss.codeplex.com .
Owen
77
no caso de você acessá-lo via google: a porta .Net agora está aqui
Eonasdan
310

Você pode adicionar várias classes a um único elemento DOM, por exemplo

<div class="firstClass secondClass thirdclass fourthclass"></div>

As regras dadas nas classes posteriores (ou que são mais específicas) substituem. Portanto fourthclass, nesse tipo de exemplo prevalece.

A herança não faz parte do padrão CSS.

Matt Bridges
fonte
12
você sabe se qual classe prevalece, a última ou a primeira, e o comportamento entre navegadores é seguro? Digamos que .firstClass {font-size:12px;} .secondClass {font-size:20px;}, em seguida, o final font-sizeserá 12pxou 20pxe este navegador é seguro?
Marco Demaio
27
A regra com a mais alta especificidade no seletor vencerá. Aplicam-se regras padrão de especificidade; no seu exemplo, como "first" e "second" têm a mesma especificidade, a regra declarada posteriormente no CSS vencerá.
Matt Pontes
19
Eu gosto da idéia de usar CSS puro (em vez de MENOS) para resolver esse problema.
9283 Alex
8
Eu também gosto da idéia de não digitando várias classes várias vezes - que é O (n ^ 2) trabalho :)
Segredo
3
E se eu estiver usando uma biblioteca de terceiros e quiser modificar o design / HTML que ele fornece, mas não puder alterar os arquivos CSS embutidos nessa biblioteca? Lá eu precisaria de algum tipo de herança nas aulas de CSS.
Shivam
112

Sim, mas não exatamente com essa sintaxe.

.composite,
.something { display:inline }

.composite,
.else      { background:red }
mlouro
fonte
7
Isso é péssimo, mas estou feliz que tenhamos pelo menos isso!
Pacerier 12/12/12
3
Por que é péssimo? parece muito bom. Não consigo entender a diferença entre o símbolo de vírgula e a solução less.js.
Revious
21
Porque se as classes .something e .else estiverem em arquivos diferentes e você não puder modificá-las, ficará bloqueado.
Alexandre Mélard 25/03
8
Esta foi a resposta correta, porque respondeu à pergunta usando a sintaxe CSS pura. A resposta menos é bom saber embora.
Raddevus 6/08/2015
1
Essa deve ser a resposta exceto.
eaglei22
66

Mantenha seus atributos comuns juntos e atribua atributos específicos (ou substitua) novamente.

/*  ------------------------------------------------------------------------------ */   
/*  Headings */ 
/*  ------------------------------------------------------------------------------ */   
h1, h2, h3, h4
{
    font-family         : myfind-bold;
    color               : #4C4C4C;
    display:inline-block;
    width:900px;
    text-align:left;
    background-image: linear-gradient(0,   #F4F4F4, #FEFEFE);/* IE6 & IE7 */
}

h1  
{
    font-size           : 300%;
    padding             : 45px 40px 45px 0px;
}

h2
{
    font-size           : 200%;
    padding             : 30px 25px 30px 0px;
}
user2990362
fonte
2
Isso está muito próximo de uma solução ideal, espero que as pessoas não a descartem apenas porque obteve poucos votos. De fato, uma das questões mais desafiadoras sobre a "herança de CSS" é que você geralmente obtém um software da Web enorme e já feito (por exemplo, um software famoso para PHP de comércio eletrônico ou blog) e eles empregam código PHP que nativamente ganha ' t adicione várias classes aos elementos HTML que eles excederem. Isso força você a mexer no código-fonte (perdendo alterações se você atualizar mais tarde) para fazer com que ele produza essas classes adicionais. Com essa abordagem, em vez disso, você apenas edita o arquivo CSS!
Dario Fumagalli
3
Era exatamente isso que eu estava procurando. Não vale a pena que essa mesma abordagem funcione com seletores CSS? Em vez de especificar h1, h2, etcvocê pode especificar.selector1, .selector2, .etc
JeffryHouser
Eu gostaria de comentar que esta é precisamente a abordagem usada pelo w3 na folha de estilos html padrão recomendada: [w3 CSS2]: w3.org/TR/CSS2/sample.html . Também estou tentando entender como organizar o código css, e parece que o paradigma é invertido comparado à herança típica orientada a objetos: você usa classes (ou, geralmente, seletores) para especificar quais elementos herdam quais atributos, mas você herda atributos (pelo menos, é assim que a hierarquia pode existir mais facilmente logicamente) e substitui os atributos nos seletores mais específicos quando necessário.
Nathan Chappell
51

Um elemento pode receber várias classes:

.classOne { font-weight: bold; }
.classTwo { font-famiy:  verdana; }

<div class="classOne classTwo">
  <p>I'm bold and verdana.</p>
</div>

E isso é o mais perto que você vai chegar, infelizmente. Eu adoraria ver esse recurso, juntamente com aliases de classe algum dia.

Sampson
fonte
45

Não, você não pode fazer algo como

.composite 
{
   .something;
   .else
}

Este não é um nome de "classe" no sentido OO. .somethinge .elsesão apenas seletores e nada mais.

Mas você pode especificar duas classes em um elemento

<div class="something else">...</div>

ou você pode procurar outra forma de herança

.foo {
  background-color: white;
  color: black;
}

.bar {
  background-color: inherit;
  color: inherit;
  font-weight: normal;
}
<div class="foo">
  <p class="bar">Hello, world</p>
</div>

Onde os parágrafos backgroundcolor e color são herdados das configurações na div anexo que é .fooestilizada. Pode ser necessário verificar a especificação exata do W3C. inherité padrão para a maioria das propriedades, mas não para todas.

nervosismo
fonte
1
Sim, essa (primeira parte) era minha expectativa quando ouvi falar de CSS no século 20 ... e ainda não o temos, eles estão queimando o desempenho em algumas coisas dinâmicas, enquanto isso pode ser composto estático pouco antes da aplicação do css e substitui a necessidade de variáveis (estáticas "variáveis")
neu-rah
30

Corri para o mesmo problema e acabei usando uma solução JQuery para fazer parecer que uma classe pode herdar outras classes.

<script>
    $(function(){
            $(".composite").addClass("something else");
        });
</script>

Isso encontrará todos os elementos com a classe "composto" e adicionará as classes "algo" e "mais" aos elementos. Então, algo como <div class="composite">...</div>vai acabar assim:
<div class="composite something else">...</div>

DHoover
fonte
1
O problema com esta solução é que se aplica a todos os controles existentes; se você criar o controle após esta chamada, ele não terá a nova classe.
LuisEduardoSP 02/09/19
27

A maneira SCSS para o exemplo dado seria algo como:

.something {
  display: inline
}
.else {
  background: red
}

.composite {
  @extend .something;
  @extend .else;
}

Mais informações, consulte o básico sobre sass

Alter Lagos
fonte
Qual é o valor agregado comparado a isso? .composite,.something { display:inline }e.composite,.else { background:red }
Pavel Gatnar
2
@PavelGatnar Você pode reutilizar as definições de .somethinge .elseem outras definições de css.
Alter Lagos
16

O melhor que você pode fazer é isso

CSS

.car {
  font-weight: bold;
}
.benz {
  background-color: blue;
}
.toyota {
  background-color: white;
}

HTML

<div class="car benz">
  <p>I'm bold and blue.</p>
</div>
<div class="car toyota">
  <p>I'm bold and white.</p>
</div>
electricbah
fonte
12

Não esqueça:

div.something.else {

    // will only style a div with both, not just one or the other

}
Ryan Florence
fonte
1
im não olhando para ele, mas esta foi construtiva para mim n__n
AgelessEssence
7

No arquivo CSS:

p.Title 
{
  font-family: Arial;
  font-size: 16px;
}

p.SubTitle p.Title
{
   font-size: 12px;
}
pedrofernandes
fonte
2
Então, qual será o resultado font-size?
abatishchev
O tamanho da fonte seria 12px para "p.Title" porque é definido após o primeiro no arquivo. substitui o primeiro tamanho da fonte.
YWE 23/03
@YWE: Isso significa que as declarações devem ser o contrário, em comparação com o que está escrito nesta resposta (pelo menos se quisermos que o exemplo seja ilustrativo)? Se o último definido prevalecer, font-size: 16pxnunca poderá entrar em vigor, certo?
OR Mapper
@ORMapper - normalmente o que acontece é que a primeira declaração está em um arquivo css comum, compartilhado por várias páginas. Em seguida, a segunda declaração está em um segundo arquivo css, usado apenas em determinadas páginas. E importado após o arquivo css comum. Portanto, essas páginas usam o valor "visto pela última vez" de 12px.
Home
7

Sei que essa pergunta agora é muito antiga, mas aqui não vale nada!

Se a intenção é adicionar uma única classe que implique as propriedades de várias classes, como uma solução nativa, eu recomendaria o uso de JavaScript / jQuery (o jQuery realmente não é necessário, mas certamente útil)

Se você possui, por exemplo, .umbrellaClassque "herda" de .baseClass1e .baseClass2você pode ter algum JavaScript que é acionado pronto.

$(".umbrellaClass").addClass("baseClass1");
$(".umbrellaClass").addClass("baseClass2");

Agora todos os elementos de .umbrellaClassterão todas as propriedades de ambos .baseClass. Observe que, como a herança de OOP, .umbrellaClasspode ou não ter suas próprias propriedades.

A única ressalva aqui é considerar se há elementos sendo criados dinamicamente que não existirão quando esse código for acionado, mas também existem maneiras simples de contornar isso.

Sucks css, no entanto, não tem herança nativa.

John Carrell
fonte
1
Essa abordagem já foi sugerida na resposta do @ DHoover a partir de 2013.
Bryan
6

Momento perfeito : passei desta pergunta para o meu e-mail para encontrar um artigo sobre Menos , uma biblioteca Ruby que, entre outras coisas, faz isso:

Como super parece footer, mas com uma fonte diferente, usarei a técnica de inclusão de classe de Less (eles chamam de mixin) para dizer para incluir também essas declarações:

#super {
  #footer;
  font-family: cursive;
}
RichieHindle
fonte
Quando pensei que o LESS não poderia me surpreender mais ... eu não tinha ideia de que você poderia importar a formatação de outro bloco como este. Ótima dica.
Daniel Rippstein
4

Infelizmente, o CSS não fornece 'herança' da mesma maneira que linguagens de programação como C ++, C # ou Java. Você não pode declarar uma classe CSS e depois estendê-la com outra classe CSS.

No entanto, você pode aplicar mais de uma classe a uma tag em sua marcação ... nesse caso, existe um conjunto sofisticado de regras que determinam quais estilos reais serão aplicados pelo navegador.

<span class="styleA styleB"> ... </span>

O CSS procurará todos os estilos que podem ser aplicados com base na sua marcação e combinará os estilos CSS dessas várias regras.

Normalmente, os estilos são mesclados, mas, quando surgem conflitos, o estilo declarado posteriormente geralmente vence (a menos que o atributo! Important seja especificado em um dos estilos, nesse caso, o vencedor). Além disso, os estilos aplicados diretamente a um elemento HTML têm precedência sobre os estilos de classe CSS.

LBushkin
fonte
Sua resposta surgiu como primeiro resultado no google para mim e foi útil. Dito isso, tenho uma dica para você - se você estiver oferecendo uma solução, é melhor evitar iniciar frases negativamente (infelizmente, o CSS não fornece herança ..) Sei que qualquer pessoa com paciência adequada leria para descobrir sua boa solução mas às vezes as pessoas estão com pouca paciência e podem chegar a uma conclusão de que o que estão tentando fazer é impossível. Para ter a melhor chance de ajudar os outros, você pode começar com algo como "Embora o CSS não tenha herança, você pode conseguir o que precisa ..."
egmfrs
4

Há também o SASS, que você pode encontrar em http://sass-lang.com/ . Há uma tag @extend, além de um sistema do tipo mix-in. (Rubi)

É uma espécie de concorrente para MENOS.

chug2k
fonte
4

Isso não é possível em CSS.

A única coisa suportada no CSS é ser mais específico do que outra regra:

span { display:inline }
span.myclass { background: red }

Um período com a classe "myclass" terá as duas propriedades.

Outra maneira é especificar duas classes:

<div class="something else">...</div>

O estilo de "else" substituirá (ou adicionará) o estilo de "something"

Philippe Leybaert
fonte
Para todos os estilos em um arquivo, existe uma solução semelhante a uma herança em CSS, veja meu post.
Pavel Gatnar 11/09/15
3

Você pode aplicar mais de uma classe CSS a um elemento usando algo como esta classe = "outra coisa"

Pete
fonte
3

Como já foi dito, você pode adicionar várias classes a um elemento.

Mas esse não é realmente o ponto. Eu recebo sua pergunta sobre herança. O ponto real é que a herança no CSS é feita não através de classes, mas através de hierarquias de elementos. Portanto, para modelar características herdadas, é necessário aplicá-las a diferentes níveis de elementos no DOM.

Assaf Lavie
fonte
É melhor criar definições CSS semelhantes a herança, em vez de usar toda a cadeia de classes de composição, veja meu post.
Pavel Gatnar
2

Eu estava procurando isso como um louco também e só descobri tentando coisas diferentes: P ... Bem, você pode fazer assim:

composite.something, composite.else
{
    blblalba
}

De repente, funcionou para mim :)

BiBi
fonte
2

Em circunstâncias específicas, você pode fazer uma herança "branda":

.composite
{
display:inherit;
background:inherit;
}

.something { display:inline }
.else      { background:red }

Isso funciona apenas se você estiver adicionando a classe .composite a um elemento filho. É uma herança "flexível" porque quaisquer valores não especificados em .composite não são herdados obviamente. Lembre-se de que ainda haveria menos caracteres para escrever "inline" e "red" em vez de "herdar".

Aqui está uma lista de propriedades e se elas fazem ou não automaticamente: https://www.w3.org/TR/CSS21/propidx.html

hydrix
fonte
2

Embora a herança direta não seja possível.

É possível usar uma classe (ou ID) para uma tag pai e, em seguida, usar combinadores CSS para alterar o comportamento da tag filho de sua hierarquia.

p.test{background-color:rgba(55,55,55,0.1);}
p.test > span{background-color:rgba(55,55,55,0.1);}
p.test > span > span{background-color:rgba(55,55,55,0.1);}
p.test > span > span > span{background-color:rgba(55,55,55,0.1);}
p.test > span > span > span > span{background-color:rgba(55,55,55,0.1);}
p.test > span > span > span > span > span{background-color:rgba(55,55,55,0.1);}
p.test > span > span > span > span > span > span{background-color:rgba(55,55,55,0.1);}
p.test > span > span > span > span > span > span > span{background-color:rgba(55,55,55,0.1);}
p.test > span > span > span > span > span > span > span > span{background-color:rgba(55,55,55,0.1);}
<p class="test"><span>One <span>possible <span>solution <span>is <span>using <span>multiple <span>nested <span>tags</span></span></span></span></span></span></span></span></p>

Eu não sugeriria usar tantas extensões como o exemplo, no entanto, é apenas uma prova de conceito. Ainda existem muitos erros que podem surgir ao tentar aplicar CSS dessa maneira. (Por exemplo, alterar os tipos de decoração de texto).

Desconhecido
fonte
2

Less e Sass são pré-processadores CSS que estendem a linguagem CSS de maneiras valiosas. Apenas uma das muitas melhorias que eles oferecem é apenas a opção que você está procurando. Existem algumas respostas muito boas com menos e vou adicionar a solução Sass.

O Sass possui a opção de extensão, que permite que uma classe seja totalmente estendida para outra. Mais sobre extensão, você pode ler neste artigo

Nesha Zoric
fonte
1

CSS realmente não faz o que você está perguntando. Se você deseja escrever regras com essa ideia composta em mente, confira a bússola . É uma estrutura de folha de estilo que se parece com o já mencionado Less.

Permite fazer mixins e todos os bons negócios.

Zack The Human
fonte
Adicionando mais detalhes acima, o Compass aka Sass via Extend, PlaceHolders Mixins vs Extend , informações mais detalhadas sobre PlaceHolders
Abhijeet
1

Para aqueles que não estão satisfeitos com as postagens mencionadas (excelentes), você pode usar suas habilidades de programação para criar uma variável (PHP ou qualquer outra) e armazenar os vários nomes de classe.

Esse é o melhor truque que eu poderia inventar.

<style>
.red { color: red; }
.bold { font-weight: bold; }
</style>

<? define('DANGERTEXT','red bold'); ?>

Em seguida, aplique a variável global ao elemento que você deseja, em vez dos nomes das classes

<span class="<?=DANGERTEXT?>"> Le Champion est Ici </span>
Shakir
fonte
1

Não pense nas classes css como classes orientadas a objetos, pense nelas apenas como uma ferramenta entre outros seletores para especificar em quais classes de atributo um elemento html é denominado. Pense em tudo entre os chavetas como a classe de atributo , e os seletores no lado esquerdo informam os elementos que eles selecionam para herdar atributos da classe de atributo . Exemplo:

.foo, .bar { font-weight : bold; font-size : 2em; /* attribute class A */}
.foo { color : green; /* attribute class B */}

Quando um elemento é dado o atributo class="foo", é útil para pensar sobre isso não como herdar atributos de classe .foo, mas de classe atributo A e classe B atributo . Ou seja, o gráfico de herança tem um nível de profundidade, com elementos derivados de classes de atributos e os seletores especificando para onde as arestas vão e determinando a precedência quando houver atributos concorrentes (semelhante à ordem de resolução do método).

insira a descrição da imagem aqui

A implicação prática para a programação é essa. Digamos que você tenha a folha de estilos fornecida acima e deseje adicionar uma nova classe .baz, na qual ela deve ter o mesmo font-sizeque .foo. A solução ingênua seria esta:

.foo, .bar { font-weight : bold; font-size : 2em; /* attribute class A */}
.foo { color : green; /* attribute class B */}
.baz { font-size : 2em; /* attribute class C, hidden dependency! */}

insira a descrição da imagem aqui

Toda vez que tenho que digitar algo duas vezes fico tão bravo! Não só tenho que escrever duas vezes, agora não tenho como indicar programaticamente isso .fooe .bazdeve ter o mesmo font-size, e criei uma dependência oculta! Meu paradigma acima sugeriria que eu abstraísse o font-sizeatributo da classe de atributo A :

.foo, .bar, .baz { font-size : 2em; /* attribute base class for A */}
.foo, .bar { font-weight : bold; /* attribute class A */}
.foo { color : green; /* attribute class B */}

insira a descrição da imagem aqui

A principal queixa é que agora eu tenho que digitar novamente a cada seletor de classe de atributo A novamente para especificar que os elementos que devem selecionar deve atributos também herdar de classe base atributo A . Ainda assim, é preciso lembrar de editar todas as classes de atributos em que existem dependências ocultas sempre que algo mudar ou usar uma ferramenta de terceiros. A primeira opção faz deus rir, a segunda me faz querer me matar.

Nathan Chappell
fonte
0

Se você deseja um pré-processador de texto mais poderoso que o LESS, confira o PPWizard:

http://dennisbareis.com/ppwizard.htm

Aviso: o site é realmente hediondo e existe uma pequena curva de aprendizado, mas é perfeito para criar códigos CSS e HTML por meio de macros. Eu nunca entendi por que mais codificadores da web não o usam.

BloDoe
fonte
11
O site é realmente hediondo.
Nanofarad
Meio irônico em um site para um processador html!
Ben Thurley 30/10/12
2
Sim, o site é hediondo, mas é mais do que isso. É difícil de ler e faz minha cabeça doer também!
ArtOfWarfare 6/09/2013
1
Uma coisa boa que é compatível com o Windows 3.1 para XP, lol #
315 Alter Alter
Uma ferramenta não-padrão bizarra, nada parecido.
22717 berkus
-6

Você pode conseguir o que deseja se pré-processar seus arquivos .css através do php. ...

$something='color:red;'
$else='display:inline;';
echo '.something {'. $something .'}';
echo '.else {'. $something .'}';
echo '.somethingelse {'. $something  .$else '}';

...

John
fonte