CSS 3 форма: обратен кръг или изрязан кръг

Искам да създам форма, която бих описал като "обратен кръг":

CSS форма

Изображението някак си е неточно, защото черната линия трябва да продължи по външната граница на елемента div.

Ето демонстрация на това, което имам в момента: http://jsfiddle.net/n9fTF/

Това дори възможно ли е с CSS без изображения?


person Alp    schedule 08.05.2012    source източник
comment
Единствената ми мисъл беше да използвам кутия-сянка, за да симулирам кривата, но тя е много несъвършена, тъй като границата на div b не следва контура. jsfiddle.net/n9fTF/4   -  person MetalFrog    schedule 08.05.2012


Отговори (6)


Актуализация: CSS3 опция за радиален фонов градиент

(За тези браузъри, които го поддържат - тествани във FF и Chrome - IE10, Safari също трябва да работи).

Един „проблем“ с първоначалния ми отговор са тези ситуации, при които човек няма солидна предистория, срещу която работи. Тази актуализация създава същия ефект, като позволява прозрачна „празнина“ между кръга и неговия обратен изрез.

Вижте примерна цигулка.

CSS

.inversePair {
    border: 1px solid black;
    display: inline-block;    
    position: relative;    
    height: 100px;
    text-align: center;
    line-height: 100px;
    vertical-align: middle;
}

#a {
    width: 100px;
    border-radius: 50px;
    background: grey;
    z-index: 1;
}

#b {
    width: 200px;
    /* need to play with margin/padding adjustment
       based on your desired "gap" */
    padding-left: 30px;
    margin-left: -30px;
    /* real borders */
    border-left: none;
    -webkit-border-top-right-radius: 20px;
    -webkit-border-bottom-right-radius: 20px;
    -moz-border-radius-topright: 20px;
    -moz-border-radius-bottomright: 20px;
    border-top-right-radius: 20px;
    border-bottom-right-radius: 20px;
    /* the inverse circle "cut" */
    background-image: -moz-radial-gradient(
        -23px 50%, /* the -23px left position varies by your "gap" */
        circle closest-corner, /* keep radius to half height */
        transparent 0, /* transparent at center */
        transparent 55px, /*transparent at edge of gap */
        black 56px, /* start circle "border" */
        grey 57px /* end circle border and begin color of rest of background */
    );
    background-image: -webkit-radial-gradient(-23px 50%, circle closest-corner, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 55px, black 56px, grey 57px);
    background-image: -ms-radial-gradient(-23px 50%, circle closest-corner, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 55px, black 56px, grey 57px);
    background-image: -o-radial-gradient(-23px 50%, circle closest-corner, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 55px, black 56px, grey 57px);
    background-image: radial-gradient(-23px 50%, circle closest-corner, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 55px, black 56px, grey 57px);
}

Оригинален отговор

Отне повече усилия, отколкото очаквах, за да накарам z-индексирането да работи (това изглежда игнорира отрицателния z-индекс), обаче, това дава хубав чист вид (тествано в IE9, FF, Chrome):

HTML

<div id="a" class="inversePair">A</div>
<div id="b" class="inversePair">B</div>

CSS

.inversePair {
    border: 1px solid black;
    background: grey;
    display: inline-block;    
    position: relative;    
    height: 100px;
    text-align: center;
    line-height: 100px;
    vertical-align: middle;
}

#a {
    width: 100px;
    border-radius: 50px;
}

#a:before {
    content:' ';
    left: -6px;
    top: -6px;
    position: absolute;
    z-index: -1;
    width: 112px; /* 5px gap */
    height: 112px;
    border-radius: 56px;
    background-color: white;
} 

#b {
    width: 200px;
    z-index: -2;
    padding-left: 50px;
    margin-left: -55px;
    overflow: hidden;
    -webkit-border-top-right-radius: 20px;
    -webkit-border-bottom-right-radius: 20px;
    -moz-border-radius-topright: 20px;
    -moz-border-radius-bottomright: 20px;
    border-top-right-radius: 20px;
    border-bottom-right-radius: 20px;
}

