ChatGPT解决这个技术问题 Extra ChatGPT

CSS 类可以继承一个或多个其他类吗?

css

是否可以创建一个从另一个 CSS 类(或多个)“继承”的 CSS 类。

例如,假设我们有:

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

我想做的是这样的:

.composite 
{
   .something;
   .else
}

其中“.composite”类将同时显示内联并具有红色背景

多考虑级联而不是继承,这里不适用

C
CoderPi

有像 LESS 这样的工具,可以让您以类似于您所描述的更高抽象级别来编写 CSS。

Less 称这些为“mixins”

代替

/* 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;
}

你可以说

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

#header {
  .rounded_corners;
}

#footer {
  .rounded_corners;
}

哇,LESS 几乎正是我正在寻找的......很遗憾它本身不受支持,而且它是用 Ruby 编写的(我使用的是 ASP.NET MVC)
是的,我也在 ASP.NET 世界中,所以我还没有将它转移到我的生产工作流程中。
是的,LESS 很甜,不是吗。我实际上一直在开发 .NET 端口:nlesscss.codeplex.com
如果您通过 google 到达:.Net 端口现在是 here
您可以使用 SCSS/SASS: sass-lang.com/guide 而不是 LESS。例如,喜欢答案: stackoverflow.com/a/22770378/1742529
k
kxr

您可以将多个类添加到单个 DOM 元素,例如

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

后面的类(或更具体的)中给出的规则会覆盖。因此,该示例中的 fourthclass 占了上风。

继承不是 CSS 标准的一部分。


你知道哪个类占上风,最后一个还是第一个,跨浏览器的行为是否安全?假设我们有 .firstClass {font-size:12px;} .secondClass {font-size:20px;},那么最终的 font-size 将是 12px20px,这个跨浏览器安全吗?
选择器上具有最高特异性的规则将获胜。适用标准特异性规则;在您的示例中,由于“第一”和“第二”具有相同的特异性,因此稍后在 CSS 中声明的规则将获胜。
我喜欢使用纯 CSS(而不是 LESS)来解决这个问题的想法。
我也喜欢不多次输入多个类的想法 - 这是 O(n^2) 工作:)
如果我使用第三方库并想修改它提供的设计/HTML,但无法更改该库中的内置 css 文件怎么办?在那里,我需要在 css 类中进行某种继承。
C
CoderPi

是的,但不完全符合那种语法。

.composite,
.something { display:inline }

.composite,
.else      { background:red }

这很糟糕,但我很高兴我们至少有这个!
为什么很烂?看起来很好。我无法理解逗号符号和 less.js 解决方案之间的区别。
因为如果 .something 和 .else 类位于不同的文件中并且您无法修改它们,那么您就会陷入困境。
这是正确的答案,因为它使用纯 CSS 语法回答了这个问题。不过,答案越少越好。
这个解决方案的其他缺点,虽然它作为一个谜题解决方案非常好,但漏洞 CSS 代码可能很快变得难以处理,因为我们无法在逻辑上组织类,例如我们希望将 .else 和 .something 的定义放入其他 CSS 定义组中.
C
CoderPi

将您的共同属性放在一起并再次分配特定(或覆盖)属性。

/*  ------------------------------------------------------------------------------ */   
/*  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;
}

这非常接近一个理想的解决方案,我希望人们不会因为它获得的票数很少而放弃它。事实上,关于“CSS 继承”的最具挑战性的问题之一是,您通常会得到一个已经制作好的、巨大的 Web 软件(例如,一个电子商务或博客 PHP 著名的软件),并且它们使用原生的 PHP 代码。 t 向它们输出的 HTML 元素添加多个类。这会迫使您四处乱转并弄乱源代码(如果稍后升级,则会丢失更改)以使其输出那些附加类。相反,使用这种方法,您只需要编辑 CSS 文件!
这正是我想要的。这种相同的方法适用于 CSS 选择器是否毫无价值?您可以指定 .selector1, .selector2, .etc 而不是指定 h1, h2, etc
我想评论一下,这正是 w3 在他们推荐的默认 html 样式表中使用的方法:[w3 CSS2]: w3.org/TR/CSS2/sample.html。我还试图掌握如何组织 css 代码,与典型的面向对象继承相比,范式似乎是颠倒的:您使用类(或更一般地选择器)来指定哪些元素继承哪些属性,但是您继承属性(至少,这是层次结构在逻辑上最容易存在的方式),然后在必要时在更具体的选择器处覆盖属性。
仅供参考:这是使用元素选择器的普通 CSS,它不使用单个 CSS 类。我不想粗鲁,但仅供参考,我对这个答案的阅读不应该被称为类继承的例子。如果目标是教授基本的 CSS 原则,我会投赞成票,但这不是 OP 问题的答案,所以投反对票。
这不是像 Bootstrap 这样的库的构建方式,而且不存在的 CSS mixin 似乎是扩展 Bootstrap 类以始终包含另一个 Bootstrap 类的属性的唯一方法,因此所有“类”属性贯穿始终不必更改网站。
P
Pete

一个元素可以采用多个类:

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

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

不幸的是,这与您将要得到的差不多。我希望有一天能看到这个功能以及类别名。


C
CoderPi

不,你不能做类似的事情

.composite 
{
   .something;
   .else
}

这不是面向对象意义上的“类”名称。 .something.else 只是选择器而已。

但是您可以在一个元素上指定两个类

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

或者你可能会研究另一种形式的继承

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

段落背景颜色和颜色是从 .foo 样式的封闭 div 中的设置继承的。您可能必须检查确切的 W3C 规范。 inherit 是大多数属性的默认值,但不是所有属性。


是的,这(第一部分)是我在 20 世纪第一次听说 CSS 时的期望......我们仍然没有它,它们在一些动态的东西上燃烧性能,而这可以在 css 应用之前是静态组合的它取代了对变量的需求(静态“变量”)
I
Igor Ivancha

给定示例的 SCSS 方式类似于:

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

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

更多信息,请查看sass basics


与此相比,附加值是多少? .composite,.something { display:inline }.composite,.else { background:red }
@PavelGatnar 您可以在另一个 css 定义中重用 .something.else 的定义。
D
DHoover

我遇到了同样的问题,最终使用了一个 JQuery 解决方案来使一个类看起来可以继承其他类。

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

这将找到所有具有“复合”类的元素,并将“某物”和“其他”类添加到元素中。所以像 <div class="composite">...</div> 这样的东西最终会像这样:
<div class="composite something else">...</div>


此解决方案的问题在于适用于所有现有控件,如果您在此调用之后创建控件,它将没有新类。
T
Tomer W

你能做的就是这个

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>

C
CoderPi

不要忘记:

div.something.else {

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

}

我不是在寻找它,但这对我来说是建设性的 n__n
C
CoderPi

完美时机:我从这个问题转到我的电子邮件,找到一篇关于 Less 的文章,这是一个 Ruby 库,其中包括:

因为 super 看起来就像 footer,但是使用了不同的字体,我将使用 Less 的类包含技术(他们称之为 mixin)来告诉它也包含这些声明:

#super {
  #footer;
  font-family: cursive;
}

就在我认为 LESS 不能再让我感到惊讶的时候......我不知道你可以从这样的另一个块导入格式。很棒的小费。
C
CoderPi

在 Css 文件中:

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

p.SubTitle p.Title
{
   font-size: 12px;
}

那么产生的 font-size 会是什么?
“p.Title”的字体大小为 12px,因为它是在文件中的第一个字体之后定义的。它覆盖了第一个字体大小。
@YWE:这是否意味着声明实际上应该与此答案中所写的内容相反(至少如果我们想举例说明)?如果最后一个定义占上风,font-size: 16px永远不会生效,对吧?
@ORMapper - 通常发生的情况是第一个声明位于一个公共 css 文件中,由多个页面共享。然后第二个声明位于第二个 css 文件中,仅在某些页面上使用。并在 之后导入通用 css 文件。因此,这些页面使用 12px 的“最后一次看到”值。
J
John Carrell

我意识到这个问题现在已经很老了,但是,这里什么都没有!

如果打算添加一个包含多个类的属性的类,作为本机解决方案,我建议使用 JavaScript/jQuery(jQuery 确实不是必需的,但肯定有用)

例如,如果您有从 .baseClass1.baseClass2“继承”的 .umbrellaClass,那么您可以准备好一些可以触发的 JavaScript。

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

现在 .umbrellaClass 的所有元素都将具有两个 .baseClass 的所有属性。请注意,与 OOP 继承一样,.umbrellaClass 可能有也可能没有自己的属性。

这里唯一需要注意的是考虑是否有动态创建的元素在此代码触发时不存在,但也有一些简单的方法可以解决这个问题。

不过,Sucks css 没有原生继承。


从 2013 年开始,@DHoover 的 answer 中已经提出了这种方法。
需要纯 JavaScript 代码。可以从库样式表中定位和提取类规则,并将它们附加到另一个库或自定义样式表或规则中,但是 Web 上似乎没有示例,并且正确执行此操作的代码有点复杂。经过大约一个小时的工作,我无法设计一个合并班级规则的功能。
C
CSSBurner

您可以使用 converse 方法来获得相同的结果 - 从复合开始,然后使用 unset 关键字删除样式。例如,如果您从以下示例组合开始:

.composite {
    color: red;
    margin-left: 50px;
    background-color: green
}

然后,您可以使用 unset 增加选择器 specificity 以选择性地删除 样式:

.composite.no-color {
    color: unset
}

.composite.no-margin-left {
    margin-left: unset
}

.composite.no-background-color {
    background-color: unset
}

a JSFiddle 演示了这种方法。

这种方法的一个好处是,因为复合选择器的 specificity 高于复合选择器本身,所以您不需要所有的类组合来实现多个组合所需的结果:

/* Multi-unset compound selector combinations, such as the one that follows, ARE NOT NECESSARY because of the higher specificity of each individual compound selectors listed above. This keeps things simple. */
.composite.no-background-color.no-color.no-margin-left {
    background-color: unset;
    color: unset;
    margin-left: unset
}

