CSS在两个元素之间创建弯角?

时间:2011-01-05 06:14:40

标签: css html5 css3 rounded-corners css-shapes

我的用户界面左侧有一个无序列表。选择列表项后,右侧会显示div。我想在<li><div>相遇的地方有一个弯曲的外角。有些人称之为负边界半径倒角。请参见下图中的白色箭头。

sample image

要将蓝色<li>延伸到<ul>的边缘,我打算做这样的事情:

li { 
    right-margin: 2em; 
    border-radius: 8px; 
}

li.active { 
    right-margin: 0; 
    border-bottom-right-radius: 0; 
    border-top-right-radius: 0;
}

有没有更好的方法将<li>扩展到<ul>的边缘?显然,我还将包括webkit和mozilla边界半径CSS。

我不确定的主要问题是活动<li>右下角下方的外角。我有一些想法,但它们看起来像黑客。有什么建议吗?

请注意,<ul>以灰色显示,但在实际设计中为白色。此外,我计划在选择<div>时使用Javascript正确定位<li>

6 个答案:

答案 0 :(得分:11)

嗯,事实证明,我自己设法解决了这个问题。我一起编写了一个演示 - check it out

基本上,需要几个额外的DOM元素和相当数量的CSS。正如@Steve提供的链接中所提到的,需要一个坚实的背景。我不相信在渐变背景或其他模式上有任何方法可以做到这一点。

我最终得到了这样的HTML:

