#css #flexbox #position #styling #shrink
#css #flexbox #положение #стиль #сжать
Вопрос:
Давайте предположим, что у нас есть «родительский» блок, который состоит из большого количества элементов, включая кнопку. Нажав эту кнопку, пользователь должен увидеть элемент «слайд», который будет закрывать родительский блок не на всю ширину, а только до самой кнопки (блоки 1 и 2, как вы увидите на ручке). Таким образом, слайд должен всегда заканчиваться непосредственно перед кнопкой. Даже при изменении ширины экрана. Как это можно реализовать?
<div class='parent'>
<div class='first'>1</div>
<div class='second'>2</div>
<div class='btn'>Button</div>
<div class='third'>3</div>
<div class='slide'>
Hello
</div>
</div>
.parent {
display: flex;
}
.first, .second, .third {
padding: 30px;
}
.first {
background-color: salmon;
flex-basis: 120px;
}
.second {
background-color: yellow;
flex-grow: 1
}
.third {
background-color: #56D7F7;
flex-grow: 1
}
.btn {
background-color: red;
cursor: pointer;
}
.slide {
position: absolute;
left: 0
}
Комментарии:
1. Поскольку вы хотите, чтобы ваш div покрывал 2 других div, и один из них имел динамическую ширину с помощью flex, я бы рекомендовал решение с помощью JS. Будет ли это проблемой?
Ответ №1:
Вы можете добиться этого с помощью немного Javascript, применяя стили CSS. Чтобы открыть слайд, вы увеличиваете его на вычисленную величину; чтобы закрыть, вы просто уменьшаете его до исходного размера.
Возможно, вы не захотите масштабировать элемент слайда, поскольку, если в нем есть какой-либо контент, он будет выглядеть немного искаженным, но не так уж много работы, чтобы изменить это решение, чтобы вместо него использовать переводы.
Я не думаю, что существует чистое CSS-решение, поскольку вам нужно вычислить положение кнопки, но, конечно, я могу ошибаться!
let open = false;
slide.style.setProperty('transform-origin', 'left top');
slide.style.setProperty('transition', 'linear .4s all');
button.addEventListener('click', (event) => {
if (open) {
slide.style.setProperty('transform', `scaleX(1)`);
open = false;
} else {
const first = slide.offsetWidth;
const last = button.offsetLeft;
const scale = last / first;
slide.style.setProperty('transform', `scaleX(${scale})`);
open = true;
}
})
.parent {
display: flex;
position: relative;
}
.first,
.second,
.third {
padding: 30px;
}
.first {
background-color: salmon;
flex-basis: 120px;
}
.second {
background-color: yellow;
flex-grow: 1
}
.third {
background-color: #56D7F7;
flex-grow: 1
}
.btn {
background-color: red;
cursor: pointer;
}
.slide {
position: absolute;
background-color: green;
width: 40px;
left: 0;
top: 0;
bottom: 0;
}
<div class='parent'>
<div class='first'>1</div>
<div class='second'>2</div>
<div id="button" class='btn'>Button</div>
<div class='third'>3</div>
<div id="slide" class='slide'>
<div class='hello'>
</div>
</div>
</div>