Как заставить CSS3 закругленные углы скрыть переполнение в Chrome / Opera

147

Мне нужно закруглить углы родительского элемента div, чтобы замаскировать содержимое от его ребенка. overflow: hiddenработает в простых ситуациях, но ломается в браузерах на основе webkit и в Opera, когда родительский элемент позиционируется относительно или абсолютно.

Это работает в Firefox и IE9:

CSS

#wrapper {
  width: 300px;
  height: 300px;
  border-radius: 100px;
  overflow: hidden;
  position: absolute;
}

#box {
  width: 300px;
  height: 300px;
  background-color: #cde;
}

HTML

<div id="wrapper">
  <div id="box"></div>
</div>

Пример на JSFiddle

Спасибо за помощь!

ОБНОВЛЕНИЕ: ошибка, вызывающая эту проблему, была исправлена ​​в Chrome. Однако я не перепроверял Opera или Safari.

jmotes
источник

Ответы:

183

Я нашел другое решение этой проблемы. Это похоже на еще одну ошибку в WebKit (или, возможно, Chrome), но это работает. Все, что вам нужно сделать - это добавить CSS-маску WebKit к элементу #wrapper. Вы можете использовать однопиксельное изображение PNG и даже включить его в CSS, чтобы сохранить HTTP-запрос.

#wrapper {
width: 300px; height: 300px;
border-radius: 100px;
overflow: hidden;
position: absolute; /* this breaks the overflow:hidden in Chrome/Opera */

/* this fixes the overflow:hidden in Chrome */
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
}

#box {
width: 300px; height: 300px;
background-color: #cde;
}​

Пример JSFiddle

graycrow
источник
3
спасибо за это исправление. попробовал это сегодня в сафари (v6.0.2) и работал там для меня!
billythetalented
6
однако это сломает любые тени на элементе.
Джек Джеймс
1
Это работает и для оболочек с абсолютно позиционированными детьми, в отличие от другого решения. Ницца!
Дан Телло
2
с использованием Chrome 42.0.2311.90 (64-разрядная версия), и это исправление все еще требуется ... спасибо!
Симон
2
ваши решения удаляют тени родительского элемента.
ABDeveloper
107

Добавьте z-index к элементу border-radius, и он замаскирует вещи внутри него.

Jackolai
источник
@ Сифу: ты просто не прав. По какой-то причине добавление z-индекса, как предлагалось, решило именно эту проблему для меня (в текущей версии Chrome), и это более простое, более общее решение, чем основной ответ.
Ник Ф
7
@simon: помните, что для того, чтобы z-index имел эффект, должны быть выполнены определенные условия (например, позиция должна быть установлена). Смотрите здесь для деталей.
Ник Ф
@NickF - это была ошибка в Chrome (-ium); -webkit-mask-image: -webkit-radial-gradient(circle, white, black);Это был эффективный обходной путь, но, к счастью, ошибка была исправлена ​​в последнем обновлении, которое я получил для Chrome.
Симон
z-index 1 для контейнера. z-index -1 для абсолютного элемента решил это за меня.
aZtraL-EnForceR
Этот работал для меня. Вышеупомянутое решение обертки не делает.
Рувен
58

Не смотря ни на что, мне удалось решить проблему, добавив дополнительный div между оболочкой и коробкой.

CSS

#wrapper {
    position: absolute;
}

#middle {
    border-radius: 100px;
    overflow: hidden; 
}

#box {
    width: 300px; height: 300px;
    background-color: #cde;
}

HTML

<div id="wrapper">
    <div id="middle">
        <div id="box"></div>
    </div>
</div>

Спасибо всем, кто помог!

http://jsfiddle.net/5fwjp/

jmotes
источник
12
Это работает, потому что позиционированные элементы не обрезают свое содержимое до своего радиуса границы в Webkit. Этот дополнительный слой просто делает так, чтобы div с border-radius НЕ позиционировался, а просто находился внутри позиционированного элемента.
Дэниэл Бердсли
9
Вы случайно не знаете, является ли это ошибкой / предполагаемым поведением?
jmotes
4
+1 голос за ошибку ... Если у вас есть галерея изображений, которая автоматически генерирует div и устанавливает абсолютное положение, тогда эта "особенность" действительно полезна ...
inf3rno
@RunLoop Я только что протестировал jsfiddle в Safari 7.1 и работает нормально. Можете ли вы быть более конкретным о том, что не работает?
jmotes
1
Наш коллега графический дизайнер на самом деле «обнаружил» это за 20 секунд до нахождения этого ответа: D
Pere
18

непрозрачность: 0,99; на обертке решить баг webkit

flavi1
источник
2
transform: translateY(0);является альтернативой, которая достигает того же результата, не влияя на визуальное представление объекта (если вы не используете перспективу).
КОНТУР
15

Кажется, это работает:

.wrap {
    -webkit-transform: translateZ(0);
    -webkit-mask-image: -webkit-radial-gradient(circle, white 100%, black 100%);
}

http://jsfiddle.net/qWdf6/82/

