Подтвердить что ты не робот

CSS для создания изогнутого угла между двумя элементами?

Мой пользовательский интерфейс имеет неупорядоченный список слева. Когда выбран элемент списка, справа от него появляется 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>? Очевидно, что я также включу CSS-код webkit и mozilla.

Главное, что я не уверен в том, что внешний угол находится внизу нижнего правого угла активного <li>. У меня есть некоторые идеи, но они кажутся хаками. Любые предложения?

ЗАМЕЧАНИЕ, что <ul> обозначается серым, но в реальном дизайне он будет белым. Кроме того, я планирую использовать Javascript, чтобы правильно позиционировать <div>, когда выбран <li>.

4b9b3361

Ответ 1

Ну, как оказалось, мне удалось решить проблему самостоятельно. Я взломал демо - проверить его.

По существу, требуется несколько дополнительных элементов 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>

Ответ 2

Чистое решение (меньше разрешенного кода и фонового градиента)

Посмотрите скрипт (или другой), который использует этот 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-radius и border-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;
}

Ответ 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, по крайней мере), но вы не можете применить фон изображения/градиента к телу. Это также "плохая магия" в том смысле, что она работает неинтуитивно.

Ответ 5

Чтобы сделать это над нечетким bg, я не думаю, что вы можете сделать это с помощью CSS, но вы можете использовать canvas или SVG с тем же эффектом - не совсем то, о чем вы просили.

Однако существует предложение для отрицательного пограничного радиуса, которое решило бы проблему. Может быть, когда-нибудь, правильно.

Ответ 6

Этот приятный Обратный ракурс в CSS-учебнике мог бы сделать трюк. Объясняет, как сделать обратный радиус границы для вкладок. Но он может быть легко адаптирован для оптимизации вашего css, поскольку он использует :after вместо создания слишком большого количества дополнительных элементов.