#css
#css
Вопрос:
У меня есть большой компонент «намереваюсь занять большую часть экрана». Если содержимое внутри этого компонента слишком велико для компонента, я хочу, чтобы у компонента были свои собственные полосы прокрутки, я не хочу, чтобы страница или родительский элемент создавали свои собственные полосы прокрутки.
Лучшее, что у меня есть для этого, — использовать flexbox для родительского элемента для достижения этой цели:
(Открыть всю страницу)
document.getElementById("button").addEventListener("click", (e) => {
document.getElementById("something").classList.toggle("something-big");
});
.parent {
height: 300px;
display: flex;
flex-flow: column nowrap;
justify-content: stretch;
border: dashed 1px black;
}
.body {
background-color: #ddf;
flex: 1 0 200px;
overflow-y: scroll;
}
.something-big {
height: 800px;
}
.something {
background-color: #bbf;
border: solid 1px blue;
}
.footer,
.header {
background-color: pink;
}
<div class="parent">
<div class="header"> header </div>
<div class="body">
body
<div class="something" id="something"> something
<button id="button"> click me</button>
</div>
</div>
<div class="footer"> footer </div>
</div>
Однако мне не очень нравится это решение.
Если я разрабатываю это как библиотеку для использования в другом месте (т.Е.. У меня есть контроль над .body
компонентом, но не над компонентами .header
.footer
. или .parent
), тогда мне нужно указать им «Чтобы это работало, вам нужно сделать родительский гибкий контейнер».
Есть ли свойство, которое я могу применить к .body
only, чтобы достичь той же функциональности?
Ответ №1:
В принципе, вы можете поиграть с:
max-height
: процент (80vh = 80% of viewport height
пример 🙂height: auto
,height: inherit;
overflow-y: scroll;
,overflow: hidden;
Для оформления height
каждого компонента и какого из scrolls
них.
Проверьте элементы под комментариями в CSS
:
/* CHECK THIS */
Scrollig HTML-страница:
.parent,
.parent > .body {
height: auto;
}
// Get the button
let myBtn = document.querySelector('#myBtn');
// A function to draw boxes (more content in .body > .something > HERE)
function drawBoxes(){
// Array to hold HTMl output
let output = [];
// Get boxes container
let boxesContainer = document.querySelector('.boxes');
// Adding boxes for testing (You can play with that to check for smaller space (try 3 or 4 ))
let boxesInTotal = 40;
// Loop to draw the boxes
for(let i = 0; i < boxesInTotal; i ){
let box =
`<div class="box"></div>`;
output.push(box);
}
// Print the boxes
boxesContainer.innerHTML = output.join('');
}
// Click on the button to see the changes
myBtn.addEventListener('click', () => {
drawBoxes();
});
*, *::after, *::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* CHECK THIS */
.parent,
.parent > .body {
height: auto;
}
.parent {
background-color: rgb(24, 146, 173);
width: 100%;
padding: 20px;
color: #FFFFFF;
text-align: center;
}
.parent > body > h1,
.parent > h1 {
margin-bottom: 20px;
}
.parent > .header {
height: 100px;
border: 1px solid #FFFFFF;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
}
.parent > .body {
color: #FFFFFF;
border: 1px solid #FFFFFF;
}
.parent > .body > #something > #myBtn {
padding: 15px 20px;
border-radius: 4px;
background: #121212;
color: #fafafa;
}
#something > .boxes {
display: flex;
flex-wrap: wrap;
height: auto;
}
#something > .boxes > .box {
border: 1px solid #FFFFFF;
height: 300px;
width: 300px;
margin: 10px auto;
display: block;
background: red;
}
<div class="parent">
<h1>Parent</h1>
<div class="header">
<h2>Header</h2>
</div>
<div class="body">
<h1>Body</h1>
<div id="something">
<button id="myBtn">Click</button>
<div class="boxes"></div>
</div>
</div>
</div>
Scrolling .body:
// Get the button
let myBtn = document.querySelector('#myBtn');
// A function to draw boxes (more content in .body > .something > HERE)
function drawBoxes(){
// Array to hold HTMl output
let output = [];
// Get boxes container
let boxesContainer = document.querySelector('.boxes');
// Adding boxes for testing
let boxesInTotal = 40;
// Loop to draw the boxes
for(let i = 0; i < boxesInTotal; i ){
let box =
`<div class="box"></div>`;
output.push(box);
}
// Print the boxes
boxesContainer.innerHTML = output.join('');
}
// Click on the button to see the changes
myBtn.addEventListener('click', () => {
drawBoxes();
});
*, *::after, *::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* CHECK THIS */
body {
height: 2000px;
}
.parent {
background-color: rgb(24, 146, 173);
width: 100%;
padding: 20px;
color: #FFFFFF;
text-align: center;
height: auto;
}
.parent > body > h1,
.parent > h1 {
margin-bottom: 20px;
}
.parent > .header {
height: 100px;
border: 1px solid #FFFFFF;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
}
/* CHECK THIS */
.parent > .body {
color: #FFFFFF;
border: 1px solid #FFFFFF;
max-height: 70vh;
overflow-y: scroll;
}
/* CHECK THIS */
.parent > .body > #something {
height: inherit;
}
.parent > .body > #something > #myBtn {
padding: 15px 20px;
border-radius: 4px;
background: #121212;
color: #fafafa;
}
#something > .boxes {
display: flex;
flex-wrap: wrap;
}
#something > .boxes > .box {
border: 1px solid #FFFFFF;
height: 300px;
width: 300px;
margin: 10px auto;
display: block;
background: red;
}
<div class="parent">
<h1>Parent</h1>
<div class="header">
<h2>Header</h2>
</div>
<div class="body">
<h1>Body</h1>
<div id="something">
<button id="myBtn">Click</button>
<div class="boxes"></div>
</div>
</div>
</div>
Прокрутка .parent:
// Get the button
let myBtn = document.querySelector('#myBtn');
// A function to draw boxes (more content in .body > .something > HERE)
function drawBoxes(){
// Array to hold HTMl output
let output = [];
// Get boxes container
let boxesContainer = document.querySelector('.boxes');
// Adding boxes for testing
let boxesInTotal = 40;
// Loop to draw the boxes
for(let i = 0; i < boxesInTotal; i ){
let box =
`<div class="box"></div>`;
output.push(box);
}
// Print the boxes
boxesContainer.innerHTML = output.join('');
}
// Click on the button to see the changes
myBtn.addEventListener('click', () => {
drawBoxes();
});
*, *::after, *::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* CHECK THIS */
.parent {
background-color: rgb(24, 146, 173);
width: 100%;
padding: 20px;
color: #FFFFFF;
text-align: center;
max-height: 90vh;
overflow-y: scroll;
}
.parent > body > h1,
.parent > h1 {
margin-bottom: 20px;
}
.parent > .header {
height: 100px;
border: 1px solid #FFFFFF;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
}
.parent > .body {
color: #FFFFFF;
border: 1px solid #FFFFFF;
}
.parent > .body > #something > #myBtn {
padding: 15px 20px;
border-radius: 4px;
background: #121212;
color: #fafafa;
}
#something > .boxes {
display: flex;
flex-wrap: wrap;
}
#something > .boxes > .box {
border: 1px solid #FFFFFF;
height: 300px;
width: 300px;
margin: 10px auto;
display: block;
background: red;
}
<div class="parent">
<h1>Parent</h1>
<div class="header">
<h2>Header</h2>
</div>
<div class="body">
<h1>Body</h1>
<div id="something">
<button id="myBtn">Click</button>
<div class="boxes"></div>
</div>
</div>
</div>
Scrolling #something:
// Get the button
let myBtn = document.querySelector('#myBtn');
// A function to draw boxes (more content in .body > .something > HERE)
function drawBoxes(){
// Array to hold HTMl output
let output = [];
// Get boxes container
let boxesContainer = document.querySelector('.boxes');
// Adding boxes for testing
let boxesInTotal = 40;
// Loop to draw the boxes
for(let i = 0; i < boxesInTotal; i ){
let box =
`<div class="box"></div>`;
output.push(box);
}
// Print the boxes
boxesContainer.innerHTML = output.join('');
}
// Click on the button to see the changes
myBtn.addEventListener('click', () => {
drawBoxes();
});
*, *::after, *::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* CHECK THIS */
.parent {
background-color: rgb(24, 146, 173);
width: 100%;
padding: 20px;
color: #FFFFFF;
text-align: center;
height: auto;
}
.parent > body > h1,
.parent > h1 {
margin-bottom: 20px;
}
.parent > .header {
height: 100px;
border: 1px solid #FFFFFF;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
}
/* CHECK THIS */
.parent > .body {
color: #FFFFFF;
border: 1px solid #FFFFFF;
max-height: 70vh;
overflow: hidden;
}
/* CHECK THIS */
.parent > .body > #something {
max-height: inherit;
overflow-y: scroll;
}
.parent > .body > #something > #myBtn {
padding: 15px 20px;
border-radius: 4px;
background: #121212;
color: #fafafa;
}
#something > .boxes {
display: flex;
flex-wrap: wrap;
}
#something > .boxes > .box {
border: 1px solid #FFFFFF;
height: 300px;
width: 300px;
margin: 10px auto;
display: block;
background: red;
}
<div class="parent">
<h1>Parent</h1>
<div class="header">
<h2>Header</h2>
</div>
<div class="body">
<h1>Body</h1>
<div id="something">
<button id="myBtn">Click</button>
<div class="boxes"></div>
</div>
</div>
</div>
Комментарии:
1. Конечно, поэтому я думаю, что использование vh здесь довольно разумно, где в основном это своего рода оценка, где вы бы сказали: «Мы считаем, что этот компонент должен занимать около 70% вертикальной высоты страницы» — если после этого компонента есть дополнительный контент, то, конечно, он начнетпрокрутка. Предположительно, тогда пользователь компонента должен переопределить это значение vh в соответствии с требованиями.