#b:before {
    content:' ';
    left: -58px;
    top: -7px;
    position: absolute;
    width: 114px; /* 5px gap, 1px border */
    height: 114px;
    border-radius: 57px;
    background-color: black;
} 
person ScottS    schedule 08.05.2012
comment
това е страхотно, харесва ми това решение - person Alp; 09.05.2012
comment
@Alp--страхотно! Радвам се, че срещна одобрение. - person ScottS; 09.05.2012
comment
@Alp--Добавих актуализация, която би позволила прозрачна празнина между кръг и обратно в браузъри, поддържащи фон с радиален градиент. - person ScottS; 13.05.2012
comment
страхотно, това е истинско CSS майсторство. почти магьосничество :) - person Alp; 13.05.2012
comment
Удивително - търсих години наред, за да намеря начин да изрежа малък кръг от div и това е точно трикът, от който имах нужда - person Fijjit; 25.10.2013

Не мога да разбера от чертежа ви колко заоблени искате точките, но ето една възможност: http://jsfiddle.net/n9fTF/6/

Ако точките трябва да бъдат по-закръглени, ще трябва да поставите няколко кръга в краищата, така че да се слеят с голямата лъжичка.

person Chris Fletcher    schedule 08.05.2012
comment
най-доброто решение досега, благодаря. въпреки това бялата празнина между двата елемента div трябва да има абсолютно еднаква ширина навсякъде, което не е случаят тук - person Alp; 08.05.2012

Различен подход: Box-shadows

Този подход използва сенки на CSS кутии, които се поддържат от IE9+ (canIuse)

ДЕМО

Изход:

CSS форма с вмъкната крива, използваща box-shadows

HTML :

<div id="a">
    <div id="b"></div>
</div>

CSS :

#a{
    overflow:hidden;
    border-radius:20px;
    position:relative;
    display:inline-block;
}
#a:before, #a:after{
    content:'';
    width: 100px;
    border-radius: 50%;
}
#a:before {
    height: 100px;
    float:left;    
    border: 1px solid black;
    background: grey;
}
#a:after {
    position:absolute;
    left:14px; top:-6px;
    height:114px;
    box-shadow: 1px 0px 0px 0px #000, 110px 0px 0px 68px #808080;
    background:none;
    z-index:-1;
}
#b {
    width: 200px;
    height: 100px;
    background:none;
    margin-left:-15px;
    border: 1px solid black;
    border-left:none;
    float:left;
    border-top-right-radius: 20px;
    border-bottom-right-radius: 20px;
}
person web-tiki    schedule 14.07.2014

Това е много интересен въпрос. Наскоро публикувах урок за това как да направя обратен радиус на границата в CSS (тук ) и мисля, че това лесно може да се адаптира за вашия случай.

Номерът е да се създаде обхват, който генерира обратната граница, като се използва много проста концепция - много дебели граници. И използвайте вътрешната секция, като ги скриете. Това, което трябва да направите в допълнение към предоставения от мен скрипт, е да добавите друг радиус на границата към горния ляв ъгъл, тъй като аз използвам само горния десен. Направете участъка подравнен вляво от елемента, който искате чрез абсолютно позициониране, и съответно увеличете височината/ширината на участъка и готово, имате своя обратен радиус на границата.

person Jon Mifsud    schedule 14.07.2012

Някой друг го е направил някъде от това, което намерих...

JSFiddle: http://jsfiddle.net/ajeN7/

и въпросът: CSS3 обърнат заоблен ъгъл

Надяваме се, че това помага!

person Rick Donohoe    schedule 08.05.2012
comment
@alp Просто премахнете -moz- от border-radius и трябва да сте добре. Това обаче не е съвсем правилният ефект. - person MetalFrog; 08.05.2012

Въведете абсолютно позициониран бял кръг без граници, който се намира зад сивия кръг с изместване. Ще трябва да зададете z-индекса на тъмния кръг, за да се уверите, че седи над белия кръг:

#c {
    position: absolute;
    border: 0;
    left: 30px;
    width: 100px;
    height: 100px;
    border-radius: 50px;
    background: white;
}

Демо.

person karim79    schedule 08.05.2012
comment
това не е оптимално поради липсващата черна рамка - person Alp; 08.05.2012