ul.selectable {
  padding-top: 1em;
  padding-bottom: 1em;
  width: 50%;
  float: left;
}
ul.selectable li {
  margin: 0 3em 0 4em;
  border-radius: 8px;
  -webkit-border-radius: 8px;
  -khtml-border-radius: 8px;
  -moz-border-radius: 8px;
}
ul.selectable li.active {
  margin-right: 0;
}
ul.selectable li.active dl {
  background-color: #4f9ddf;
}
ul.selectable li dt {
  background-color: #dfd24f;
  padding: 1em;
  margin-left: -2em;
  margin-right: -2em;
  -webkit-border-radius: 8px;
  -khtml-border-radius: 8px;
  -moz-border-radius: 8px;
  border-radius: 8px;
}
ul.selectable li dd {
  padding: 0.25em;
  background-color: #fff;
}
ul.selectable li.active dt {
  background-color: #4f9ddf;
  margin-right: 0;
  -webkit-border-top-right-radius: 0;
  -webkit-border-bottom-right-radius: 0;
  -khtml-border-top-right-radius: 0;
  -khtml-border-bottom-right-radius: 0;
  -moz-border-radius-topright: 0;
  -moz-border-radius-bottomright: 0;
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
ul.selectable li.active dd.top {
  -webkit-border-bottom-right-radius: 8px;
  -khtml-border-bottom-right-radius: 8px;
  -moz-border-radius-bottomright: 8px;
  border-bottom-right-radius: 8px;
}
ul.selectable li.active dd.bot {
  -webkit-border-top-right-radius: 8px;
  -khtml-border-top-right-radius: 8px;
  -moz-border-radius-topright: 8px;
  border-top-right-radius: 8px;
}
div.right {
  float: left;
  padding-top: 3em;
  width: 50%;
}
div.content {
  height: 15em;
  width: 80%;
  background-color: #4f9ddf;
  padding: 1em;
  -webkit-border-radius: 8px;
  -khtml-border-radius: 8px;
  -moz-border-radius: 8px;
  border-radius: 8px;
}
<ul class="selectable">
  <li>
    <dl>
      <dd class="top"></dd>
      <dt>Title</dt>
      <dd class="bot"></dd>
    </dl>
  </li>
  <li class="active">
    <dl>
      <dd class="top"></dd>
      <dt>Title</dt>
      <dd class="bot"></dd>
    </dl>
  </li>
  <li>
    <dl>
      <dd class="top"></dd>
      <dt>Title</dt>
      <dd class="bot"></dd>
    </dl>
  </li>
</ul>
<div class="right">
  <div class="content">This is content</div>
</div>

我没有优化任何CSS,因为我只是将它们一起攻击。但也许它会帮助别人。我只是在Mac OSX上的谷歌浏览器中对此进行了测试。

答案 1 :(得分:5)

清洁解决方案(少代码&amp; 允许背景渐变

See the fiddle(或another),正在使用此html:

<ul class="selectable">
    <li>Title</li>
    <li class="active">Title</li>
    <li>Title</li>
    <li>Title</li>
</ul>
<div class="right">
    <div class="content">This is content</div>
</div>

这个css(关键是允许伪元素上的border-radiusborder-width为你做倒圆;我省略了gradient代码。) :

ul.selectable {
    padding-top: 1em;
    padding-bottom: 1em;
    width: 50%;
    float: left;
}
ul.selectable li {
    margin: 1em 1em 1em 2em;
    padding: 1em;
    border-radius: 8px;
    -webkit-border-radius: 8px;
    -khtml-border-radius: 8px;
    -moz-border-radius: 8px;
    background-color: #dfd24f;
    position: relative;
}
ul.selectable li.active {
    margin-right: 0;
    background-color: #4f9ddf;
    -webkit-border-top-right-radius: 0;
    -webkit-border-bottom-right-radius: 0;
    -khtml-border-top-right-radius: 0;
    -khtml-border-bottom-right-radius: 0;
    -moz-border-radius-topright: 0;
    -moz-border-radius-bottomright: 0;
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

ul.selectable li.active:before,
ul.selectable li.active:after {
    content: '';
    position: absolute;
    left: 100%; /* I use this instead of right: 0 to avoid 1px rounding errors */
    margin-left: -8px; /* I use this because I am using left: 100% */
    width: 8px;
    height: 8px;
    border-right: 8px solid #4f9ddf;
    z-index: -1;    
}

ul.selectable li.active:before {
    top: -8px;
    border-bottom: 8px solid  #4f9ddf;
    -webkit-border-bottom-right-radius: 16px;
    -khtml-border-bottom-right-radius: 16px;
    -moz-border-radius-bottomright: 16px;
    border-bottom-right-radius: 16px;
}
ul.selectable li.active:after {
    bottom: -8px;
    border-top: 8px solid  #4f9ddf;
    -webkit-border-top-right-radius: 16px;
    -khtml-border-top-right-radius: 16px;
    -moz-border-radius-topright: 16px;
    border-top-right-radius: 16px;
}
div.right {
    float: left;
    padding-top: 3em;
    width: 50%;
}
div.content {
    height: 15em;
    width: 80%;
    background-color: #4f9ddf;
    padding: 1em;
    -webkit-border-radius: 8px;
    -khtml-border-radius: 8px;
    -moz-border-radius: 8px;
    border-radius: 8px;
}

答案 2 :(得分:3)

我想出了一个需要较少标记的解决方案。总之,不是使用边距而是使用白色圆角边框,然后我们将活动的li放在白色圆角边框后面,以实现倒边的半径效果。

http://jsfiddle.net/zrMW8/

<ul class="selectable">
    <li>
        <a href="#">Title</a>
    </li>
    <li class="active">
        <a href="#">Title</a>
    </li>
    <li>
        <a href="#">Title</a>
    </li>
    <li>
        <a href="#">Title</a>
    </li>
</ul>
<div class="right">
    <div class="content">This is content</div>
</div>

也减少了CSS! (这是精神上的弯曲):

a { color: #000; text-decoration: none;}

ul.selectable {
    padding: 1em 1em;
    width: 40%;
    float: left;
}

ul.selectable li {
    margin:  -1em 0 0 0;
    border-radius: 8px;
    -webkit-border-radius: 8px;
    -khtml-border-radius: 8px;
    -moz-border-radius: 8px;
    border: solid #fff 1em;
    position: relative;
}

ul.selectable li a {
   background-color: #dfd24f;
    padding: 1em;
    display: block;
       border-radius: 8px;
    -webkit-border-radius: 8px;
    -khtml-border-radius: 8px;
    -moz-border-radius: 8px;
}

ul.selectable li.active {
    margin: -1em -1em -1em 1em;
    border: solid #4f9ddf 1em;
    border-left: solid #fff 1em;
    background-color: #4f9ddf;
    position: static;
}

ul.selectable li.active a {
    margin: 0 0 0 -1em;
    border-left: solid #4f9ddf 1em;
    background-color: #4f9ddf;
    position: static;
    text-indent: -1em;
}

div.right {
    float: left;
    padding-top: 3em;
    width: 50%;
    margin-left: -1em;
}
div.content {
    height: 15em;
    width: 80%;
    background-color: #4f9ddf;
    padding: 1em;
    -webkit-border-radius: 8px;
    -khtml-border-radius: 8px;
    -moz-border-radius: 8px;
    border-radius: 8px;
}

说实话我不确定它是一个更好的版本,它确实使渐变/图像背景变得容易(至少对于非活动的li),但你不能将图像/渐变背景应用于身体。它也是“不好的魔法”,因为它以非直观的方式运作。

答案 3 :(得分:0)

不是,对不起,按

Invert rounded corner in CSS?

答案 4 :(得分:0)

要在非固体bg上执行此操作,我认为你不能用CSS做到这一点,但是你可以使用canvas或SVG来达到同样的效果 - 不过你所要求的不完全。

但是,似乎有一个proposal for negative border radius可以解决问题。也许有一天,对。

答案 5 :(得分:0)

这个不错的Inverse Border Radius in CSS tutorial可以解决问题。说明如何为制表符执行反边界半径。但它可以很容易地适应简化您的CSS,因为它使用:after而不是创建太多的额外元素。