You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor .NET6:如何根据浏览器窗口大小实现按钮响应式圆角

解决方案

针对你的Blazor .NET6 Server应用需求,推荐两种实现方式,优先选择纯CSS方案(无需C#/JS逻辑,更简洁易维护):


方案1:纯CSS实现(推荐)

利用CSS媒体查询和Flex布局,直接控制不同屏幕下的按钮排列和圆角样式,完全不需要修改Blazor组件的C#逻辑。

步骤1:添加布局与圆角样式

在组件的CSS文件或全局样式中添加以下代码:

/* 按钮容器基础Flex布局 */
#buttons .nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem; /* 统一控制按钮间距,替代原有的ms-3、mb-3类 */
  padding: 0;
  list-style: none;
}

/* 小屏幕(<768px):每行1个按钮 */
#buttons .nav li {
  flex: 1 0 100%; /* 按钮占满整行宽度 */
}

/* 中屏幕(768px~1199px):每行2个按钮 */
@media (min-width: 768px) {
  #buttons .nav li {
    flex: 1 0 calc(50% - 0.5rem); /* 减去间距的一半,避免布局溢出 */
  }
  /* 给每行第2个按钮添加右侧圆角 */
  #buttons .nav li:nth-child(2n) .custom-btn {
    border-top-right-radius: 0.5rem;
    border-bottom-right-radius: 0.5rem;
  }
}

/* 大屏幕(≥1200px):每行3个按钮 */
@media (min-width: 1200px) {
  #buttons .nav li {
    flex: 1 0 calc(33.333% - 0.666rem);
  }
  /* 给每行第3个按钮添加右侧圆角 */
  #buttons .nav li:nth-child(3n) .custom-btn {
    border-top-right-radius: 0.5rem;
    border-bottom-right-radius: 0.5rem;
  }
}

/* 小屏幕下每个按钮都是行尾,添加全圆角 */
@media (max-width: 767px) {
  #buttons .nav li .custom-btn {
    border-radius: 0.5rem;
  }
}

/* 按钮基础样式(保留边框) */
.custom-btn {
  border: 1px solid #ccc;
  padding: 0.5rem 1rem;
  background-color: #fff;
}

步骤2:简化Blazor组件代码

移除原有的indexhasRoundEnd和OnInitialized逻辑,直接渲染按钮并添加样式类:

<h3>Component</h3>
@if (model != null)
{
    bool isStatusX = model.Status == StatusEnum.Description(StatusEnum.X);
    bool isStatusY = model.Status == StatusEnum.Description(StatusEnum.Y);

    <div id="buttons">
        <ul class="nav">
            @if (isStatusX)
            {
                <li>
                    <Button CssClass="custom-btn" Title="title 1" OnClick=@EventOne />
                </li>
            }
            @if (isStatusY)
            {
                <li>
                    <Button CssClass="custom-btn" Title="title 2" Url=@url OnClick=@EventTwo />
                </li>
            }
            @if (isStatusX)
            {
                <li>
                    <Button CssClass="custom-btn" Title="title 3" OnClick=@EventThree />
                </li>
            }
            @if (isStatusX || isStatusY)
            {
                <li>
                    <Button CssClass="custom-btn" Title="title 4" OnClick=@EventFour />
                </li>
            }
        </ul>
    </div>
}

@code {
    // 移除原有的indexhasRoundEnd相关逻辑
}

说明

  • 用flex-wrap: wrap实现自动换行,媒体查询动态调整每行按钮宽度,无需手动计算位置。
  • 通过:nth-child()选择器精准定位每行末尾按钮,直接设置border-radius,完全避开overflow-hidden的限制。
  • gap属性统一控制按钮间距,布局更规整。

方案2:Blazor JS互操作+组件状态

若必须通过C#逻辑控制HasRoundEnd参数,可通过JS监听窗口大小,动态更新行尾按钮判断规则:

步骤1:添加JS监听逻辑(在wwwroot/index.html中)

<script>
    window.getWindowWidth = () => window.innerWidth;
    window.listenResize = (dotNetRef) => {
        window.addEventListener('resize', () => {
            dotNetRef.invokeMethodAsync('OnWindowResized', window.innerWidth);
        });
    };
</script>

步骤2:修改Blazor组件代码

@inject IJSRuntime JS
@implements IDisposable

<h3>Component</h3>
@if (model != null)
{
    bool isStatusX = model.Status == StatusEnum.Description(StatusEnum.X);
    bool isStatusY = model.Status == StatusEnum.Description(StatusEnum.Y);
    var buttons = new List<ButtonMeta>();

    // 先收集所有要显示的按钮
    if (isStatusX) buttons.Add(new ButtonMeta("title 1", EventOne));
    if (isStatusY) buttons.Add(new ButtonMeta("title 2", EventTwo, url));
    if (isStatusX) buttons.Add(new ButtonMeta("title 3", EventThree));
    if (isStatusX || isStatusY) buttons.Add(new ButtonMeta("title 4", EventFour));

    <div id="buttons">
        <ul class="nav d-flex flex-wrap gap-3">
            @for (int i = 0; i < buttons.Count; i++)
            {
                var btn = buttons[i];
                // 判断当前按钮是否为行尾:是每行最后一个,或是整个列表的最后一个
                bool hasRoundEnd = (i + 1) % _itemsPerRow == 0 || (i + 1) == buttons.Count;
                <li class="flex-fill">
                    <Button HasRoundEnd=@hasRoundEnd Title=@btn.Title Url=@btn.Url OnClick=@btn.OnClick />
                </li>
            }
        </ul>
    </div>
}

@code {
    private int _itemsPerRow = 1;
    private DotNetObjectReference<YourComponent>? _dotNetRef;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            _dotNetRef = DotNetObjectReference.Create(this);
            // 初始化时获取当前窗口宽度
            var width = await JS.InvokeAsync<int>("getWindowWidth");
            UpdateItemsPerRow(width);
            // 监听窗口大小变化
            await JS.InvokeVoidAsync("listenResize", _dotNetRef);
        }
    }

    [JSInvokable]
    public void OnWindowResized(int width)
    {
        UpdateItemsPerRow(width);
        StateHasChanged();
    }

    // 根据窗口宽度更新每行按钮数量
    private void UpdateItemsPerRow(int width)
    {
        if (width >= 1200)
            _itemsPerRow = 3;
        else if (width >= 768)
            _itemsPerRow = 2;
        else
            _itemsPerRow = 1;
    }

    public void Dispose()
    {
        _dotNetRef?.Dispose();
    }

    // 按钮元数据类,用于统一管理按钮信息
    private class ButtonMeta
    {
        public string Title { get; }
        public EventCallback OnClick { get; }
        public string? Url { get; }

        public ButtonMeta(string title, EventCallback onClick, string? url = null)
        {
            Title = title;
            OnClick = onClick;
            Url = url;
        }
    }
}

步骤3:Button组件处理圆角

在自定义Button组件中,根据HasRoundEnd参数添加样式:

<button class="@(HasRoundEnd ? "rounded-end" : "") custom-btn" @onclick="OnClick">
    @Title
</button>

@code {
    [Parameter] public bool HasRoundEnd { get; set; }
    [Parameter] public string Title { get; set; } = string.Empty;
    [Parameter] public string? Url { get; set; }
    [Parameter] public EventCallback OnClick { get; set; }
}

内容的提问来源于stack exchange,提问作者user1531040

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 13:50:48