29 votes

CSS pour créer un coin incurvé entre deux éléments?

Mon INTERFACE est une liste non triée sur la gauche. Lorsqu'un élément de la liste est sélectionné, un div s'affiche sur la droite. J'aimerais avoir une courbe coin externe où l' <li> et de la <div> rencontrer. Certaines personnes appellent cela un négatif rayon des frontières ou inversé coin. Voir la flèche blanche dans l'image ci-dessous.

sample image

Pour prolonger le bleu <li> vers le bord de l' <ul>, j'ai l'intention de faire quelque chose comme ceci:

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

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

Est-il une meilleure façon de prolonger l' <li> vers le bord de l' <ul>? Évidemment, je vais inclure le webkit et mozilla border radius CSS ainsi.

La principale chose que je ne suis pas sûr, c'est que coin externe sous le coin inférieur droit de l'actif <li>. J'ai quelques idées, mais ils semblent comme des hacks. Toutes les suggestions?

NOTEZ que l' <ul> est indiqué en gris, mais il serait blanc dans la conception réelle. Aussi, j'ai l'intention d'utiliser Javascript pour la position de l' <div> correctement lorsqu'un <li> est sélectionné.

11voto

Tauren Points 9324

Eh bien, comme il s'avère, j'ai réussi à résoudre le problème moi-même. J'ai bidouillé un démo -- check it out.

Essentiellement, plusieurs autres éléments du DOM sont nécessaires et une bonne quantité de feuilles de style CSS. Et comme mentionné dans le lien fourni par @Steve, un solide arrière-plan est nécessaire. Je ne crois pas qu'il existe un moyen pour ce faire sur un dégradé d'arrière-plan ou autre motif.

J'ai fini avec le HTML comme ceci:

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

Et voici le CSS. Notez que je suis en utilisant des marges négatives dans certains endroits. Il y a probablement un moyen de le faire sans, mais c'était plus facile.

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

Je n'ai pas du tout optimisé tout de la CSS que j'ai juste piraté ensemble. Mais peut-être que cela aidera quelqu'un d'autre. J'ai uniquement testé dans Google Chrome sur Mac OSX.

6voto

ScottS Points 37738

Solution Plus Propre (Moins De Code & Dégradé D'Arrière-Plan Autorisé)

Voir le violon (ou un autre), qui est à l'aide de ce code 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>

Et ce css (la clé est de permettre à l' border-radius et border-width sur le pseudo-éléments pour faire de l'inversion de cercle pour vous; j'ai omis 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;
}

3voto

Duopixel Points 27962

Je suis venu avec une solution qui nécessite moins de balisage. En résumé, au lieu d'utiliser les marges de il blanc utilise des bordures arrondies, puis nous position de l'actif li derrière le blanc des bords arrondis pour réaliser l'inversion de border-radius effet.

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>

Et moins de CSS aussi! (c'est l'esprit de flexion):

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

Pour vous dire la vérité, je ne suis pas sûr que c'est une meilleure version, il est dégradé/images de fond facile (pour les non actif li, au moins), mais vous ne pouvez pas appliquer une image en dégradé de fond pour le corps. C'est aussi la "mauvaise magie" en ce sens qu'elle travaille dans un non-intuitive.

0voto

Steve Points 10623

0voto

Russell Leggett Points 4562

Pour ce faire sur un bg non solide, je ne pense pas que vous puissiez le faire avec CSS, mais vous pouvez utiliser canvas ou SVG dans le même effet - pas exactement ce que vous avez demandé, cependant.

Cependant, il semble y avoir une proposition de rayon de bordure négatif qui résoudrait le problème. Peut-être un jour, non.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X