3 列流体布局,根据面板位置扩展中间 div
3 column fluid layout with expanding middle div based on panel positions
对 not-super-descriptive 标题表示歉意,我很难用语言表达问题,所以让我再试一次更详细。
我正在使用 flexbox 创建一个 3 列布局,我希望在折叠左/右列(菜单面板)中的一个(或两个)时展开中间列。
这是我遇到的问题的屏幕截图。
https://www.dropbox.com/s/d9mcg7q71hwogog/example.jpg?dl=0
当面板打开(展开)时,所有三列都会填满屏幕宽度。这很好。但是,当两个侧面板中的任何一个处于动画状态(折叠)时,中心列不会扩展以填充额外的 space。这样不好。
我不确定这是否与我使用 translateX 来切换左/右面板这一事实有关,这只是一个理论,但也许中心栏没有意识到左/右列已移动位置,因此它不知道还有更多 space 需要填充?
要遵循的代码:
CSS:
<style>
body {
background-color: lightslategrey;
}
.red {
background-color: lightcoral;
}
.green {
background-color: lightgreen;
}
.grey {
background-color: lightslategray;
}
* {
box-sizing: border-box;
}
.ls-toggle, .rs-toggle {
//position: fixed;
z-index: 1;
cursor: pointer;
transition: 0.5s;
}
#left-sidebar, #right-sidebar {
width: 250px;
height: 100vh;
transition: 0.5s;
}
#left-sidebar.is-closed {
transform: translateX(-80%);
}
#right-sidebar.is-closed {
transform: translateX(80%);
}
.ls-top, .rs-top {
display: flex;
width:100%;
height:35px;
align-items: center;
justify-content: flex-end;
background-color: lightslategrey;
}
.rs-top {
justify-content: flex-start;
}
#mw-content {
width: 100%;
height: 100vh;
}
</style>
HTML:
<div class="d-flex">
<div id="left-sidebar" class="col- red">
<div class='ls-top grey'>
<button class="ls-toggle"><i class="fas fa-angle-left fa-2x"></i></button>
</div>
</div>
<div id="mw-content" class="col green">
<h3> Main Window Content.</h3>
</div>
<div id="right-sidebar" class="col- red">
<div class='rs-top grey'>
<button class="rs-toggle"><i class="fas fa-angle-right fa-2x"></i></button>
</div>
</div>
</div>
JS:
$(document).ready(function () {
var lsToggleBtn = document.querySelector('.ls-toggle');
var lsSidebar = document.querySelector('#left-sidebar');
var rsToggleBtn = document.querySelector('.rs-toggle');
var rsSidebar = document.querySelector('#right-sidebar');
lsToggleBtn.addEventListener('click', function () {
lsToggleBtn.classList.toggle('is-closed');
lsSidebar.classList.toggle('is-closed');
});
rsToggleBtn.addEventListener('click', function () {
rsToggleBtn.classList.toggle('is-closed');
rsSidebar.classList.toggle('is-closed');
});
});
我尝试过的事情:
- 正在将 flex: 1 1 auto 添加到主要内容容器 (mw-content)。
- 将 flex: 0 添加到 l/r 侧边栏容器并将 flex: 1 1 auto 添加到主要内容容器
- 将主内容容器的宽度设置为 100%
- 尝试在主内容容器上使用 translateX 并在单击左侧边栏时设置新宽度
显然 none 这些想法奏效了,我承认我不是最擅长使用 flexbox 的人,所以我确定我只是遗漏了一些基本的东西,但我会很感激你的任何建议好人可能有。 :)
这是一个示例,说明如何使用原版实现此目的 javascript。
两个函数,一个是跟踪部分元素的折叠并调整中间部分的大小。它检查点击并将元素(部分)id 添加到数组,条件检查数组,如果数组 includes
两个外部部分 id,我们使用 style.transform
调整中间部分的大小 => scale()
。第二个函数重置可折叠元素。
在代码片段中找到更多信息。
let clicked = [];
const middle = document.querySelector('#sect2')
let section = document.querySelectorAll('.sect')
let reset = document.querySelector('#reset')
// function
const resizeOnCollapse = (els) => {
// loop over the three sections
els.forEach(sect => {
// do not allow the middle section to be collapsed
if (sect.id !== 'sect2') {
// eventlistener to check a click on the outer sections
sect.addEventListener('click', (e) => {
// push the clicked elements into an array
clicked.push(e.target.id)
// set the event targets width to 0
// essentially collapsing it from view
e.target.style.width = '0px';
// conditional that checks if the array
// includes the two outer sections
if (clicked.includes('sect1') && clicked.includes('sect3')) {
// resize the middle section using
// transform: scale()
middle.style.transform = 'scale(1.2)'
// transition animation on the transform
middle.style.transition = 'transform .5s ease-out'
}
})
}
})
}
// function to reset the elements and reset the array
const resetEls = (el, section) => {
// eventlistener on click
el.addEventListener('click', () => {
// reset the array
clicked = [];
// loop over the sections
section.forEach((sect) => {
// reset the width essentially uncollapsing the sections
sect.style.width = '30vw';
// reset the middle transform rule, scale() to 1
sect.style.transform = 'scale(1)';
})
})
}
// call the functions
resetEls(reset, section)
resizeOnCollapse(section)
#main {
display: flex;
justify-content: space-around;
}
.sect {
width: 30vw;
height: 80vh;
}
#sect1 {
background-color: red;
}
#sect2 {
background-color: blue;
}
#sect3 {
background-color: green;
}
<button id="reset">reset</button>
<div id="main">
<div id="sect1" class="sect">
</div>
<div id="sect2" class="sect">
</div>
<div id="sect3" class="sect">
</div>
</div>
您需要尝试使用“position: absolute”并添加另外两个 classList.toggle 函数
$(document).ready(function () {
var mwContent = document.querySelector('#mw-content'); // !!
var lsToggleBtn = document.querySelector('.ls-toggle');
var lsSidebar = document.querySelector('#left-sidebar');
var rsToggleBtn = document.querySelector('.rs-toggle');
var rsSidebar = document.querySelector('#right-sidebar');
lsToggleBtn.addEventListener('click', function () {
lsToggleBtn.classList.toggle('is-closed');
lsSidebar.classList.toggle('is-closed');
mwContent.classList.toggle('ls-pos'); // here
});
rsToggleBtn.addEventListener('click', function () {
rsToggleBtn.classList.toggle('is-closed');
rsSidebar.classList.toggle('is-closed');
mwContent.classList.toggle('rs-pos'); // here
});
});
body {
background-color: lightslategrey;
margin: 0;
overflow: hidden;
}
.red {
background-color: lightcoral;
}
.green {
background-color: lightgreen;
}
.grey {
background-color: lightslategray;
}
* {
box-sizing: border-box;
}
.d-flex {
display: flex;
position: relative;
}
.ls-toggle,
.rs-toggle {
cursor: pointer;
transition: 0.5s;
}
#left-sidebar {
position: absolute;
left: 0;
width: 250px;
height: 100vh;
transition: 0.5s;
}
#right-sidebar {
position: absolute;
right: 0;
width: 250px;
height: 100vh;
transition: 0.5s;
}
#left-sidebar.is-closed {
transform: translateX(-80%);
}
#right-sidebar.is-closed {
transform: translateX(80%);
}
.ls-top,
.rs-top {
display: flex;
width: 100%;
height: 35px;
align-items: center;
justify-content: flex-end;
background-color: lightslategrey;
}
.rs-top {
justify-content: flex-start;
}
#mw-content {
position: absolute;
right: 250px;
left: 250px;
height: 100vh;
transition: 0.5s;
}
.ls-pos {
left: 50px !important;
transition: 0.5s;
}
.rs-pos {
right: 50px !important;
transition: 0.5s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="d-flex">
<div id="left-sidebar" class="col red">
<div class='ls-top grey'>
<button class="ls-toggle"><i class="fas fa-angle-left fa-2x"></i></button>
</div>
</div>
<div id="mw-content" class="col green">
<h3> Main Window Content.</h3>
</div>
<div id="right-sidebar" class="col red">
<div class='rs-top grey'>
<button class="rs-toggle"><i class="fas fa-angle-right fa-2x"></i></button>
</div>
</div>
</div>
对 not-super-descriptive 标题表示歉意,我很难用语言表达问题,所以让我再试一次更详细。
我正在使用 flexbox 创建一个 3 列布局,我希望在折叠左/右列(菜单面板)中的一个(或两个)时展开中间列。
这是我遇到的问题的屏幕截图。 https://www.dropbox.com/s/d9mcg7q71hwogog/example.jpg?dl=0
当面板打开(展开)时,所有三列都会填满屏幕宽度。这很好。但是,当两个侧面板中的任何一个处于动画状态(折叠)时,中心列不会扩展以填充额外的 space。这样不好。
我不确定这是否与我使用 translateX 来切换左/右面板这一事实有关,这只是一个理论,但也许中心栏没有意识到左/右列已移动位置,因此它不知道还有更多 space 需要填充?
要遵循的代码:
CSS:
<style>
body {
background-color: lightslategrey;
}
.red {
background-color: lightcoral;
}
.green {
background-color: lightgreen;
}
.grey {
background-color: lightslategray;
}
* {
box-sizing: border-box;
}
.ls-toggle, .rs-toggle {
//position: fixed;
z-index: 1;
cursor: pointer;
transition: 0.5s;
}
#left-sidebar, #right-sidebar {
width: 250px;
height: 100vh;
transition: 0.5s;
}
#left-sidebar.is-closed {
transform: translateX(-80%);
}
#right-sidebar.is-closed {
transform: translateX(80%);
}
.ls-top, .rs-top {
display: flex;
width:100%;
height:35px;
align-items: center;
justify-content: flex-end;
background-color: lightslategrey;
}
.rs-top {
justify-content: flex-start;
}
#mw-content {
width: 100%;
height: 100vh;
}
</style>
HTML:
<div class="d-flex">
<div id="left-sidebar" class="col- red">
<div class='ls-top grey'>
<button class="ls-toggle"><i class="fas fa-angle-left fa-2x"></i></button>
</div>
</div>
<div id="mw-content" class="col green">
<h3> Main Window Content.</h3>
</div>
<div id="right-sidebar" class="col- red">
<div class='rs-top grey'>
<button class="rs-toggle"><i class="fas fa-angle-right fa-2x"></i></button>
</div>
</div>
</div>
JS:
$(document).ready(function () {
var lsToggleBtn = document.querySelector('.ls-toggle');
var lsSidebar = document.querySelector('#left-sidebar');
var rsToggleBtn = document.querySelector('.rs-toggle');
var rsSidebar = document.querySelector('#right-sidebar');
lsToggleBtn.addEventListener('click', function () {
lsToggleBtn.classList.toggle('is-closed');
lsSidebar.classList.toggle('is-closed');
});
rsToggleBtn.addEventListener('click', function () {
rsToggleBtn.classList.toggle('is-closed');
rsSidebar.classList.toggle('is-closed');
});
});
我尝试过的事情:
- 正在将 flex: 1 1 auto 添加到主要内容容器 (mw-content)。
- 将 flex: 0 添加到 l/r 侧边栏容器并将 flex: 1 1 auto 添加到主要内容容器
- 将主内容容器的宽度设置为 100%
- 尝试在主内容容器上使用 translateX 并在单击左侧边栏时设置新宽度
显然 none 这些想法奏效了,我承认我不是最擅长使用 flexbox 的人,所以我确定我只是遗漏了一些基本的东西,但我会很感激你的任何建议好人可能有。 :)
这是一个示例,说明如何使用原版实现此目的 javascript。
两个函数,一个是跟踪部分元素的折叠并调整中间部分的大小。它检查点击并将元素(部分)id 添加到数组,条件检查数组,如果数组 includes
两个外部部分 id,我们使用 style.transform
调整中间部分的大小 => scale()
。第二个函数重置可折叠元素。
在代码片段中找到更多信息。
let clicked = [];
const middle = document.querySelector('#sect2')
let section = document.querySelectorAll('.sect')
let reset = document.querySelector('#reset')
// function
const resizeOnCollapse = (els) => {
// loop over the three sections
els.forEach(sect => {
// do not allow the middle section to be collapsed
if (sect.id !== 'sect2') {
// eventlistener to check a click on the outer sections
sect.addEventListener('click', (e) => {
// push the clicked elements into an array
clicked.push(e.target.id)
// set the event targets width to 0
// essentially collapsing it from view
e.target.style.width = '0px';
// conditional that checks if the array
// includes the two outer sections
if (clicked.includes('sect1') && clicked.includes('sect3')) {
// resize the middle section using
// transform: scale()
middle.style.transform = 'scale(1.2)'
// transition animation on the transform
middle.style.transition = 'transform .5s ease-out'
}
})
}
})
}
// function to reset the elements and reset the array
const resetEls = (el, section) => {
// eventlistener on click
el.addEventListener('click', () => {
// reset the array
clicked = [];
// loop over the sections
section.forEach((sect) => {
// reset the width essentially uncollapsing the sections
sect.style.width = '30vw';
// reset the middle transform rule, scale() to 1
sect.style.transform = 'scale(1)';
})
})
}
// call the functions
resetEls(reset, section)
resizeOnCollapse(section)
#main {
display: flex;
justify-content: space-around;
}
.sect {
width: 30vw;
height: 80vh;
}
#sect1 {
background-color: red;
}
#sect2 {
background-color: blue;
}
#sect3 {
background-color: green;
}
<button id="reset">reset</button>
<div id="main">
<div id="sect1" class="sect">
</div>
<div id="sect2" class="sect">
</div>
<div id="sect3" class="sect">
</div>
</div>
您需要尝试使用“position: absolute”并添加另外两个 classList.toggle 函数
$(document).ready(function () {
var mwContent = document.querySelector('#mw-content'); // !!
var lsToggleBtn = document.querySelector('.ls-toggle');
var lsSidebar = document.querySelector('#left-sidebar');
var rsToggleBtn = document.querySelector('.rs-toggle');
var rsSidebar = document.querySelector('#right-sidebar');
lsToggleBtn.addEventListener('click', function () {
lsToggleBtn.classList.toggle('is-closed');
lsSidebar.classList.toggle('is-closed');
mwContent.classList.toggle('ls-pos'); // here
});
rsToggleBtn.addEventListener('click', function () {
rsToggleBtn.classList.toggle('is-closed');
rsSidebar.classList.toggle('is-closed');
mwContent.classList.toggle('rs-pos'); // here
});
});
body {
background-color: lightslategrey;
margin: 0;
overflow: hidden;
}
.red {
background-color: lightcoral;
}
.green {
background-color: lightgreen;
}
.grey {
background-color: lightslategray;
}
* {
box-sizing: border-box;
}
.d-flex {
display: flex;
position: relative;
}
.ls-toggle,
.rs-toggle {
cursor: pointer;
transition: 0.5s;
}
#left-sidebar {
position: absolute;
left: 0;
width: 250px;
height: 100vh;
transition: 0.5s;
}
#right-sidebar {
position: absolute;
right: 0;
width: 250px;
height: 100vh;
transition: 0.5s;
}
#left-sidebar.is-closed {
transform: translateX(-80%);
}
#right-sidebar.is-closed {
transform: translateX(80%);
}
.ls-top,
.rs-top {
display: flex;
width: 100%;
height: 35px;
align-items: center;
justify-content: flex-end;
background-color: lightslategrey;
}
.rs-top {
justify-content: flex-start;
}
#mw-content {
position: absolute;
right: 250px;
left: 250px;
height: 100vh;
transition: 0.5s;
}
.ls-pos {
left: 50px !important;
transition: 0.5s;
}
.rs-pos {
right: 50px !important;
transition: 0.5s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="d-flex">
<div id="left-sidebar" class="col red">
<div class='ls-top grey'>
<button class="ls-toggle"><i class="fas fa-angle-left fa-2x"></i></button>
</div>
</div>
<div id="mw-content" class="col green">
<h3> Main Window Content.</h3>
</div>
<div id="right-sidebar" class="col red">
<div class='rs-top grey'>
<button class="rs-toggle"><i class="fas fa-angle-right fa-2x"></i></button>
</div>
</div>
</div>