nakrill
источник
4
transform: translateZ(0)мне достаточно.
Калвн
Обратите внимание, что это (в частности translateZ) неявно включит аппаратное ускорение для ваших элементов, что, к сожалению, в некоторых случаях открывает новую банку с червями.
Дольдт
transform: translateZ(0)тоже работал на меня. В моем случае это неплохая идея, что этот пункт аппаратно ускорен.
Себастьян Лорбер
9

Поддерживается в последних Chrome, Opera и Safari, вы можете сделать это:

-webkit-clip-path: inset(0 0 0 0 round 100px);
clip-path: inset(0 0 0 0 round 100px);

Вы обязательно должны проверить инструмент http://bennettfeely.com/clippy/ !

Antoni
источник
Я думаю, что вы можете сократить этот путь клипа: inset (0%); ... просто наличие пути клипа, кажется,
Jakob E
Вот это да. Это идеальный ответ.
Шашанк Бхатт
6

Не ответ, но это ошибка в источнике Chromium: http://code.google.com/p/chromium/issues/detail?id=62363

К сожалению, не похоже, что кто-то работает над этим. :(

Райана
источник
1
И через 3 года он все еще не был исправлен>. <
Натан Хорнби
4

измените непрозрачность родительского элемента с рамкой, и это позволит организовать упорядоченные элементы. Это чудесно сработало для меня после нескольких часов исследований и неудачных попыток. Это было так же просто, как добавить непрозрачность 0,99, чтобы реорганизовать этот процесс рисования в браузерах. Проверьте http://philipwalton.com/articles/what-no-one-told-you-about-z-index/

Рами Авар
источник
3

На мой взгляд, ни одно из решений не сработало, только с использованием:

-webkit-mask-image: -webkit-radial-gradient(circle, white, black);

на элемент обертки сделал свою работу.

Вот пример: http://jsfiddle.net/gpawlik/qWdf6/74/

Гжегож Павлик
источник
2

основанный на превосходном ответе серой вороны ...

Вот более реальный пример, в котором есть два специальных элемента с некоторым содержанием наполнителя. Я заменил жестко запрограммированный фон png на шестнадцатеричное значение, т.е.

-=-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);

заменяется на

-webkit-mask-image:#fff;

Смотрите это JSFiddle ... http://jsfiddle.net/hqLkA/

gts101
источник
1

Вот посмотрите, как я это сделал; Jsfiddle

С помощью кода, который я вставил, мне удалось заставить его работать на Webkit (Chrome / Safari) и Firefox. Я не знаю, работает ли он с последней версией Opera. Да, он работает под последней версией Opera.

#wrapper {
  width: 300px; height: 300px;
  border-radius: 100px;
  overflow: hidden;
  position: absolute; /* this breaks the overflow:hidden in Chrome/Opera */
}

#box {
  width: 300px; height: 300px;
  background-color: #cde;
  border-radius: 100px;
  -webkit-border-radius: 100px;
  -moz-border-radius: 100px;
  -o-border-radius: 100px;
}
Лабиринт
источник
Зачем border-radiusвообще ставить обертку в такой ситуации, вы получите тот же результат, просто включив ее #box. Кроме того, если #boxрадиус границы предназначен только для исправления WebKit, вы можете просто включить это -webkit-свойство.
Роберт
Лабиринт, это может работать в некоторых ситуациях, но в моем случае я ищу решение, которое не преобразует форму коробки (а оболочка все еще работает как маска). Мой пример был очень упрощен, но я пытаюсь использовать оболочку, чтобы скрыть капли от коробки (используя отступы на оболочке, чтобы сделать только тени, которые я хочу видеть).
jmotes
1
Спасибо за помощь, хотя лабиринт! Ваше решение помогло мне подумать о проблеме более критически. Кстати, вы можете игнорировать изменения, которые я внес в ваш пост. Я хотел сделать это самостоятельно. Извините :)
jmotes
@ user480837 Нет проблем, приятель, рад, что я помог. :)
Лабиринт
1
@Maze Это не сработает, если применить какую-либо границу: jsfiddle.net/ptW85/228
антитоксический
1

Я попробовал каждый ответ, но безуспешно. После нескольких часов исследований я нашел решение этой проблемы. Использование этих свойств в вашем классе не позволит элементам div переполнять контейнер.

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
}
Samin
источник
0

Если вы хотите создать маску для изображения и расположить изображение внутри контейнера, не устанавливайте атрибут 'position: absolute'. Все, что вам нужно сделать, это изменить поля слева и поля справа. Chrome / Opera будет придерживаться правил переполнения: скрытый и радиус границы.

// Breaks in Chrome/Opera.
    .container {
        overflow: hidden;
        border-radius: 50%;
        img {
            position: absolute;
            left: 20px;
            right: 20px;
        }
    }

// Works in Chrome/Opera.
    .container {
        overflow: hidden;
        border-radius: 50%;
        img {
            margin-left: 20px;
            margin-right: 20px;
        }
    }
user6039997
источник