Неверный стек с коробкой-тенью и трансформацией
Я создал фигуру, которая представляет собой страницу с тенью, которая становится больше к нижней части.
body {
background: #dddddd;
}
div {
background: white;
margin: 40px auto;
height: 300px;
width: 300px;
position: relative;
padding: 10px;
}
div:before,
div:after {
height: 96%;
z-index: -10;
position: absolute;
content: "";
left: 8px;
top: 2%;
width: 30%;
max-width: 300px;
background: transparent;
box-shadow: -10px 0px 10px rgba(0, 0, 0, 0.5);
transform: rotate(1.5deg);
}
div:after {
transform: rotate(-1.5deg);
right: 8px;
left: auto;
box-shadow: 10px 0px 10px rgba(0, 0, 0, 0.5);
}
<div></div>
Мне нужно, чтобы это было повернуто, но когда я пытаюсь добавить transform: rotate(10deg)
, иллюзия box-shadow
разрушается и идет поверх родительского слоя.
body {
background: #dddddd;
}
div {
background: white;
margin: 40px auto;
height: 300px;
width: 300px;
position: relative;
padding: 10px;
transform: rotate(10deg);
}
div:before,
div:after {
height: 96%;
z-index: -10;
position: absolute;
content: "";
left: 8px;
top: 2%;
width: 30%;
max-width: 300px;
background: transparent;
box-shadow: -10px 0px 10px rgba(0, 0, 0, 0.5);
transform: rotate(1.5deg);
}
div:after {
transform: rotate(-1.5deg);
right: 8px;
left: auto;
box-shadow: 10px 0px 10px rgba(0, 0, 0, 0.5);
}
<div></div>
Я нашел этот вопрос: какие свойства CSS создают контекст укладки? но, кажется, нет предложенного решения для моего требование.
Есть ли какие-либо хорошие решения, которые будут работать в моем случае? Я не возражаю, если они естьSVG
, filter
, canvas
или любая другая вещь, если она поддерживается достаточно хорошо.3 ответа:
Примечание: Этот ответ не описывает, как исправить проблему контекста укладки, которая видна в вашем подходе. Это всего лишь несколько альтернативных подходов, которые могут быть использованы для достижения аналогичного эффекта. преимущество этих подходов заключается в том, что онидолжны работать в IE10+ и не требуют каких-либо дополнительных элементов .
Я бы все равно рекомендовал ответ vals, если поддержка IE не является обязательной.
Метод 1: Перспектива Transform
Это почти похоже на то, что вы использовали, за исключением того, что он использует один псевдо-элемент, повернутый с перспективой, чтобы произвести тени. Поскольку используется только один псевдо-элемент, другой псевдо может быть использован для добавления белого переднего плана над тенями.
body { background: #dddddd; } div { position: relative; height: 300px; width: 300px; padding: 10px; margin: 40px auto; transform: rotate(10deg); } div:before, div:after { position: absolute; content: ''; top: 0px; } div:before { height: 100%; width: 100%; left: 0px; background: white; } div:after { height: 98%; width: 97%; left: 1.5%; transform-origin: bottom; transform: perspective(125px) rotateX(1deg); box-shadow: 10px 0px 10px rgba(0, 0, 0, .5), -10px 0px 10px rgba(0, 0, 0, .5); z-index: -1; }
<div></div>
Метод 2: Линейные Градиенты
Мы можем использовать фоновые изображения
linear-gradient
и расположить их соответствующим образом, чтобы произвести эффект, подобный произведенному у ящика-тени. Но, как вы можете видеть на выходе, он не совсем соответствует тени, потому что размытые области не совпадают.Здесь мы используем следующее:
- одно небольшое угловое линейное градиентное изображение (
to top left
) для получения тени на левой стороне коробки.- Еще одно небольшое угловое линейное градиентное изображение (
to top right
) для получения тени на правой стороне коробки.- большое линейно-градиентное изображение для области белого цвета (которая является почти сплошной цвет). Здесь вместо сплошного цвета используется градиент, поскольку размер градиентного изображения можно регулировать.
body { background: #dddddd; } div { margin: 40px auto; height: 300px; width: 300px; transform: rotate(10deg); backface-visibility: hidden; background: linear-gradient(to right, transparent 0.1%, white 0.1%), linear-gradient(to top left, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .3) 5%, transparent 50%), linear-gradient(to top right, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .3) 5%, transparent 50%); background-size: 280px 100%, 10px 97%, 10px 97%; background-position: 10px 0px, left top, right top; background-repeat: no-repeat; background-origin: border-box; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> <div></div>
Нижняя часть градиента все еще не получает размытия, которое видно на выходе
box-shadow
. При необходимости это может быть достигнуто в некоторой степени путем добавления еще большего количества градиентов, как в приведенном ниже фрагменте.
body { background: #dddddd; } div { margin: 40px auto; height: 300px; width: 300px; transform: rotate(10deg); backface-visibility: hidden; background: linear-gradient(to right, transparent 0.1%, white 0.1%), linear-gradient(to top left, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .3) 5%, transparent 50%), linear-gradient(to top right, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .3) 5%, transparent 50%), linear-gradient(to bottom left, rgba(0, 0, 0, 0), rgba(0, 0, 0, .3) 5%, transparent 60%), linear-gradient(to bottom right, rgba(0, 0, 0, 0), rgba(0, 0, 0, .3) 5%, transparent 70%); background-size: 280px 100%, 10px 97%, 10px 97%, 10px 2.5%, 10px 2.5%; background-position: 10px 0px, left top, right top, left 99.25%, right 99.25%; background-repeat: no-repeat; background-origin: border-box; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> <div></div>
Если вы используете другой
div
, это устраняет проблему, которую вы испытываете, так что цвет фона находится на внутреннемdiv
, а поворот-на внешнемdiv
.В противном случае вам может потребоваться использовать другой метод, чтобы получить тот же результат.
body { background: #dddddd; } .two{ background: white; height: 300px; width: 300px; padding: 10px; } div.one { margin: 40px auto; height: 300px; width: 300px; position: relative; transform: rotate(10deg); } div.one:before, div.one:after { height: 96%; z-index: -10; position: absolute; content: ""; left: 8px; top: 2%; width: 30%; max-width: 300px; background: transparent; box-shadow: -10px 0px 10px rgba(0, 0, 0, 0.5); transform: rotate(1.5deg); } div.one:after { transform: rotate(-1.5deg); right: 8px; left: auto; box-shadow: 10px 0px 10px rgba(0, 0, 0, 0.5); }
<div class="one"> <div class="two"> </div> </div>
Когда вы войдете в мир трансформаций, сами трансформации решат некоторые из проблем, которые они создают. Вы можете решить эту задачу с помощью 3d-эквивалента z-индекса, координаты Z
К сожалению, это не будет работать в IE (я считаю, пока они не поддерживают сохранить 3d)
body { background: #dddddd; } div { background: white; margin: 40px auto; height: 300px; width: 300px; position: relative; padding: 10px; transform: translateZ(1px) rotate(10deg); transform-style: preserve-3d; } div:before, div:after { height: 96%; z-index: -10; position: absolute; content: ""; left: 8px; top: 2%; width: 30%; max-width: 300px; background: transparent; box-shadow: -10px 0px 10px rgba(0, 0, 0, 0.5); transform: translateZ(-1px) rotate(1.5deg); } div:after { transform: translateZ(-1px) rotate(-1.5deg); right: 8px; left: auto; box-shadow: 10px 0px 10px rgba(0, 0, 0, 0.5); }
<div></div>