微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从模型中的列表创建矩阵显示 LinksListGrid.cshtml: LinkContainer.scss: HTML和SCSS方式 ASP.NET MVC方式

如何解决如何从模型中的列表创建矩阵显示 LinksListGrid.cshtml: LinkContainer.scss: HTML和SCSS方式 ASP.NET MVC方式

我有一个名为LinksListWidgetModel的模型,该模型包含一个名为Links的IEnumerable属性,该属性包含我的网站链接的列表。

在我的Razor视图中,我有两列(即一列用于网格“ col-md-8”,一列用于另一工具“ col-md-4”。我有一个foreach循环,可将每个链接添加到网格工具。我尝试获得以下外观:Matrix View,但是按钮不会在三个后自动换行,而是在整个页面宽度上连续。我正在使用Bootstrap4.x和flexBox

我尝试按照以下问题中的示例进行操作:How I can make nice looking matrix of buttons with bootstrap 3?,但这也不能解决问题。

这是我的代码

LinksListGrid.cshtml:

@if (Model == null)
{
@Html.Partial("_WidgetNotConfigured") }
else
{
  <div class="btn-group btn-matrix" role="group">
    @foreach (var link in Model.Links)
    {
        <div class="linkContainer-gridItem">
            <button>
                <a class="linkContainer-gridItem-link btn btn-default" href="@link.Url">
                    @if (!string.IsNullOrEmpty(link.Icon))
                    {
                        <div>
                            <i class="icon @link.Icon"></i>
                        </div>
                    }
                    @link.Label
                </a>
                </button>
        </div>
    }
</div>
}

LinkContainer.scss:

.linkContainer {
    padding: 1rem;
    margin-bottom: 2rem;
    position: relative;
    background: #fff;
    border-radius: 8px;
    border: 1px solid #dddfe2;

    .linkContainer-title {
        color: #fff;
        background: $colorBrandDarkBlue;
        padding: 1rem;
        border-radius: 5px;
        margin: -.5rem -.5rem 1rem -.5rem;
        font-weight: 400;
    }

    .linkContainer-list {
        list-style: none;
        padding: 0;
        margin-bottom: 0;
        font-family: "Montserrat",sans-serif;

        .linkContainer-item {
            position: relative;

            .linkContainer-link {
                display: -webkit-Box;
                display: -ms-flexBox;
                display: flex;
                padding: .75rem .5rem;
                color: $colorBrandBlue;
                font-weight: 400;
                font-size: 18px;
                -webkit-Box-align: center;
                -ms-flex-align: center;
                align-items: center;
                text-decoration: none;
                background-color: transparent;
                font-family: "Montserrat",sans-serif;
            }

            .icon:before {
                font-size: 30px;
                margin-right: 1rem;
            }
        }

        .linkContainer-item:after {
            content: '';
            position: absolute;
            top: 0;
            right: 0;
            left: 0;
            border-top: 1px dotted;
            opacity: .25;
        }
    }

    .linkContainer-grid {
        width: 290px;
        display: block;
        margin: 0 auto;
        padding: 0;
        padding-bottom: 19px;
        font-family: "Montserrat",sans-serif;
        text-align: center;

        .linkContainer-gridItem {
            background-color: $colorBrandBlue;
            border-radius: 25px;
            width: 120px;
            height: 120px;
            margin: 10px;
            display: inline-block;
            vertical-align: top;

            .linkContainer-gridItem-link {
                color: white;
                text-decoration: none;
                display: flex;
                flex-direction: column;
                justify-content: center;
                height: 100%;
                padding: 20px 10px;
            }

            .icon {
                font-size: 30px;
                margin-bottom: 0.25rem;
            }
        }
    }

    @media screen and (max-width: 767px) {
        &.linkContainer-gridLayout {
            padding: 0;
        }
    }
}

.btn-matrix {
    > .btn {
        &:nth-child(3n+4) {
            clear: left;
            margin-left: 0;
        }

        &:nth-child(n+4) {
            margin-top: -1px;
        }

        &:first-child {
            border-bottom-left-radius: 0;
        }

        &:nth-child(3) {
            border-top-right-radius: 4px !important;
        }

        &:nth-last-child(3) {
            border-bottom-left-radius: 4px !important;
        }

        &:last-child {
            border-top-right-radius: 0;
        }
    }
}

它最终看起来像这样:Grid View

如何更改它,使其看起来像第一个屏幕截图的矩阵/网格显示?每3个按钮后,它就会进入第二行。

解决方法

我认为clear:left;在flexbox上不起作用。但是还有其他方法可以实现。

HTML和SCSS方式

我认为您最好自己对.btn-matrix进行样式设置,而不要混合.btn-group样式,因为Bootstrap .btn-group为其.btn子项带来了很多麻烦,例如例如border-radiusborder等。无论如何,您都需要使用自己的样式来设置它们的样式,以防打扰。

我认为以下结构应该足够通用,可以用来构造矩阵:

<div class="btn-matrix btn-matrix-white" role="group">
    <a class="btn" href="#">
        <div class="fa-stack fa-2x">
            <i class="fas fa-circle fa-stack-2x" />
            <i class="fas fa-chart-bar fa-stack-1x" />
        </div>
        Reports
    </a>
    ...
</div>

首先,在原始HTML结构中,您有一个用于包装锚链接的按钮。这不是必需的,因为Bootstrap具有类来设置锚链接的样式,使其看起来就像一个按钮。

第二,我正在使用图标堆叠方法来构造具有圆形背景的图标。您可以在这里阅读有关内容:https://fontawesome.com/how-to-use/on-the-web/styling/stacking-icons

最后,这是样式:

$numOfMatrixItemPerRow: 3;
$matrixItemBorderWidth: 1px;

.btn-matrix {
    display: flex;
    flex-flow: row wrap;
    box-shadow: 0 0 1rem #ccc;
    border: 1px solid transparent;
    border-radius: .25rem;
    
    > .btn {
        display: flex;
        flex-flow: column nowrap;
        align-items: center;
        justify-content: flex-start;
        flex-grow: 0;
        flex-shrink: 0;
        padding: 5%;
        width: calc(100% / #{$numOfMatrixItemPerRow});
        border-radius: 0;
    }

    &.btn-matrix-white {
        > .btn {
            background-color: #fff;
            border-right: $matrixItemBorderWidth solid #ddd;
            border-bottom: $matrixItemBorderWidth solid #ddd;
            
            .fa-stack-2x {
                color: var(--primary);
            }
            
            .fa-stack-1x {
                color: #fff;
            }
            
            &:nth-child(#{$numOfMatrixItemPerRow}n) {
                border-right: none !important;
            }
            
            &:last-child {
                border-bottom: none !important;
            }
        }
    }
}

那里真的没有什么棘手的问题,只不过您需要使用SASS Interpolation来将$numOfMatrixItemPerRow变量包含在计算中:

  • .btn-matrix显示为可包装的flex行
  • 将每个按钮的宽度设置为100% / $numOfMatrixItemPerRow,以便在分成新行之前,每一行将包含确切数量的项目。
  • .btn显示为flexbox列,以便您可以轻松地在其中对齐图标和文本
  • 设置每个按钮的右边框和下边框,但每行的最后一个和最后一个除外

enter image description here

演示: https://jsfiddle.net/davidliang2008/1wqost69/201/


ASP.NET MVC方式

现在,由于您正在使用ASP.NET MVC,所以我认为您可以考虑使用另一种方法。也就是说,在循环遍历模型中每个链接的循环中,您可以在其中定义变量并执行以下操作:

<div class="btn-matrix">
    @for (int i = 0; i < Model.Links.Count(); i++)
    {
        var link = Model.Links[i];

        if (i % numOfItemsPerRow == 0)
        {
            <div class="row">
        }
        <div class="col-md-4">
            <a class="btn" href="@link.Url">
                @if (!string.IsNullOrEmpty(link.Icon))
                {
                    <div>
                        <i class="icon @link.Icon"></i>
                    </div>
                }
                @link.Label
            </a>
        </div>
        if ((i+1) % numOfItemsPerRow == 0 || i + 1 == Model.Links.Count())
        {
            </div>
        }
    }
</div>

我只是在整理东西,但希望你能看到我要去的地方。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。