此外,在 unset 关键字的 96% support 处,浏览器覆盖率非常好。


我认为这是迄今为止最好的答案。可以改进在开头指定元素类型,例如 div.composite.no-background-color.no-color.no-margin-left {...}
L
LBushkin

不幸的是,CSS 没有像 C++、C# 或 Java 这样的编程语言那样提供“继承”。你不能声明一个 CSS 类,然后用另一个 CSS 类扩展它。

但是,您可以将多个类应用于标记中的标记......在这种情况下,有一组复杂的规则可以确定浏览器将应用哪些实际样式。

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

CSS 将根据您的标记查找可以应用的所有样式,并将来自多个规则的 CSS 样式组合在一起。

通常,样式会被合并,但是当发生冲突时,后面声明的样式通常会胜出(除非在其中一个样式上指定了 !important 属性,在这种情况下会胜出)。此外,直接应用于 HTML 元素的样式优先于 CSS 类样式。


您的回答对我来说是谷歌上的第一个结果,并且很有帮助。也就是说,我有一个提示给你——如果你要提供一个解决方案,最好避免消极地开始句子(不幸的是,CSS 不提供继承..)我知道任何有耐心的人都会继续阅读以发现你的好解决方案但有时人们缺乏耐心,可能会匆忙得出结论,认为他们试图做的事情是不可能的。为了获得帮助他人的最佳机会,您可以从“虽然 CSS 没有继承性,但您可以通过...实现您需要的东西”之类的内容开始。
N
Nathan Chappell

