如何在循环输出列表项时交替应用不同的CSS类或样式?

在网站设计中,为了提升视觉美观度和用户体验,我们经常会遇到需要对列表项(如文章列表、产品列表、导航菜单等)交替应用不同CSS类或样式的情境。例如,让奇数行和偶数行背景色不同,或者每隔几项应用一种独特的布局样式。安企CMS(AnQiCMS)凭借其灵活的模板引擎,提供了多种简洁高效的方法来实现这一需求。

安企CMS采用类似Django模板引擎的语法,在循环处理数据时,我们可以轻松地利用内置的循环变量和标签来控制列表项的样式。核心在于利用循环过程中项的序号,通过条件判断或特定标签来分配不同的CSS类。

核心功能:for 循环与 forloop.Counter

在安企CMS的模板中,当我们使用 {% for item in items %} 这样的结构遍历列表数据时,模板引擎会自动提供一些特殊的循环变量,其中最常用且对样式交替至关重要的就是 forloop.Counter

forloop.Counter 表示当前循环的序号,它从 1 开始递增。这意味着在循环的第一项,forloop.Counter 的值为 1;第二项为 2,以此类推。利用这个特性,我们便能实现各种复杂的样式交替逻辑。

方法一:利用 cycle 标签高效交替CSS类

cycle 标签是安企CMS模板中实现样式交替最直接、最优雅的方式之一。它可以在每次循环中按顺序输出预定义的字符串列表,当列表用尽时会自动循环回到第一个。这非常适合用于奇偶行样式或按固定模式循环多种样式。

实现奇偶行交替样式:

假设我们希望列表项的奇数行使用 odd-row 类,偶数行使用 even-row 类。

{# 假设 archives 是通过 {% archiveList archives ... %} 获取的文档列表 #}
<ul class="article-list">
    {% for item in archives %}
    <li class="{% cycle 'odd-row' 'even-row' %}">
        <a href="{{ item.Link }}">{{ item.Title }}</a>
        <p>{{ item.Description }}</p>
    </li>
    {% endfor %}
</ul>

对应的CSS样式可以这样定义:

.odd-row {
    background-color: #f9f9f9;
    border-left: 3px solid #007bff;
}
.even-row {
    background-color: #ffffff;
    border-left: 3px solid #6c757d;
}

实现多类(N种样式)循环:

如果我们需要循环应用三种或更多种不同的CSS类,cycle 标签同样适用。

<ul class="product-grid">
    {% for item in products %}
    <li class="product-item {% cycle 'style-one' 'style-two' 'style-three' %}">
        <img src="{{ item.Thumb }}" alt="{{ item.Title }}">
        <h3>{{ item.Title }}</h3>
        <p>价格: {{ item.Price }}</p>
    </li>
    {% endfor %}
</ul>

对应的CSS样式:

.product-item.style-one {
    background-color: #e0ffe0;
    border: 1px solid #28a745;
}
.product-item.style-two {
    background-color: #e0e0ff;
    border: 1px solid #007bff;
}
.product-item.style-three {
    background-color: #fffde0;
    border: 1px solid #ffc107;
}

方法二:使用 forloop.Counter 进行条件判断(奇偶样式)

虽然 cycle 标签更简洁,但有时我们可能需要基于明确的条件进行判断,尤其是在不只是简单循环交替,而是当某个条件成立时应用特定样式。最常见的场景是判断奇偶数。

<div class="category-items">
    {% for item in categories %}
    <div class="category-card {% if forloop.Counter % 2 == 1 %}is-odd{% else %}is-even{% endif %}">
        <h4><a href="{{ item.Link }}">{{ item.Title }}</a></h4>
        <p>{{ item.Description }}</p>
    </div>
    {% endfor %}
</div>

对应的CSS样式:

.category-card.is-odd {
    background-color: #f0f8ff;
}
.category-card.is-even {
    background-color: #f8f8f8;
}

方法三:基于 forloop.Counter 生成递增的定制类名

在某些设计中,我们可能需要为列表中的每一项生成一个基于其序号的独特类名,例如 item-1, item-2, item-3 等。这在需要针对特定位置的项进行精细控制时非常有用。

<ol class="ordered-list">
    {% for item in navigation %}
    <li class="list-item-{{ forloop.Counter }}">
        <a href="{{ item.Link }}">{{ item.Title }}</a>
    </li>
    {% endfor %}
</ol>

对应的CSS样式:

.ordered-list li {
    padding: 10px;
    margin-bottom: 5px;
}
.ordered-list .list-item-1 {
    font-weight: bold;
    color: #dc3545;
}
.ordered-list .list-item-3 {
    border-bottom: 1px dashed #cccccc;
}
/* 甚至可以结合伪类实现更多效果 */
.ordered-list .list-item-{{ forloop.Counter }}:hover {
    background-color: #e9ecef;
}

方法四:高级条件判断,实现更多样式的复杂循环

当交替逻辑不仅仅是简单的奇偶或循环几种固定样式,而是基于特定序号(例如每第3项、第5项有特殊样式)时,forloop.Counter 的条件判断能力便能发挥作用。

<div class="gallery">
    {% for image in gallery_images %}
    <div class="gallery-item
        {% if forloop.Counter == 1 %}first-item{% endif %}
        {% if forloop.Counter % 4 == 0 %}last-in-row{% endif %}
        {% if forloop.Counter > 5 and forloop.Counter < 10 %}highlighted{% endif %}">
        <img src="{{ image.src }}" alt="{{ image.alt }}">
        <p>{{ image.caption }}</p>
    </div>
    {% endfor %}
</div>

对应的CSS样式可以这样定义:

.gallery-item {
    float: left;
    width: 24%; /* 假设每行4个 */
    margin-right: 1%;
    margin-bottom: 15px;
    box-sizing: border-box;
    border: 1px solid #eee;
}
.gallery-item.first-item {
    background-color: #ffeb3b;
    border-color: #ff9800;
}
.gallery-item.last-in-row {
    margin-right: 0; /* 清除每行最后一个的右边距 */
}
.gallery-item.highlighted {
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}

实用技巧与建议

  • 语义化类名: 尽量使用描述样式用途而非具体视觉效果的类名(例如 featured-item