Bootstrap 4.0 动态网站每行响应卡片数

Bootstrap 4.0 Responsive Number of Cards Per Row For Dynamic Website

我有一个有趣的问题。我在 UI.

上使用 razor 语法在我的 .Net 5.0 应用程序中动态创建 Bootstrap 卡片

每第 5 张卡片创建一个新行,所以我有 4 张卡片水平对齐用户可见。

在大多数屏幕尺寸上都可以正常工作。有 4 张卡片,或者在较小的屏幕上可以看到 1 或 2 张水平对齐的卡片。

问题出在中等屏幕上,当它对于连续 4 张卡片来说太小,但又太大而不能下降到每行 2 张卡片时。这导致了 3 张卡片visible 与用户水平对齐,第 4 个位于他们下方。它们都在同一个 'row' 元素中。

我看不出如何使用 class 属性解决此问题,因为这些行是动态创建并填充了 4 张卡片的。我也看不到如何在代码中修复它,因为我的 razor 函数不知道生成元素的屏幕尺寸是多少?非常感谢任何建议...

cshtml代码:

        <body class="body-bg-img">
        
        <!-- This function checks if the card iteration is divisible by 4 to move to the next row -->
        
            @{
                bool check(int i)
                {
                    var iAsString = i.ToString();
                    int iLength = iAsString.Length;
        
                    if ((iLength == 1 && ((iAsString[0] - '0') % 4 == 0)) || iLength == 0)
                    {
                        return true;
                    }
                    else if (iLength > 1)
                    {
                        int last = iAsString[iLength - 1] - '0';
                        int secondLast = iAsString[iLength - 2] - '0';
        
                        if ((secondLast * 10 + last) % 4 == 0)
                        {
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else
                    {
                        return false;
                    }
                }
        
            }
        
        <!-- This function creates a row and populates the first card, the nested loop then populates 3
    more cards on the same row before breaking out to the main loop again, which creates the next row.  
    The nested loop then populates the next row etc. NOTE: I have [snipped] out some code for posting 
    to make it easier to read. -->
        
            @for (int i = 0; i < Model.MainArticleList.Count(); i++)
            {
                var item = Model.MainArticleList[i];
        
                if (check(i))
                {

                <div class="container-body">
                <div class="row align-content-center justify-content-center">

                <!-- CREATE A NEW CONTAINER WITH ROW & ADD FIRST CARD IN ROW -->
        
                            @if (item.UserIdRef != "none")
                            {
                [snip]
        
                                @if (item.RazorRef != "none")
                                {
                                        <div class="card h-35 border-success m-2" style="max-width: 18rem;">

               [snip] <!-- Bootstrap card properties are being populated here -->

                                        </div>
                                }
                                else if (item.HREFRef != "none")
                                {
                                    <div class="card h-35 border-success m-2" style="max-width: 18rem;">

               [snip] <!-- Just a different card content type -->

                                    </div>
                                }
                            }
        
                            @for (int j = i + 1; j < Model.MainArticleList.Count(); j++)
                            {

               <!-- CREATE CARDS 2, 3 and 4 INSIDE THE EXISTING ROW -->

                                var item1 = Model.MainArticleList[j];
        
                                if (!check(j))
                                {
        
                                    @if (item1.UserIdRef != "none")
                                    {
               [snip]
        
                                        @if (item1.RazorRef != "none")
                                        {
                                                <div class="card h-35 border-success m-2" style="max-width: 18rem;">

               [snip] <!-- Bootstrap card properties are being populated here -->

                                                </div>
                                        }
                                        else if (item1.HREFRef != "none")
                                        {
                                            <div class="card h-35 border-success m-2" style="max-width: 18rem;">

               [snip] <!-- Just a different card content type -->

                                            </div>
                                        }
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                        </div>
                    </div>
                }
            }
            <br />
        </body>

诀窍是不要自己计算行和列,并将此计算留在 CSS 级别。今天我们可以通过使用 flex-box 来做到这一点。这就是 Bootstrap 4 已经使用的卡片布局 card-deck.
How to adjust the data in grid columns in placing the data dynamically from the backend

CSS

.card-deck .card {
    flex-basis: 100%;
}

@media (min-width: 992px) {
    .card-deck .card {
        flex-basis: calc(25% - 30px); /* #{$grid-gutter-width} */
    }
}

您的设计要求可以选择告诉您让 .card 增长,如果它是一张剩余的卡片。您可以在 CSS 中使用 flex-grow 1 或 0 来控制它。 通常你将它设置为 0,有可能为某些分辨率创建空白 space。

DEMO 1(1卡移动,2小,3中,4大)
DEMO 2(1 张移动卡,3 张中卡)
DEMO 3(1 张移动卡,2 张中卡)

为了使其在后端更加动态,您可以在其中选择卡片组的列数,您可以使用助手 类 来映射断点,例如 .two-col.three-col , .four-col 等等,如DEMO 2和DEMO 3.


如果您真的必须使用行和列,请参阅我的 other answer。 您可以使用模数运算符 => amount % 4 计算剩余数。 根据我的经验,我成功地实现了三列布局。 四列肯定会更棘手。


另请注意 Bootstrap 5 这又发生了变化,因为他们摆脱了卡片组。 在这里你可以简单地使用 .row.col ,它们再次在 CSS.
中控制