css :nth-child(an+b)

2016-08-09 17:28:26 搞明白css :nth-child(an+b)的意义,解决一个问题::nth-child(an+b)中的an+b的理解方式。

就解决一个问题:
:nth-child(an+b)中的an+b的理解方式。

css3中nth-child这个伪类选择器,我觉得挺强大的。
比如选择父元素下的第5个子元素(家里排行老5):

  1. <style> 
  2. li:nth-child(5){ 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

此选择器的强大在于不仅选定父元素下一个特定位置的子元素,而且还能选择一批元素。
比如选择所有奇数位的元素:

  1. <style> 
  2. li:nth-child(2n+1){ 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

其中公式an+b用的2n+1,鉴于很多同学这种方式不太理解。
下面我就来说说这个事情,公式、公式就是算术!

我们先来看,
公式:nth-child(n)
示例如下:

  1. <style> 
  2. li:nth-child(n){ 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

公式n,表示选择所有子元素。
把n看作是一个集合,匹配第0,1,2,...个元素。
n是自然数,从零开始。当然,第0个元素是不存在的。

那么公式n+1呢?
每个自然数都加1,因此变成:
1,2,3,...
自然也是所有子元素:

  1. <style> 
  2. li:nth-child(n+1){ 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

公式n-100呢?
1,2,3,...,100,101,102,...分别减去100,变成
-99,-98,-97,...,0,1,2,...前面100个数都是非正数,对应的子元素不存在,但仍然包括自然数,因此匹配的也是所有子元素:

  1. <style> 
  2. li:nth-child(n-100){ 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

那么,公式3n+2匹配的是什么?
把自然数集合
0,1,2,3,4,...
变成了
2,5,8,11,14...
示例如下:

  1. <style> 
  2. li:nth-child(3n+2){ 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

这么理解是没问题的。
比如我要匹配从第7个元素开始到往后:
公式n+7
因为n+7这个集合是:
7,8,9,...

  1. <style> 
  2. li:nth-child(n+7){ 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

问题又来了,我要匹配前7个元素怎么弄:
-n+7
把自然数集合
0,1,2,3,4,5,6,7,8,9...
变成了
7,6,5,4,3,2,1,0,-1,-2,...

  1. <style> 
  2. li:nth-child(-n+7){ 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

这回看明白了吧,an+b,a是负数没啥不好理解的。
再来一个
公式-3n+20
把自然数集合
0,1,2,3,4,5,6,7...
变成了
20,17,14,11,8,5,2,-1...

  1. <style> 
  2. li:nth-child(-3n+20){ 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

nth-child是从头数到尾部的,
还有另一个相似的选择器nth-last-child,
是从尾部数到头的,数的方向不一样,原理是一样的。
因此匹配后三个元素的:
公式:nth-last-child(-n+3)
示例如下:

  1. <style> 
  2. li:nth-last-child(-n+3){ 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

最后再来一个demo,看代码后面的look here!那块儿。。。

  1. <meta charset="utf-8"> 
  2. <style> 
  3. ul{ 
  4. list-style:none; 
  5. font-family:'Microsoft YaHei'; 
  6. ul li a { 
  7. display: inline-block; 
  8. padding-left: 25px; 
  9. height: 30px; 
  10. line-height: 30px; 
  11. overflow: hidden; 
  12. position: relative; 
  13. text-decoration: none; 
  14. color:#333333; 
  15. ul li a:hover{ 
  16. color: #3498db; 
  17. text-decoration: underline; 
  18. ul li a i{ 
  19. display: block; 
  20. top: 5px; 
  21. left: 0; 
  22. width: 18px; 
  23. height: 18px; 
  24. line-height: 16px; 
  25. color: #aab2bd; 
  26. text-align: center; 
  27. font-style:normal; 
  28. font-size: 12px; 
  29. border: 1px #aab2bd solid; 
  30. border-radius: 50%; 
  31. position: absolute; 
  32.  
  33. /*look here!*/ 
  34. ul li:nth-child(-n+3) a i{ 
  35. color: #3498db; 
  36. border-color: #3498db; 
  37. </style> 
  38. <ul> 
  39. <li><a href="javascript:"><i>1</i>彻底搞明白:nth-child(an+b)的意义</a></li> 
  40. <li><a href="javascript:"><i>2</i>彻底搞明白:nth-child(an+b)的意义</a></li> 
  41. <li><a href="javascript:"><i>3</i>彻底搞明白:nth-child(an+b)的意义</a></li> 
  42. <li><a href="javascript:"><i>4</i>彻底搞明白:nth-child(an+b)的意义</a></li> 
  43. <li><a href="javascript:"><i>5</i>彻底搞明白:nth-child(an+b)的意义</a></li> 
  44. <li><a href="javascript:"><i>6</i>彻底搞明白:nth-child(an+b)的意义</a></li> 
  45. <li><a href="javascript:"><i>7</i>彻底搞明白:nth-child(an+b)的意义</a></li> 
  46. <li><a href="javascript:"><i>8</i>彻底搞明白:nth-child(an+b)的意义</a></li> 
  47. <li><a href="javascript:"><i>9</i>彻底搞明白:nth-child(an+b)的意义</a></li> 
  48. <li><a href="javascript:"><i>10</i>彻底搞明白:nth-child(an+b)的意义</a></li> 
  49. </ul> 

集合怎么求交集、并集、补集问题。
先研究并集,这个比较简单。
比如我要匹配3n+1的情形,我们知道效果如下:

  1. <style> 
  2. li:nth-child(3n+1){ 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

如果我还想匹配3n+2呢?即集合3n+1和3n+2的并集。
此时我们用组合选择器来实现

  1. <style> 
  2. li:nth-child(3n+1), 
  3. li:nth-child(3n+2) 
  4. color:red; 
  5. </style> 
  6. <ul> 
  7. <li>xxx1</li> 
  8. <li>xxx2</li> 
  9. <li>xxx3</li> 
  10. <li>xxx4</li> 
  11. <li>xxx5</li> 
  12. <li>xxx6</li> 
  13. <li>xxx7</li> 
  14. <li>xxx8</li> 
  15. <li>xxx9</li> 
  16. <li>xxx10</li> 
  17. <li>xxx11</li> 
  18. <li>xxx12</li> 
  19. </ul> 

并集功能很简单就解决了,我们来看看补集。
比如我要实现n+7的补集。
先看看n+7是什么效果:

  1. <style> 
  2. li:nth-child(n+7) 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

其补集就是匹配前6个元素,
通过上篇文章我们知道可以用-n+6来实现

  1. <style> 
  2. li:nth-child(-n+6) 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

然而这种方式不够优雅,
有没有更好的呢?有,强大的:not选择器:

  1. <style> 
  2. li:not(:nth-child(n+7)) 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

因此针对3n+1和3n+2的并集,我们可以取3n的补集来做到。

  1. <style> 
  2. li:not(:nth-child(3n)) 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

最后一个问题才是本文的核心,怎么求交集。
建设我们选择小于10的偶数?
通过上篇文章我们知道可以使用-2n+10来做到

  1. <style> 
  2. li:nth-child(-2n+10) 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

上面其实来说不算优雅的方案,
匹配小于10的元素我们知道是-n+10,
匹配偶数的元素是2n,我们希望直接求出交集,
怎么来实现:

  1. <style> 
  2. li:nth-child(-n+10):nth-child(2n) 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

看到了吗
:nth-child(-n+10):nth-child(2n)
因此匹配3到7的元素怎么做呢?
大于等于3的使用nth-child(n+3),
小于等于7的使用nth-child(-n+7)
因此是:nth-child(n+3):nth-child(-n+7)

  1. <style> 
  2. li:nth-child(n+3):nth-child(-n+7) 
  3. color:red; 
  4. </style> 
  5. <ul> 
  6. <li>xxx1</li> 
  7. <li>xxx2</li> 
  8. <li>xxx3</li> 
  9. <li>xxx4</li> 
  10. <li>xxx5</li> 
  11. <li>xxx6</li> 
  12. <li>xxx7</li> 
  13. <li>xxx8</li> 
  14. <li>xxx9</li> 
  15. <li>xxx10</li> 
  16. <li>xxx11</li> 
  17. <li>xxx12</li> 
  18. </ul> 

至此交并补都已经讲完。
最后来复合的例子
匹配45、89怎么做?
48可以用4n来做,
59可以用4n+1来做,
因为二者在4到9之间,可以n+4和-n+9的交集来做,
当然也有其他的解决方案,比如4、5、8、9的并集。
为了凸显逼格,我决定要把交并补都用上:

  1. <style> 
  2. li:nth-child(4n):not(:nth-child(n+10)), 
  3. li:nth-child(4n+1):not(:nth-child(n+10)):not(:nth-child(1)) 
  4. color:red; 
  5. </style> 
  6. <ul> 
  7. <li>xxx1</li> 
  8. <li>xxx2</li> 
  9. <li>xxx3</li> 
  10. <li>xxx4</li> 
  11. <li>xxx5</li> 
  12. <li>xxx6</li> 
  13. <li>xxx7</li> 
  14. <li>xxx8</li> 
  15. <li>xxx9</li> 
  16. <li>xxx10</li> 
  17. <li>xxx11</li> 
  18. <li>xxx12</li> 
  19. </ul> 

完成!整理来自——前端网

更新