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

发布于 2024-10-10 21:05:30 字数 993 浏览 2 评论 0原文

我的用户界面左侧有一个无序列表。选择列表项后,其右侧会出现一个 div。我希望在

  • 相交处有一个弯曲的外角。有些人称之为负边界半径倒角。请参见下图中的白色箭头。
  • sample image

    将蓝色

  • 延伸到 < 的边缘;ul>,我计划做这样的事情:
  • li { 
        right-margin: 2em; 
        border-radius: 8px; 
    }
    
    li.active { 
        right-margin: 0; 
        border-bottom-right-radius: 0; 
        border-top-right-radius: 0;
    }
    

    有没有更好的方法将

  • 扩展到
      < 的边缘/代码>?显然,我还将包括 webkit 和 mozilla 边框半径 CSS。
  • 我不确定的主要事情是活动

  • 右下角下方的外角。我有一些想法,但它们看起来像是黑客。有什么建议吗?
  • 请注意,

      以灰色表示,但在实际设计中它将是白色的。另外,我计划在选择
    • 时使用 Javascript 正确定位

    My UI has an unordered list on the left. When a list item is selected, a div appears on the right of it. I'd like to have a curved outer corner where the <li> and the <div> meet. Some people call this a negative border radius or an inverted corner. See the white arrow in the image below.

    sample image

    To extend the blue <li> to the edge of the <ul>, I'm planning to do something like this:

    li { 
        right-margin: 2em; 
        border-radius: 8px; 
    }
    
    li.active { 
        right-margin: 0; 
        border-bottom-right-radius: 0; 
        border-top-right-radius: 0;
    }
    

    Is there a better way to extend the <li> to the edge of the <ul>? Obviously, I'll include the webkit and mozilla border radius CSS as well.

    The main thing I'm unsure about is that outer corner underneath the bottom right corner of the active <li>. I have some ideas, but they seem like hacks. Any suggestions?

    NOTE that the <ul> is indicated in grey, but it would be white in the real design. Also, I'm planning to use Javascript to position the <div> correctly when an <li> is selected.

    如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

    扫码二维码加入Web技术交流群

    发布评论

    需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

    评论(5

    浊酒尽余欢 2024-10-17 21:05:30

    好吧,事实证明,我自己解决了这个问题。我编写了一个演示 - 查看一下

    本质上,需要几个额外的 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 上的 Google Chrome 中对此进行了测试。

    Well, as it turns out, I managed to solve the problem myself. I hacked together a demo -- check it out.

    Essentially, several additional DOM elements are required and a fair amount of CSS. And as mentioned in the link provided by @Steve, a solid background is required. I don't believe there is any way to do this over a gradient background or other pattern.

    I ended up with HTML like this:

    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>

    I haven't optimized any of the CSS as I just hacked it together. But perhaps it will help someone else. I've only tested this in Google Chrome on Mac OSX.

    素年丶 2024-10-17 21:05:30

    更干净的解决方案(更少的代码和允许背景渐变

    查看小提琴(或另一个),它使用这个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;
    }
    

    Cleaner Solution (Less Code & Background Gradient Allowed)

    See the fiddle (or another), which is using this 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>
    

    And this css (the key is to allow the border-radius and border-width on the pseudo-elements to make the inverted circle for you; I've omitted the gradient code.):

    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;
    }
    
    南城旧梦 2024-10-17 21:05:30

    我想出了一个需要更少标记的解决方案。综上所述,它不使用边距,而是使用白色圆角边框,然后我们将活动 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;
    }
    

    说实话,我不确定这是一个更好的版本,它确实使渐变/图像背景变得容易(至少对于非活动的李来说),但你不能应用图像/渐变背景到身体。从它以非直观的方式起作用的意义上来说,它也是“坏魔法”。

    I came up with a solution that requires less markup. In summary, instead of using margins it uses white rounded borders, then we position the active li behind the white rounded borders to achieve the inverted border-radius effect.

    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>
    

    And less CSS too! (this is mind bending):

    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;
    }
    

    To tell you the truth I'm not sure it's a better version, it does make gradient/image backgrounds easy (for non active li's, at least) but you can't apply an image/gradient background to the body. It's also "bad magic" en the sense that it works in a non-intuitive way.

    日暮斜阳 2024-10-17 21:05:30

    要在非固体背景上做到这一点,我认为你不能使用 CSS 来做到这一点,但你可以使用 canvas 或 SVG 来达到相同的效果 - 但不完全是你所要求的。

    然而,似乎确实有一个负边框半径的提案可以解决这个问题问题。也许有一天,对吧。

    To do this over a non-solid bg, I don't think you can do it with CSS, but you could use canvas or SVG to the same effect - not exactly what you asked for, though.

    However, there does appear to be a proposal for negative border radius that would solve the problem. Maybe some day, right.

    凹づ凸ル 2024-10-17 21:05:30

    这个很好的 CSS 中的反向边框半径教程 可以解决这个问题。解释如何为选项卡执行反向边框半径。但它可以很容易地适应简化你的 CSS,因为它使用 :after 而不是创建太多额外的元素。

    This nice Inverse Border Radius in CSS tutorial could do the trick. Explains how to do inverse border radius for tabs. But it could be easily adapted to streamline your css since it uses :after instead of creating too many extra elements.

    ~没有更多了~
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文