首页 > 解决方案 > 如果它们彼此相邻,则合并具有 CSS 边框半径的列表项?

问题描述

我正在创建一个 Web 应用程序(一个辅助项目!),我试图让它看起来不错并且遇到了一点 CSS 挑战,你能帮我吗?

示例,因为使用图片更容易:

示例 1

我得到什么:

我想要的是 :

示例 2

我得到什么:

我想要的是 :

我在这里托管了一个非常简单的 vuejs 示例:https ://jsfiddle.net/ep8ny04d/3/

li {
  margin: 0;
  padding: 10px;
  border-radius: 10px;
  cursor: pointer;
  &.active {
    background: #39a374;
    color: white;
  }
}

(我的截图来自这个例子。)

所以问题是:两个元素必须粘在一起,但是如果选择了两个或多个元素并且彼此相邻,则必须更改元素的边框半径(或删除中间元素)。

你认为没有Javascript可以做到吗?

标签: cssvue.js

解决方案


您可以使用兄弟组合符 , , 和 的组合获得大部分方法:first-child:last-child:not()注意,您需要border-radius: 10px从顶级li规则中删除声明):

li {
  margin: 0;
  padding: 10px;
  cursor: pointer;
  &.active {
    background: #39a374;
    color: white;
  }
  &.active:first-child, &:not(.active) + .active {
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
  }
  &.active:last-child {
    border-bottom-left-radius: 10px;
    border-bottom-right-radius: 10px;
  }
}

但这不会为.active出现在项目之前的:not(.active)项目产生底部圆角。您需要为这些特定项目添加另一个类,然后才能使用 CSS 定位它们。这可以在类绑定中完成,这样您就可以避免污染数据模型(或者实际上,编写额外的应用程序逻辑,我认为这就是您所说的“没有 JavaScript”......):

<li v-for="(todo,i) in todos"
  v-on:click="toggle(todo)"
  v-bind:class="{active: todo.active, beforeInactive: todo.active && todos[i+1] && !todos[i+1].active}">
  {{i}} Hey
</li>

然后在 CSS 中引用:

li
  // ...
  &.active:first-child, &:not(.active) + .active {
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
  }
  // Added reference to new .beforeInactive class
  &.active:last-child, &.beforeInactive {
    border-bottom-left-radius: 10px;
    border-bottom-right-radius: 10px;
  }
}

更新的小提琴


推荐阅读