CSS, um eine gekrümmte Ecke zwischen zwei Elementen zu erstellen?
-
25-09-2019 - |
Frage
Meine Benutzeroberfläche hat eine ungeordnete Liste links. Wenn ein Listenelement ausgewählt ist, a div
erscheint rechts davon. Ich würde gerne eine gekrümmte haben äußere Ecke bei dem die <li>
und die <div>
Treffen. Einige Leute nennen das a negativer Grenzradius oder an Umgekehrte Ecke. Siehe den weißen Pfeil im Bild unten.
Das Blau verlängern <li>
zum Rand der <ul>
, Ich habe vor, so etwas zu tun:
li {
right-margin: 2em;
border-radius: 8px;
}
li.active {
right-margin: 0;
border-bottom-right-radius: 0;
border-top-right-radius: 0;
}
Gibt es eine bessere Möglichkeit, die zu erweitern? <li>
zum Rand der <ul>
? Offensichtlich werde ich auch das CSS von Webkit und Mozilla Border Radius einbeziehen.
Die Hauptsache, über die ich mich nicht sicher bin, ist das äußere Ecke unter der unteren rechten Ecke des aktiven <li>
. Ich habe einige Ideen, aber sie scheinen Hacks zu sein. Irgendwelche Vorschläge?
Notiere dass der <ul>
ist grau angezeigt, aber es wäre weiß im realen Design. Außerdem plane ich JavaScript, um das zu positionieren <div>
richtig, wenn an <li>
ist ausgewählt.
Lösung
Nun, wie sich herausstellt, habe ich es geschafft, das Problem selbst zu lösen. Ich habe eine Demo zusammengehackt - Hör zu.
Im Wesentlichen sind mehrere zusätzliche DOM -Elemente erforderlich und eine angemessene Menge an CSS. Und wie in dem von @steve bereitgestellten Link erwähnt, ist ein solider Hintergrund erforderlich. Ich glaube nicht, dass es eine Möglichkeit gibt, dies über einen Gradientenhintergrund oder ein anderes Muster zu tun.
Am Ende hatte ich HTML wie folgt:
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>
Ich habe kein CSS optimiert, da ich es gerade zusammen gehackt habe. Aber vielleicht wird es jemand anderem helfen. Ich habe dies nur in Google Chrome unter Mac OSX getestet.
Andere Tipps
Cleaner -Lösung (weniger Code & Hintergrundgradient erlaubt)
Siehe die Geige (oder Ein weiterer), was diese HTML verwendet:
<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>
Und dieses CSS (der Schlüssel ist, das zuzulassen border-radius
und border-width
auf den Pseudoelementen, um den umgekehrten Kreis für Sie zu machen; Ich habe das weggelassen 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;
}
Ich hatte eine Lösung, die weniger Markup erfordert. Zusammenfassend positionieren wir den aktiven Li hinter den weißen, abgerundeten Rändern, um den umgekehrten Grenz-Radius-Effekt zu erreichen, anstatt die Ränder zu verwenden.
<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>
Und weniger CSS auch! (Das ist ein Eingeweidebiegung):
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;
}
Um Ihnen die Wahrheit zu sagen. Ich bin mir nicht sicher, ob es sich um eine bessere Version handelt, es macht Gradienten-/Bildhintergründe einfach (zumindest für nicht aktive Li), aber Sie können keinen Bild-/Gradientenhintergrund auf den Körper anwenden. Es ist auch "schlechte Magie" und das Gefühl, dass es nicht intuitiv funktioniert.
Nicht wirklich, sorry, pro
Um dies über einen nicht soliden BG zu tun, glaube ich nicht, dass Sie es mit CSS tun können, aber Sie könnten Leinwand oder SVG zu demselben Effekt verwenden - nicht genau das, wonach Sie gefragt haben.
Es scheint jedoch a zu geben Vorschlag für einen negativen Grenzradius Das würde das Problem lösen. Vielleicht eines Tages, richtig.
Das schön Umgekehrter Grenzradius im CSS -Tutorial könnte den Trick machen. Erklärt, wie umgekehrter Grenzradius für Registerkarten durchführt. Es könnte jedoch leicht angepasst werden, um Ihr CSS zu optimieren, da es verwendet wird :after
Anstatt zu viele zusätzliche Elemente zu erstellen.