不要将 css 类视为面向对象的类,将它们仅视为其他选择器中的一种工具,用于指定 html 元素的样式所依据的属性类。将大括号之间的所有内容视为属性类,左侧的选择器告诉他们选择的元素从属性类继承属性。例子:

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

当一个元素被赋予属性 class="foo" 时,将其视为不是从类 .foo 继承的属性,而是从 属性类 A属性类 B。即,继承图是一层深度,元素来自属性类,选择器指定边的位置,并在存在竞争属性时确定优先级(类似于方法解析顺序)。

https://i.stack.imgur.com/GyXys.png

编程的实际含义是这样的。假设您有上面给出的样式表,并且想要添加一个新类 .baz,它应该具有与 .foo 相同的 font-size。天真的解决方案是这样的:

.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! */}

https://i.stack.imgur.com/iHIFf.png

每当我必须输入两次内容时,我都会很生气!我不仅要写两次,而且现在我无法以编程方式指示 .foo.baz 应该具有相同的 font-size,而且我创建了一个隐藏的依赖关系!我的上述范例建议我应该从 attribute class A 中抽象出 font-size 属性:

.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 */}

https://i.stack.imgur.com/27RKo.png

这里的主要抱怨是,现在我必须再次从属性类 A 重新键入每个选择器,以指定他们应该选择的元素也应该从属性基类 A 继承属性。不过,替代方法是必须记住编辑每个属性类每次发生变化或使用第三方工具时都有隐藏的依赖项。第一个选项让上帝发笑,第二个让我想自杀。


C
CoderPi

这在 CSS 中是不可能的。

CSS 中唯一支持的是比其他规则更具体:

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

具有“myclass”类的跨度将具有这两个属性。

另一种方法是指定两个类:

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

“else”的样式将覆盖(或添加)“something”的样式


对于 1 个文件中的所有样式,CSS 中有一个类似继承的解决方案,请参阅我的帖子。
A
Assaf Lavie

正如其他人所说,您可以向一个元素添加多个类。

但这不是重点。我得到你关于继承的问题。真正的一点是,CSS 中的继承不是通过类完成的,而是通过元素层次结构完成的。因此,要对继承的特征进行建模,您需要将它们应用于 DOM 中不同级别的元素。


最好创建类似继承的 CSS 定义,而不是使用所有组合类链,请参阅我的帖子。
S
Stryderunknown

