Как заставить 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.

Ответы:


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


3
спасибо за это исправление. попробовал это сегодня в сафари (v6.0.2) и работал там для меня!
billythetalented

6
однако это сломает любые тени на элементе.
Джек Джеймс

1
Это работает и для оболочек с абсолютно позиционированными детьми, в отличие от другого решения. Ницца!
Дан Телло

2
с использованием Chrome 42.0.2311.90 (64-разрядная версия), и это исправление все еще требуется ... спасибо!
Симон

2
ваши решения удаляют тени родительского элемента.
ABDeveloper

107

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


@ Сифу: ты просто не прав. По какой-то причине добавление 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/


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


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/


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


Я думаю, что вы можете сократить этот путь клипа: inset (0%); ... просто наличие пути клипа, кажется,
Jakob E

Вот это да. Это идеальный ответ.
Шашанк Бхатт


4

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



2

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

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

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

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

-webkit-mask-image:#fff;

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


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

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;
        }
    }
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.