Reputation: 2095
I have got this neat CSS accordion, which works all nice and fine, until I try to add either padding or margin to the .accordBody
.
The entire "magic" of the accordion consists out of the simple trick of, increasing the height of .accordBody
from 0
to 125px
on the :focus
of the according .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>
Now visually this does not look really aesthetically pleasing, since the missing padding of the .accordBody
. However if I now try to add said padding, the design breaks, since the padding will cause the .accordBody
, though its height
is set to 0
, to stay open.
.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>
How do I ensure that height: 0;
includes padding as well?
Upvotes: 2
Views: 571
Reputation: 11
In order for the transition to work I introduced a additional "paddingDiv"
and gave it the padding style
.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>
Upvotes: 0
Reputation: 273448
Add an extra container and consider margin instead of padding
.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>
Without extra wrapper you can consider some trick with pseudo element:
.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>
Upvotes: 3