#html #css
#HTML #css
Вопрос:
У меня есть этот аккуратный CSS-аккордеон, который работает все хорошо и хорошо, пока я не попытаюсь добавить отступы или поля к .accordBody
.
Вся «магия» аккордеона состоит из простого трюка, увеличения высоты .accordBody
от 0
до 125px
в :focus
соответствии .accordHeader
.
.accordion {
border: solid 1px #cccccc;
border-radius: 0.25rem;
box-shadow: 0 2px 4px -1px #b3b3b3;
}
.accordion .accord .accordHeader,
.accordion .accord .accordBody {
background-color: #fff;
padding: 1rem;
}
.accordion .accord .accordHeader {
border-bottom: solid 1px #cccccc;
color: #000;
cursor: pointer;
}
.accordion .accord .accordBody {
padding: 0;
box-shadow: inset 0px 2px 4px -1px #e6e6e6;
height: 0;
transition: height 250ms ease;
overflow: hidden;
}
.accordion .accord:focus>*~.accordBody {
height: 125px;
overflow: auto;
}
.accordion .accord:focus .accord .accordHeader {
border-top: solid 1px #cccccc;
}
<div class="accordion">
<div class="accord" tabindex="0">
<div class="accordHeader">
Header
</div>
<div class="accordBody">
Body
</div>
</div>
<div class="accord" tabindex="0">
<div class="accordHeader">
Header
</div>
<div class="accordBody">
Body
</div>
</div>
<div class="accord" tabindex="0">
<div class="accordHeader">
Header
</div>
<div class="accordBody">
Body
</div>
</div>
Теперь визуально это выглядит не очень эстетично, поскольку отсутствует заполнение .accordBody
. Однако, если я сейчас попытаюсь добавить указанное заполнение, дизайн нарушится, поскольку заполнение приведет .accordBody
к тому, что, хотя для него height
установлено значение 0
, он останется открытым.
.accordion {
border: solid 1px #cccccc;
border-radius: 0.25rem;
box-shadow: 0 2px 4px -1px #b3b3b3;
}
.accordion .accord .accordHeader,
.accordion .accord .accordBody {
background-color: #fff;
padding: 1rem;
}
.accordion .accord .accordHeader {
border-bottom: solid 1px #cccccc;
color: #000;
cursor: pointer;
}
.accordion .accord .accordBody {
box-shadow: inset 0px 2px 4px -1px #e6e6e6;
height: 0;
transition: height 250ms ease;
overflow: hidden;
}
.accordion .accord:focus > * ~ .accordBody {
height: 125px;
overflow: auto;
}
.accordion .accord:focus .accord .accordHeader {
border-top: solid 1px #cccccc;
}
<div class="accordion">
<div class="accord" tabindex="0">
<div class="accordHeader">
Header
</div>
<div class="accordBody">
Body
</div>
</div>
<div class="accord" tabindex="0">
<div class="accordHeader">
Header
</div>
<div class="accordBody">
Body
</div>
</div>
<div class="accord" tabindex="0">
<div class="accordHeader">
Header
</div>
<div class="accordBody">
Body
</div>
</div>
</div>
Как мне убедиться, что height: 0;
это также включает отступы?
Ответ №1:
Добавьте дополнительный контейнер и учитывайте поля вместо отступов
.accordion {
border: solid 1px #cccccc;
border-radius: 0.25rem;
box-shadow: 0 2px 4px -1px #b3b3b3;
}
.accordion .accord .accordHeader {
background-color: #fff;
padding: 1rem;
}
.accordion .accord .accordBody {
background-color: #fff;
}
.accordion .accord .accordBody > div {
margin:1rem;
}
.accordion .accord .accordHeader {
border-bottom: solid 1px #cccccc;
color: #000;
cursor: pointer;
}
.accordion .accord .accordBody {
box-shadow: inset 0px 2px 4px -1px #e6e6e6;
height: 0;
transition: height 250ms ease;
overflow: hidden;
}
.accordion .accord:focus > * ~ .accordBody {
height: 125px;
overflow: auto;
}
.accordion .accord:focus .accord .accordHeader {
border-top: solid 1px #cccccc;
}
<div class="accordion">
<div class="accord" tabindex="0">
<div class="accordHeader">
Header
</div>
<div class="accordBody">
<div>Body</div>
</div>
</div>
<div class="accord" tabindex="0">
<div class="accordHeader">
Header
</div>
<div class="accordBody">
<div>Body</div>
</div>
</div>
<div class="accord" tabindex="0">
<div class="accordHeader">
Header
</div>
<div class="accordBody">
<div>Body</div>
</div>
</div>
</div>
Без дополнительной оболочки вы можете рассмотреть некоторые хитрости с псевдо-элементом:
.accordion {
border: solid 1px #cccccc;
border-radius: 0.25rem;
box-shadow: 0 2px 4px -1px #b3b3b3;
}
.accordion .accord .accordHeader {
background-color: #fff;
padding: 1rem;
}
.accordion .accord .accordBody {
background-color: #fff;
padding:0 1rem;
}
.accordion .accord .accordBody:before,
.accordion .accord .accordBody:after{
content:"";
display:block;
height:min(100%,1rem); /* don't make it more than 1rem and it will be 0 on collapse due to 100%x0 */
}
.accordion .accord .accordHeader {
border-bottom: solid 1px #cccccc;
color: #000;
cursor: pointer;
}
.accordion .accord .accordBody {
box-shadow: inset 0px 2px 4px -1px #e6e6e6;
height: 0;
transition: height 250ms ease;
overflow: hidden;
}
.accordion .accord:focus > * ~ .accordBody {
height: 125px;
overflow: auto;
}
.accordion .accord:focus .accord .accordHeader {
border-top: solid 1px #cccccc;
}
<div class="accordion">
<div class="accord" tabindex="0">
<div class="accordHeader">
Header
</div>
<div class="accordBody">
Body
</div>
</div>
<div class="accord" tabindex="0">
<div class="accordHeader">
Header
</div>
<div class="accordBody">
Body
</div>
</div>
<div class="accord" tabindex="0">
<div class="accordHeader">
Header
</div>
<div class="accordBody">
Body
</div>
</div>
</div>
Комментарии:
1. Спасибо, это решает проблему, однако я хотел бы, чтобы пробелы применялись к исходному
.accordBody
div, я приму ваш ответ, хотя, если это действительно невозможно.2. другого пути, кроме этого решения без JS, нет. Даже
box-sizing: border-box;
не поможет, поскольку он не изменяет высоту отступа или границы. Everythign else будет применять отрицательную высоту, что будет означать, что она становится недействительной.3. @Simplicius добавил еще одну идею
4. Вы потратили много времени и думали найти такой хакерский подход к моему вопросу, спасибо! Это определенно стоит моего согласия!
Ответ №2:
Для того, чтобы переход заработал, я ввел дополнительный "paddingDiv"
и придал ему стиль заполнения
.accordion {
border: solid 1px #cccccc;
border-radius: 0.25rem;
box-shadow: 0 2px 4px -1px #b3b3b3;
}
.accordHeader {
background-color: #fff;
padding: 1rem;
}
.accordHeader {
border-bottom: solid 1px #cccccc;
color: #000;
cursor: pointer;
}
.accordBody {
padding: 0;
box-shadow: inset 0px 2px 4px -1px #e6e6e6;
height: 0;
transition: height 250ms ease;
overflow: hidden;
}
.accordion .accord:focus>*~.accordBody {
height: 125px;
overflow: auto;
}
.accord:focus .accord .accordHeader {
border-top: solid 1px #cccccc;
}
.paddingDiv {
overflow: hidden;
padding: 1rem;
}
<!DOCTYPE html>
<html>
<head>
<title>Another simple example</title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<div class="accordion">
<div class="accord" tabindex="0">
<div class="accordHeader">
Header
</div>
<div class="accordBody" visibility="hidden" height="2px">
<div class="paddingDiv">Body</div>
</div>
</div>
<div class="accord" tabindex="0">
<div class="accordHeader">
Header
</div>
<div class="accordBody">
<div class="paddingDiv">Body</div>
</div>
</div>
<div class="accord" tabindex="0">
<div class="accordHeader">
Header
</div>
<div class="accordBody">
<div class="paddingDiv">Body</div>
</div>
</div>
</div>
</body>
</html>
Комментарии:
1. Это сработало бы, однако мне потребовалась бы возможность добавить переход к
.accordBody
, посколькуdisplay
он двоичный и не может быть масштабирован.