Как сделать закругленные углы как внутри коробки, так и по ее краям? - PullRequest
40 голосов
/ 30 января 2011

Полагаю, название довольно сложно понять, поэтому я объясню.Я пытаюсь добиться этого эффекта:

enter image description here

(прямоугольник с закругленными углами и границей с закругленными границами).

У меня естьудалось это сделать, используя свойство background-clip:

enter image description here

(закругленные углы для границы, но не для внутреннего поля)

Вопрос в том, как мне получить закругленные углы для внутреннего поля?

Спасибо!

РЕДАКТИРОВАТЬ

HTML-код, который я использую:

<header class="body template-bg template-border radius-all">
        <nav>
            <ul>
                <li><a href="#">Link 1</a></li>
                <li><a href="#">Link 2</a></li>
                <li><a href="#">Link 3</a></li>
                <li><a href="#">Link 4</a></li>
            </ul>
        </nav>
    </header>

И CSS:

.radius-all {
  border-radius: 10px;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
}

.template-bg {
  background: #FFF;
  -moz-background-clip: padding;
  -webkit-background-clip: padding;
  background-clip: padding-box;
}

.template-border {
  border: 5px solid rgba(255, 255, 255, 0.2);
}

Ответы [ 8 ]

37 голосов
/ 30 января 2011

Расчеты внутренней границы

Сначала вам нужно удалить -vendor-background-clip: padding-box или установить для них значение border-box по умолчанию, чтобы достичь радиуса внутренней границы.

Радиус внутренней границы рассчитывается как разность радиуса внешней границы (border-radius) и ширины границы (border-width), такая что

inner border radius = outer border radius - border width

Всякий раз, когда border-width больше, чем border-radius, радиус внутренней границы отрицателен, и вы получаете несколько неловких перевернутых углов. В настоящее время я не верю, что есть свойство для настройки inner-border-radius, поэтому вам придется рассчитать его вручную.

В вашем случае:

inner border radius = 6px - 5px = 1px

Ваш новый CSS должен быть:

