有没有办法为“除第一个/最后一个元素外的所有元素”指定一个CSS简写?

时间:2020-12-09 15:40:32

Very often, it's natural to need to specify a CSS style for all elements except the first (or the last). For example, when styling paragraphs, you wish to add a bottom margin to every element except the last one (or similarly, a top margin to every element except the first one).

通常,需要为所有元素指定CSS样式是很自然的,除了第一个(或最后一个)。例如,在样式化段落时,除了最后一个元素(或者类似地,除了第一个元素之外的每个元素都要加上顶边距),您希望为每个元素添加底部边距。

Is there any way to do that that's :

有没有办法做到这一点呢?

  • more concise than defining p {...} and then p:first-child {...}?
  • 比定义p{…然后p:第一个孩子{…}?
  • more straightforward and intuitive than p:nth-child(-n+1)?
  • 比p:n -child(-n+1)更直接和直观?

If there is not, do you know of any attempt at adding it?

如果没有的话,你知道有任何添加的尝试吗?

4 个解决方案

#1


77  

For all p elements except the first child, use either one of these (the second one is better-supported):

对于除了第一个子元素之外的所有p元素,使用其中的任何一个(第二个元素更受支持):

p:not(:first-child)
p:first-child ~ p

For all p elements except the last child:

除最后一个子元素外的所有p元素:

p:not(:last-child)

For all p elements except the first and the last children:

除第一个和最后一个子元素外的所有p元素:

p:not(:first-child):not(:last-child)

As usual, CSS3's :not() and :last-child aren't supported until IE9+ and relatively new versions of other browsers. You're not going to reach very far in terms of browser support (IE8 and older) unless you add classes to your first and last children, using JavaScript or otherwise.

和往常一样,CSS3的:not()和:last-child在IE9+和其他浏览器的相对新版本之前不受支持。在浏览器支持(IE8和更老的)方面,您不会有太大的进展,除非您使用JavaScript或其他方式将类添加到您的第一个和最后一个子代中。

Remember that vertical margins collapse between in-flow paragraphs and their ancestor(s), so unless you want to zero out the margins of the container element for these paragraphs as well, you shouldn't need to zero out the margins of the first and last p elements specifically. Here's a fiddle to illustrate.

请记住,流中段落和它们的祖先段落之间的垂直边距是折叠的,所以除非您也想要为这些段落的容器元素的边距归零,否则您不应该专门为第一个和最后一个p元素的边距归零。这里有一个小提琴来说明。

#2


3  

Well, you could do:

你可以做的:

p:not(:first-child) {...}

But only the most recent browsers support the :not psuedo-class.

但是只有最近的浏览器支持:而不是psuedo类。

Other than that, no. Your best option is to specify a style for all and then override it for the first/last.

除此之外,没有。您最好的选择是指定一个样式,然后在第一个/最后指定一个样式。

#3


3  

If IE7-8 support is not needed you can use the :not() CSS selector.

如果不需要IE7-8支持,可以使用:not() CSS选择器。

But if you need to support IE7+, which may still be the case there is a little trick you can use and usually gets you fairly far. A lesser known fact is that the :first-child psuedo selector actually works in IE7+ (not :last-child though) as are some other css selectors and this makes stuff like adding vertical margins in a horizontally floated layout possible.

但是,如果你需要支持IE7+,这可能仍然是一个小技巧,你可以使用它,而且通常会让你走得更远。一个不太为人知的事实是:第一个子psuedo选择器实际上可以在IE7+(不是:last-child)和其他一些css选择器中工作,这使得在水平浮动布局中添加垂直边距成为可能。

Imagine this html:

想象一下这个html:

<ul>
    <li>Item #1</li>
    <li>Item #2</li>
    <li>Item #3</li>
    <li>Item #4</li>
</ul>

And this as some CSS:

这是一些CSS:

/* General reset */
ul, li { list-type: none; margin: 0; padding: 0; }
/* Make horizontal */
ul > li { float: left; }

So now all list items are horizontally next to each other, and now we want to add a margin in BETWEEN all items but not on the right or left side, we can do this in css:

现在所有的列表项都是水平排列的,现在我们想在所有项之间增加一个边距但不是在右边或左边,我们可以在css中这样做:

/* General reset */
ul, li { list-type: none; margin: 0; padding: 0; }
/* Make horizontal */
ul > li { float: left; margin-left: 10px; }
ul > li:first-child { margin-left: 0; }

This usually covers 95% of the cases where I want something unique, then the rest of the 'forgotten' selectors cover another few percent, after that you need to add some classes which usually isn't much of a bottleneck anyway in the backend of the page.

这通常覆盖95%的情况,我想要一些独特的东西,然后剩下的“被遗忘的”选择器覆盖了另外的几个百分点,之后你需要添加一些类,这些类通常在页面的后端并不是很大的瓶颈。

#4


2  

I would suggest to use first-of-type:

我建议使用第一类:

p:not(:first-of-type) { ... }

Browser support (caniuse)

浏览器支持(caniuse)

#1


77  

For all p elements except the first child, use either one of these (the second one is better-supported):

对于除了第一个子元素之外的所有p元素,使用其中的任何一个(第二个元素更受支持):

p:not(:first-child)
p:first-child ~ p

For all p elements except the last child:

除最后一个子元素外的所有p元素:

p:not(:last-child)

For all p elements except the first and the last children:

除第一个和最后一个子元素外的所有p元素:

p:not(:first-child):not(:last-child)

As usual, CSS3's :not() and :last-child aren't supported until IE9+ and relatively new versions of other browsers. You're not going to reach very far in terms of browser support (IE8 and older) unless you add classes to your first and last children, using JavaScript or otherwise.

和往常一样,CSS3的:not()和:last-child在IE9+和其他浏览器的相对新版本之前不受支持。在浏览器支持(IE8和更老的)方面,您不会有太大的进展,除非您使用JavaScript或其他方式将类添加到您的第一个和最后一个子代中。

Remember that vertical margins collapse between in-flow paragraphs and their ancestor(s), so unless you want to zero out the margins of the container element for these paragraphs as well, you shouldn't need to zero out the margins of the first and last p elements specifically. Here's a fiddle to illustrate.

请记住,流中段落和它们的祖先段落之间的垂直边距是折叠的,所以除非您也想要为这些段落的容器元素的边距归零,否则您不应该专门为第一个和最后一个p元素的边距归零。这里有一个小提琴来说明。

#2


3  

Well, you could do:

你可以做的:

p:not(:first-child) {...}

But only the most recent browsers support the :not psuedo-class.

但是只有最近的浏览器支持:而不是psuedo类。

Other than that, no. Your best option is to specify a style for all and then override it for the first/last.

除此之外,没有。您最好的选择是指定一个样式,然后在第一个/最后指定一个样式。

#3


3  

If IE7-8 support is not needed you can use the :not() CSS selector.

如果不需要IE7-8支持,可以使用:not() CSS选择器。

But if you need to support IE7+, which may still be the case there is a little trick you can use and usually gets you fairly far. A lesser known fact is that the :first-child psuedo selector actually works in IE7+ (not :last-child though) as are some other css selectors and this makes stuff like adding vertical margins in a horizontally floated layout possible.

但是,如果你需要支持IE7+,这可能仍然是一个小技巧,你可以使用它,而且通常会让你走得更远。一个不太为人知的事实是:第一个子psuedo选择器实际上可以在IE7+(不是:last-child)和其他一些css选择器中工作,这使得在水平浮动布局中添加垂直边距成为可能。

Imagine this html:

想象一下这个html:

<ul>
    <li>Item #1</li>
    <li>Item #2</li>
    <li>Item #3</li>
    <li>Item #4</li>
</ul>

And this as some CSS:

这是一些CSS:

/* General reset */
ul, li { list-type: none; margin: 0; padding: 0; }
/* Make horizontal */
ul > li { float: left; }

So now all list items are horizontally next to each other, and now we want to add a margin in BETWEEN all items but not on the right or left side, we can do this in css:

现在所有的列表项都是水平排列的,现在我们想在所有项之间增加一个边距但不是在右边或左边,我们可以在css中这样做:

/* General reset */
ul, li { list-type: none; margin: 0; padding: 0; }
/* Make horizontal */
ul > li { float: left; margin-left: 10px; }
ul > li:first-child { margin-left: 0; }

This usually covers 95% of the cases where I want something unique, then the rest of the 'forgotten' selectors cover another few percent, after that you need to add some classes which usually isn't much of a bottleneck anyway in the backend of the page.

这通常覆盖95%的情况,我想要一些独特的东西,然后剩下的“被遗忘的”选择器覆盖了另外的几个百分点,之后你需要添加一些类,这些类通常在页面的后端并不是很大的瓶颈。

#4


2  

I would suggest to use first-of-type:

我建议使用第一类:

p:not(:first-of-type) { ... }

Browser support (caniuse)

浏览器支持(caniuse)