Angular结合CSS实现列表奇偶行异色时所有行均为灰色的问题
问题原因
你当前样式不生效的核心原因是:nth-child选择器是相对于当前元素的直接父元素计数的:
- 父组件中
*ngFor循环生成了一层div,每个div内部只放了一个<app-event-item>组件 - 每个子组件内部只有一个带
.list-view类的根节点,这个节点在自己的直接父容器(也就是<app-event-item>宿主元素)里永远是第1位,属于奇数位,所以所有行都会匹配你写的:nth-child(odd)规则,全部渲染成灰色。
修复方案
推荐用第一种方案,符合Angular组件单向数据流的设计,不需要处理样式隔离问题:
方案1:通过输入属性传递行奇偶状态
- 修改父组件模板,在
*ngFor中导出奇偶标识,传给子组件:
<div class="list-view"> <div *ngFor="let event of allEvents; let isOdd = odd"> <app-event-item [eventsList]="event" [isOddRow]="isOdd" ></app-event-item> </div> </div>
- 子组件中新增输入属性接收标识:
// 子组件ts文件中 @Input() isOddRow: boolean = false;
- 修改子组件模板,给根节点动态绑定样式类:
<div class="list-view" [class.odd-row]="isOddRow"> <img [src]="imageUrl" /> <div class="about"> <h4> <a>{{ eventsList.title }}</a> </h4> </div> <div class="date"> <p>{{ eventsList.date }}</p> </div> <div class="count"> <p>{{ eventsList.count }}</p> </div> </div>
- 修改子组件样式,替换原有
:nth-child规则为类选择器:
.list-view { display: grid; grid-template-columns: 300px 45% 1fr 1fr; align-items: center; height: 100px; img { max-height: 100%; max-width: 100%; object-fit: cover; border-radius: 0.75rem; } .about-event { padding-left: 1rem; } } .odd-row { background-color: #F9F9F9; }
方案2:父组件直接通过选择器控制(适合不想改子组件逻辑的场景)
- 去掉
*ngFor外层多余的包裹div,直接在子组件标签上循环:
<div class="list-view"> <app-event-item *ngFor="let event of allEvents" [eventsList]="event" ></app-event-item> </div>
- 在父组件样式中用
::ng-deep穿透样式隔离,直接匹配奇偶位置的子组件内部节点:
.list-view { display: flex; flex-direction: column; } /* 奇数行背景色 */ .list-view app-event-item:nth-child(odd) ::ng-deep .list-view { background-color: #F9F9F9; } /* 偶数行背景色,需要自定义其他颜色可以在这里加 */ .list-view app-event-item:nth-child(even) ::ng-deep .list-view { background-color: #ffffff; }
这种写法不需要修改子组件的ts和模板代码,但是要注意::ng-deep在Angular未来版本中可能被废弃,长期维护更推荐方案1。
内容的提问来源于stack exchange,提问作者devZ
相关产品推荐
相关产品推荐