.radius-all { border-radius: 6px; -moz-border-radius: 6px; -webkit-border-radius: 6px; }
.template-bg { background: #FFF; }
.template-border { border: 5px solid rgba(255, 255, 255, 0.2); }

Просто вычтите значения border-radius (6px) из значения border-width (5px), чтобы получить желаемый радиус внутренней границы:


Код, который работает для меня

Протестировано на Firefox 3.x, Google Chrome и Safari 5.0

 .radius-all { border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; }
.template-bg { background: #FFF; }
.template-border { border: 5px solid rgba(0, 0, 0, 0.2); } /* Note that white on white does not distinguish a border */

Добавление цветовых оверлеев в JavaScript

<script type="text/javascript">
    var bodyBgColor = document.getElementsByTagName('body')[0].style.backgroundColor;;

    // insert opacity decreasing code here for hexadecimal

    var header = document.getElementsByTagName('header')[0];
    header.style.backgroundColor = bodyBgColor;
</script>

Я не совсем уверен, как выполнять шестнадцатеричную арифметику в JavaScript, но я уверен, что вы можете найти алгоритм в Google.


Применение общих границ

Используете ли вы отдельное поле <div> для своей границы через свойство background? Если это так, вам нужно применить border-radius и его свойства, специфичные для поставщика, как в рамке, так и во внутренней рамке:

<div id="border-box" style="border-radius: 5px;">
    <div id="inner-box" style="border-radius: 5px;">
    </div>
</div>

Гораздо более эффективный способ, если бы внутренняя коробка управляла собственной границей:

<div id="inner-box" style="border: 4px solid blue; border-radius: 5px">
    <!-- Content -->
</div>

С точки зрения CSS, вы можете просто объявить класс .rounded-border и применить его к каждому прямоугольнику с закругленными границами:

.rounded-borders {
    border-radius: 5px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    -khtml-border-radius: 5px;
}

И применить класс к любым клеткам, у которых будут закругленные границы:

<div id="border-box" class="rounded-borders">
    <div id="inner-box" class="rounded-borders">
    </div>
</div>

Для одного элемента box вам все равно потребуется объявить размер границы для отображения:

<style type="text/css">
    #inner-box { border: 4px solid blue; }
</style>

<div id="inner-box" class="rounded-borders">
</div>
18 голосов
/ 29 декабря 2011

Другое решение состоит в том, чтобы совмещать внутренние и внешние границы в сочетании с border-radius - «подделывать» границу, используя <spread-radius> свойства box-shadow. Это создает сплошную тень, которая может легко перейти за обычную границу.

Например, чтобы достичь границы 4px и радиуса белой границы 4px, попробуйте следующее:

/* rounded corners */
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;

/* drop shadow */
-webkit-box-shadow: 0px 0px 0px 4px #fff;
-moz-box-shadow: 0px 0px 0px 4px #fff;
box-shadow: 0px 0px 0px 4px #fff;

Если вы хотите добавить «настоящую» тень для всего контейнера, вы можете просто связать свои теневые операторы следующим образом:

/* drop shadow */
-webkit-box-shadow: 0px 0px 0px 4px rgba(255,255,255,1.0),
        1px 1px 8px 0 rgba(0,0,0,0.4);
-moz-box-shadow: 0px 0px 0px 4px rgba(255,255,255,1.0),
        1px 1px 8px 0 rgba(0,0,0,0.4);
box-shadow: 0px 0px 0px 4px rgba(255,255,255,1.0),
        1px 1px 8px 0 rgba(0,0,0,0.4);

Примечание: Имейте в виду, что порядок утверждений - это порядок, в котором они будут отображаться.

Единственное, о чем следует опасаться, это то, что начальная «искусственная граница» будет перекрывать первые X пикселей (где X - ширина границы) любой тени, которую вы хотите под ней (и объединять, если вы используете RGBa непрозрачность на нем ниже 100%.)

Так что он не будет работать в всех ситуациях, но получит большинство. Я использую это довольно часто, когда обычные границы не идеальны.

15 голосов
/ 28 февраля 2013

Поскольку для CSS не существует такого понятия, как inner-border-radius, браузеры по умолчанию устанавливают значение border-radius - border-width. Если вам это не нравится, типичным решением является создание двух элементов div с границами для имитации радиуса внутренней границы, но это решение вносит больше дизайна в HTML. Также будет неприятно, если это общий шаблон границ, используемый на сайте.

Мне удалось найти способ сохранить все это в css, создав внутренний div, используя :after и content: "". Так что для вашего случая это будет:

.template-border {
    position: relative;
    border-radius: 5px;
    background-color: #000;
    border: 10px solid #000;
    z-index: -2;
}

.template-border:after {
    content: "";
    display: block;
    position: absolute;
    width: 100%;
    height: 100%;
    border-radius: 5px;
    background-color: #FFF;
    z-index: -1;
}
3 голосов
/ 26 января 2017

Основываясь на идее Лео Ву, вот мое решение:

.my-div
{
  background-color: white;
  border: solid 20px black;
  border-radius: 10px;
  box-shadow: 0 0 10px black;
  height: 100px;
  left: 30px;
  position: relative;
  top: 20px;
  width: 200px;
}
.my-div:before
{
  background-color: white;
  border-radius: 5px;
  content: "";
  display: block;
  height: calc(100% + 20px);
  left: -10px;
  position: absolute;
  top: -10px;
  width: calc(100% + 20px);
  z-index: 1;
}
.some-content
{
  height: calc(100% + 20px);
  left: -10px;
  position: relative;
  top: -10px;
  width: calc(100% + 20px);
  z-index: 3;
}
.some-header
{
  background-color: green;
  border-radius: 5px 5px 0 0;
  height: 30px;
}
<html>
	<body>
		<div class="my-div">
			<div class="some-content">
				<div class="some-header">my title</div>
				<div>some other content</div>
			</div>
		</div>
	</body>
</html>
2 голосов
/ 19 января 2017

Проблема не в кодировании CSS, а в математике круга. По сути ваш border-inner-radius (я знаю, что это свойство не существует) равно border-radius - border-width.

Проще всего определить, каким должен быть ваш внутренний радиус, а затем добавьте ширину границы для достижения желаемого эффекта.

border-inner-radius + border-width = border-radius

2 голосов
/ 30 января 2011

Вам нужно иметь два элемента div, один внутри другого, и использовать кросс-браузерный закругленный угол css, например:

.small-rounded {
    border: 1px solid ##000;
    -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px;
    -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px;
    -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px;
    -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px;
    border-radius: 5px;
}
0 голосов
/ 18 марта 2019

На всякий случай, если кто-то ищет в Google этот ответ и будет отправлен сюда, вот простой и легкий способ сделать это ...

Пример HTML ...

<div class="wrapper">
    <div class="content">
        your content goes here
    </div>
</div>

Пример CSS ...

.wrapper {
    border-radius: 25px;
    border: solid 25px blue;
    background-color: blue;
}
.content {
    border-radius: 10px;
    background-color: white;
}

... Presto. enter image description here

0 голосов
/ 31 декабря 2015

Вам нужно сделать border-radius равным значению больше, чем border-width, пока вы не начнете видеть кривую. Это не установленная формула, чтобы установить border-radius на + 1px больше, чем border-width. Тем не менее, это будет положительная ценность, безусловно. Вам нужно экспериментировать в разных браузерах, где это необходимо, пока вы не увидите наименьшее возможное значение радиуса границы, которое вам подходит в большинстве браузеров. (Некоторые браузеры могут не поддерживать это.) Например, в Google Chrome я установил ширину границы в 10 пикселей, но мне пришлось установить радиус границы в 13 пикселей, прежде чем я начал видеть подобие кривой внутренней границы, в то время как 15 пикселей работал еще лучше.

...