Search code examples
htmlcssrounded-cornerscss-shapes

CSS to create curved corner between two elements?


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.


Solution

  • 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.