虽然直接继承是不可能的。

可以为父标签使用类(或 id),然后使用 CSS 组合器从其层次结构中改变子标签的行为。

p.test{背景颜色:rgba(55,55,55,0.1);} p.test > span{背景颜色:rgba(55,55,55,0.1);} p.test > span > span{背景颜色:rgba(55,55,55,0.1);} p.test > span > span > span{背景颜色:rgba(55,55,55,0.1);} p.test > span > span >跨度>跨度{背景颜色:rgba(55,55,55,0.1);} p.test>跨度>跨度>跨度>跨度>跨度{背景颜色: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{背景色:rgba(55,55,55,0.1);} p.test > 跨度 > 跨度 > 跨度 > 跨度 > 跨度 > 跨度 > 跨度{背景色:rgba(55,55,55,0.1) ;}

一个可能的解决方案使用多个嵌套标签

我不建议像这个例子那样使用这么多跨度,但这只是一个概念证明。尝试以这种方式应用 CSS 时仍然会出现许多错误。 (例如更改文本装饰类型)。


C
CoderPi

我也在疯狂地寻找它,我只是通过尝试不同的东西来解决这个问题:P......好吧,你可以这样做:

composite.something, composite.else
{
    blblalba
}

它突然对我有用:)


如果某些类位于固定库文件中,则不起作用。
h
hydrix

在特定情况下,您可以进行“软”继承:

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

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

这仅在您将 .composite 类添加到子元素时才有效。这是“软”继承,因为 .composite 中未指定的任何值都不会明显继承。请记住,简单地写“内联”和“红色”而不是“继承”仍然会更少字符。

以下是属性列表以及它们是否自动执行此操作:https://www.w3.org/TR/CSS21/propidx.html


N
Nesha Zoric

Less 和 Sass 是 CSS 预处理器,它们以有价值的方式扩展了 CSS 语言。他们提供的众多改进之一就是您正在寻找的选项。 Less 有一些非常好的答案,我将添加 Sass 解决方案。

Sass 有扩展选项,它允许一个类完全扩展到另一个类。有关扩展的更多信息,您可以阅读in this article


C
Community

实际上你所要求的存在 - 但是它是作为附加模块完成的。在 Better CSS in .NET 上查看此问题以获取示例。

查看 Larsenal's answer on using LESS 了解这些插件的作用。


Z
Zack The Human

CSS 并没有真正你所要求的。如果您想根据这种复合想法编写规则,您可能需要查看 compass。这是一个样式表框架,看起来类似于已经提到的 Less。

它可以让你做 mixins 和所有的好生意。


在上面添加更多详细信息,Compass aka Sass 通过扩展、PlaceHolders Mixins vs Extend 以及有关 PlaceHolders 的更多详细信息
S
Shakir

对于那些对提到的(优秀的)帖子不满意的人,您可以使用您的编程技能制作一个变量(PHP 或其他)并让它存储多个类名。

这是我能想出的最好的技巧。

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

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

然后将全局变量应用于您想要的元素而不是类名本身

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

B
Benjam

查看 CSS composehttps://bambielli.com/til/2017-08-11-css-modules-composes/

根据他们:

.serif-font {
    font-family: Georgia, serif;
}

.display {
    composes: serif-font;
    font-size: 30px;
    line-height: 35px;
}

我在我的反应项目中使用它。


m
miquelvir

我认为这是一个更好的解决方案:

[class*=“button-“] {
  /* base button properties */
}
.button-primary { ... }
.button-plain { ... }

coderwall.com/p/lqjd1w/css-class-inheritance-in-css 上有关此技术的更多信息。那里的评论批评了性能。关于性能影响的任何好的博客文章? (欢迎好或坏。)我的用户群主要是桌面(80%)和一些高端手机(5%)和 iPad(5%),所以如果桌面浏览器的性能“OK”,我可能会坚持使用这种方法过度采用 LESS/SASS 进行 CSS 类继承。
B
BloDoe

如果您想要一个比 LESS 更强大的文本预处理器,请查看 PPWizard:

http://dennisbareis.com/ppwizard.htm

警告该网站真的很可怕,而且学习曲线很小,但它非常适合通过宏构建 CSS 和 HTML 代码。我一直不明白为什么更多的网络编码人员不使用它。


这个网站真的很可怕。
对于 html 处理器的网站有点讽刺!
是的,这个网站很可怕,但不仅如此。很难读,也让我头疼!
好在它兼容 windows 3.1 到 XP,哈哈
一个奇怪的非标准工具,不喜欢。
j
john

如果你通过 php 预处理你的 .css 文件,你可以实现你想要的。 ...

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

...