I am trying to build a kind of accordion effect on hover of column field which is built using css flex-box. When i apply few styles the columns are also moving position instead of the bottom row alone. Can someone please help here. Here is the fiddle to check the issue. On hover of category the description content opens up and pushing the columns below.
https://jsfiddle.net/rc402/rx7gmbca/1/
.product-container {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: flex-start;
list-style: none;
width: 100vw;
overflow: hidden;
padding: 0;
font-family: "Open Sans', sans-serif";
letter-spacing: -0.005em;
color: black;
margin: 0 8rem;
column-gap: 3.2rem;
.l-product {
flex: 0 0 auto;
margin-top: 4rem;
margin-top: 6rem;
img {
height: 29.6rem;
width: 29.6rem;
border: 1px solid gray;
border-radius: 2px;
}
.name {
margin: 2.4rem 0 0 0;
width: 10.8rem;
height: 1.8rem;
font-style: normal;
font-weight: 700;
font-size: 16px;
line-height: 18px;
text-align: left;
}
.role {
margin: 1.6rem 0 0 0;
width: 20.9rem;
height: 1.6rem;
font-style: italic;
font-weight: normal;
font-size: 14px;
line-height: 16px;
text-decoration-line: underline;
text-align: left;
}
}
.hide {
display: none;
}
.product-description:hover .hide {
margin-top: 162px;
display: block;
width: 1280px;
height: 526px;
background: #ffffff;
border: 1px solid #d9d9d9;
box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.1);
border-radius: 2px;
}
}
Also if i need to achieve same thing on click any pointers on how to do it?
CodePudding user response:
@Kumar it's not completely finished, but I think I created the effect you wanted: Codepen: CSS Flexbox need accordion effect on hover (SO)
The main part of the magic is now happening in javascript, mainly in initProductDesc
. I used jQuery but you could change it to vanilla of course.
You still need to adapt the initial height of the container by adding the margin.
$('.hide').each(function() {
$hide = $(this);
$hide.attr('data-initial-height', $hide.height()); // change height to include margin-top too -> outerHeigth() or something for example.
$hide.addClass('initialized');
});
Does this help?
This should also work if you have to change the container width and height in responsive and it would also work with a dynamic height of the .hide-container (at least I think, not tested though).
Full code:
html (had to remove the base64 image codes -> char limit):
<ul id="">
<li >
<img src="image.png" />
<p >Product 2</p>
<p >category</p>
<div >product description.</div>
</li>
<li >
<img src="image.png" />
<p >Product 5</p>
<p >category</p>
<div >product description.</div>
</li>
<li >
<img src="image.png" />
<p >Product 6</p>
<p >category</p>
<div >product description.</div>
</li>
<li >
<img src="image.png" />
<p >Product 7</p>
<p >category</p>
<div >product description.</div>
</li>
<li >
<img src="image.png" />
<p >Product</p>
<p >category</p>
<div >product description.</div>
</li>
<li >
<img src="image.png" />
<p >Product 8</p>
<p >category</p>
<div >product description.</div>
</li>
<li >
<img src="image.png" />
<p >Product 9</p>
<p >category</p>
<div >product description.</div>
</li>
<li >
<img src="image.png" />
<p >Product 10</p>
<p >category</p>
<div >product description.</div>
</li>
<li >
<img src="image.png" />
<p >Product 11</p>
<p >category</p>
<div >product description.</div>
</li>
<li >
<img src="image.png" />
<p >Product 12</p>
<p >category</p>
<div >product description.</div>
</li>
</ul>
scss:
.product-container {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: flex-start;
list-style: none;
width: 100vw;
overflow: hidden;
padding: 0;
font-family: "Open Sans', sans-serif";
letter-spacing: -0.005em;
color: black;
margin: 0 8rem;
column-gap: 3.2rem;
overflow: hidden;
&, & * {
box-sizing: border-box;
}
.l-product {
flex: 0 0 auto;
margin-top: 4rem;
margin-top: 6rem;
position: relative;
overflow: hidden;
padding-bottom: 0;
transition: all 0.5s ease-in;
&.open {
overflow: visible;
}
img {
height: 29.6rem;
width: 29.6rem;
border: 1px solid gray;
border-radius: 2px;
}
.name {
margin: 2.4rem 0 0 0;
width: 10.8rem;
height: 1.8rem;
font-style: normal;
font-weight: 700;
font-size: 16px;
line-height: 18px;
text-align: left;
}
.role {
margin: 1.6rem 0 0 0;
width: 20.9rem;
height: 1.6rem;
font-style: italic;
font-weight: normal;
font-size: 14px;
line-height: 16px;
text-decoration-line: underline;
text-align: left;
}
.hide {
display: block;
width: 1280px;
height: 526px;
position: absolute;
margin-top: 162px;
background: #ffffff;
border: 1px solid #d9d9d9;
box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.1);
border-radius: 2px;
transition: all 0.5s ease-in;
}
&:not(.open) {
.hide {
&.initialized {
height: 0;
}
}
}
}
}
javascript/jQuery:
var initProductDesc = function() {
$('.hide').each(function() {
$hide = $(this);
$hide.attr('data-initial-height', $hide.height());
$hide.addClass('initialized');
});
$('.product-description').on('click', function() {
$thisDescription = $(this);
$thisLi = $thisDescription.closest('.l-product');
$thisHide = $thisDescription.siblings('.hide');
toggledOpen = toggleClass($thisLi, 'open');
if (toggledOpen) {
$thisLi.css('padding-bottom', $thisDescription.siblings('.hide').attr('data-initial-height') 'px');
}
else {
$thisLi.css('padding-bottom', '');
}
});
}
var toggleClass = function($element, classname) {
if ($element.hasClass(classname)) {
$element.removeClass(classname);
return false;
}
else {
$element.addClass(classname);
return true;
}
}
$(function() {
initProductDesc();
});