Adding an `animation` declaration messes up the z-indexes, kind of - css

Using Bootstrap's native classes, I have a list of .list-group-item elements, in which there are some clickable options, shown as dropdowns in the .dropdown-menu. By default this works fine, even when the dropdown of one .list-group-item element goes over the one below it.
What I've added then, is an animation declaration that fades in the .list-group-items by using #keyframes animation going from opacity:0 to opacity:1. And as a side-effect of that, every .list-group-item element goes visually over the dropdown menu from the previous one.
(there aren't actually any z-index declarations involved, I've only used that term in the title to illustrate the manifestation of the issue)
I am wondering if there is some kind of workaround for this overflowing issue that would allow me to keep the fade-in animation for the elements?
An example can be seen on the following fiddle (there is no javascript involved or included there as it is not necesarry, so both of the dropdowns are just declared as open in the HTML code to illustrate the situation):
https://jsfiddle.net/o8ysz4qp/2/
HTML:
<div class="list-group-item fade-in">
<div class="pull-right dropdown open">
<button class="btn btn-primary">
↓
</button>
<ul class="dropdown-menu">
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
</div>
<p>Lorem ipsum dolor sit amet</p>
</div>
<div class="list-group-item fade-in">
<div class="pull-right dropdown open">
<button class="btn btn-primary">
↓
</button>
<ul class="dropdown-menu">
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
</div>
<p>Lorem ipsum dolor sit amet</p>
</div>
CSS:
.fade-in {
opacity: 0;
animation:fade-in .5s ease;
animation-fill-mode: forwards;
animation-delay:1s;
}
#keyframes fade-in {
from { opacity:0; }
to { opacity:1; }
}

The problems is that when the opacity is not 1 it creates a new stacking context (See The stacking context - CSS | MDN)
A solution is to add a z-index (since it becomes usable after the opacity change) and reverse their value (the last one has the lowest z-index etc)
Something like (assuming they are siblings)
#import url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css');
.list-group-item:nth-last-child(1){z-index:1}
.list-group-item:nth-last-child(2){z-index:2}
.list-group-item:nth-last-child(3){z-index:3}
.list-group-item:nth-last-child(4){z-index:4}
.list-group-item:nth-last-child(5){z-index:5}
.list-group-item:nth-last-child(6){z-index:6}
.list-group-item:nth-last-child(7){z-index:7}
.fade-in {
opacity: 0;
animation:fade-in .5s ease;
animation-fill-mode: forwards;
animation-delay:1s;
}
#keyframes fade-in {
from { opacity:0; }
to { opacity:1; }
}
<div class="list-group-item fade-in">
<div class="pull-right dropdown open">
<button class="btn btn-primary">
↓
</button>
<ul class="dropdown-menu">
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
</ul>
</div>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
</div>
<div class="list-group-item fade-in">
<div class="pull-right dropdown open">
<button class="btn btn-primary">
↓
</button>
<ul class="dropdown-menu">
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
</ul>
</div>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
</div>

As Gaby explained, animating opacity establishes a stacking context.
So instead of animating the opacity on each .list-group-item, you should place them all in a container and animate opacity there.
#import 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css';
body {
opacity: 0;
animation: fade-in 2s ease;
animation-fill-mode: forwards;
}
#keyframes fade-in {
from { opacity:0; }
to { opacity:1; }
}
<div class="list-group-item fade-in">
<div class="pull-right dropdown open">
<button class="btn btn-primary">
↓
</button>
<ul class="dropdown-menu">
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
</ul>
</div>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
</div>
<div class="list-group-item fade-in">
<div class="pull-right dropdown open">
<button class="btn btn-primary">
↓
</button>
<ul class="dropdown-menu">
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
</ul>
</div>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
<p>Lorem ipsum dolor sit amet</p>
</div>

Related

MaterializeCSS collapsible with IMAGE

I'm using MaterializeCSS and I'm looking to add and image inside of the "collapsible-body" of a Collapsible element... but it doesn't shows up.
It's possible to do what i'm trying some way? Maybe with CSS or JS?
here is my code:
<ul class="collapsible">
<li>
<div class="collapsible-header"><i class="material-icons">filter_drama</i>First</div>
<div class="collapsible-body">
<p>Lorem ipsum dolor sit amet.</p>
<img href="https://materializecss.com/images/yuna.jpg"><!-- Example image -->
</div>
</li>
</ul>
and ofcourse the JS to initialize the collapsible:
$(document).ready(function(){
$('.collapsible').collapsible();
});
Images use a SRC attribute, not HREF:
<ul class="collapsible">
<li>
<div class="collapsible-header"><i class="material-icons">filter_drama</i>First</div>
<div class="collapsible-body">
<p>Lorem ipsum dolor sit amet.</p>
<img src="https://materializecss.com/images/yuna.jpg"><!-- Example image -->
</div>
</li>
</ul>

Indent content based on headings

I'm trying to get a style to indent like the following
H1
Content here
H2
Any content after the H2, paragraphs, images, etc
H3
Any content after the H2, paragraphs, images, etc
H2
content
H1 another top level heading
etc
Sample html:
<h1>heading 1</h1>
<p>content</p>
<h2>heading 2</h2>
<p>content</p>
<p>content</p>
<h3>heading 2</h3>
<p>content</p>
<img src="something.png" />
<p>content</p>
<h1>heading 1</h1>
<p>content</p>
I've tried the following
h2, h2 + * {
margin-left: 30px;
}
h3, h3 + * {
margin-left: 60px;
}
But this only sets a margin on the first element after the heading, I need all subsequent tags, until the next one.
Any questions please ask.
I'd like to point out that I can't rewrite the hml as I'm applying this to a website where many pages have already been created.
Some sample code https://codepen.io/User1972/pen/WZyKNR
I would do this something like this: https://codepen.io/andrasadam93/pen/dVKedR
This way you can easily scale it for further indentations, modify each and every part by adding id's or further classes and get your desired result in later specific cases as well.
.first{
margin-left:0;
}
.second{
margin-left:30px;
}
.third{
margin-left:60px;
}
<div class="first">
<h1>Hello</h1>
<p>Some content here</p>
<div class="second">
<h2>Hello second</h2>
<p>Also some content here</p>
<div class="third">
<h3>Hello third</h3>
<p>Also some content here</p>
</div>
<p>Some further content in the second indentation</p>
</div>
<p>This is also some content in the first indentation</p>
</div>
Why not just use a list <ul><li>...
ul, li { list-style: none; }
<ul>
<li>
<h1>hello h1</h1>
<p>Lorem ipsum dolor sit amet</p>
<ul>
<li>
<h2>hello h2</h2>
<p>Lorem ipsum dolor sit amet</p>
<ul>
<li>
<h3>hello h3</h3>
<p>Lorem ipsum dolor sit amet</p>
</li>
</ul>
</li>
</ul>
</li>
<li>
<h1>hello h1</h1>
<p>Lorem ipsum dolor sit amet</p>
</li>
</ul>
or if you do not want to use a list you can achieve the same with one single CSS rule and class like so:
.cheating-list .cheating-list {
margin-left: 40px;
}
<div class="cheating-list">
<h1>hello h1</h1>
<p>Lorem ipsum dolor sit amet</p>
<div class="cheating-list">
<h2>hello h2</h2>
<p>Lorem ipsum dolor sit amet</p>
<div class="cheating-list">
<h3>hello h3</h3>
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
</div>
<div class="cheating-list">
<h1>hello h1</h1>
<p>Lorem ipsum dolor sit amet</p>
</div>
The trick is do add the wrap <div class="cheating-list"> inside itself.
UPDATED CODE
With your sample HTML (which was added much later) something like this will do the trick (but if possible I would change the markup to one of the above examples)
h1,
h1 ~ *,
h2 ~ h1,
h2 ~ h1 ~ *,
h3 ~ h1,
h3 ~ h1 ~ * {
margin-left: 0px;
}
h2,
h2 ~ *,
h1 ~ h2,
h1 ~ h2 ~ *:not(h1):not(h3) {
margin-left: 40px;
}
h3,
h3 ~ *,
h1 ~ h3,
h1 ~ h3 ~ *:not(h1):not(h2) {
margin-left: 80px;
}
<h1>heading 1</h1>
<p>content</p>
<h2>heading 2</h2>
<p>content</p>
<p>content</p>
<h3>heading 3</h3>
<p>content</p>
<img src="something.png" />
<p>content</p>
<h1>heading 1</h1>
<p>content</p>
<h1 class="entry-title">Inputs</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean porttitor, lacus eget egestas pharetra.</p>
<h2><span id="Columns">Columns</span></h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean porttitor, lacus eget egestas pharetra.</p>
<ul>
<li>fghgfdh</li>
</ul>
<img src="http://via.placeholder.com/350x50" />
<h3><span id="another">another heading</span></h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean porttitor, lacus eget egestas pharetra.</p>
<h1 class="entry-title">2nd Heading One</h1>
<p>This should not have a margin</p>
<h2><span id="Columns">Columns XXXX</span></h2>
<p>This margin is too large. It has the h3 margin applied to it</p>
<h3><span id="another">another h3 heading</span></h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean porttitor, lacus eget egestas pharetra.</p>
Instead of using margin, we can achieve this style easily by using Un-Ordered list.
ul {
list-style-type: none;
}
h1,h2,h3,h4,h5,h4 {
margin: 0px;
}
<ul>
<li>
<h1>H1</h1>
<p>Content here</p>
<ul>
<li>
<h2>H2</h2>
<p>Any content after the H2, paragraphs, images, etc</p>
<ul>
<li>
<h3>H3</h3>
<p>Any content after the H2, paragraphs, images, etcContent here</p>
</li>
</ul>
</li>
<li>
<h2>H2</h2>
<p>Any content after the H2, paragraphs, images, etc</p>
</li>
</ul>
</li>
<li>
<h1>H1</h1>
<p>Content here</p>
<ul>
<li>
<h2>H2</h2>
<p>Any content after the H2, paragraphs, images, etc</p>
<ul>
<li>
<h3>H3</h3>
<p>Any content after the H2, paragraphs, images, etcContent here</p>
</li>
</ul>
</li>
<li>
<h2>H2</h2>
<p>Any content after the H2, paragraphs, images, etc</p>
</li>
</ul>
</li>
</ul>
Here I have attached my codepen link.
No need for extra classes. For any correctly structured HTML document following CSS is enough:
ul, ol {
list-style-position: inside;
} // This is necessary if you use lists. Otherwise just delete this rule.
h1 ~ *:not(h1) {
margin-left: 1.2rem;
}
h2 ~ *:not(h1, h2) {
margin-left: 2.4rem;
}
h3 ~ *:not(h1, h2, h3) {
margin-left: 3.6rem;
}

CSS Flexbox - make elements containing other elements same height

I am trying to create a layout using Flexbox where I have elements which consist of 3 other internal elements. The parent item element contains 3 divs: image, button, text. The issue is that my items will not always contain images or text that is the same height as the others. The button is the one thing that will have a consistent height. I am trying to figure out if it's possible to have each of my image divs be the same height as the tallest one and same for the text divs. I would also like the images to be vertically aligned to the bottom, so if one element has a shorter image, the white space to make the element the same height will go above the image like this:
And here is what I have so far:
.container {
display:flex;
flex-wrap:wrap;
flex-flow:row wrap;
justify-content:center;
}
.item {
max-width:200px;
margin:0 20px;
}
<div class="container">
<div class="item">
<div class="image">
<img src="http://placehold.it/150x300" />
</div>
<div class="button">
<button>Click Me</button>
</div>
<div class="text">
<p>consectetur adipiscing elit.</p>
</div>
</div>
<div class="item">
<div class="image">
<img src="http://placehold.it/150x200" />
</div>
<div class="button">
<button>Click Me</button>
</div>
<div class="text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
<div class="item">
<div class="image">
<img src="http://placehold.it/150x250" />
</div>
<div class="button">
<button>Click Me</button>
</div>
<div class="text">
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<div class="item">
<div class="image">
<img src="http://placehold.it/150x270" />
</div>
<div class="button">
<button>Click Me</button>
</div>
<div class="text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
</div>
I know that I could do this using Javascript to loop through each item to get the tallest and change the CSS of all others, but I'd like to use only CSS if possible. I also know that I could just set the height of the image container to the height of the tallest image, but these images are going to be dynamic and there are going to be a lot of them, so I'd rather have a solution that doesn't require hardcoding values.
Flexing the .item class and adding justify-content: flex-end; would provide the majority of the affect, but as far as I know you'd have to set a specific height on at least one of the items if you want two elements to be aligned the same across flexbox. Happy to be proven wrong though.
You could alternatively use margin-top: auto on the first child to push any unused space to the top and everything else down.
.container {
display:flex;
flex-wrap:wrap;
flex-flow:row wrap;
justify-content:center;
}
.item {
max-width:200px;
margin:0 20px;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.text {
height: 36px; /* magic number */
}
<div class="container">
<div class="item">
<div class="image">
<img src="http://placehold.it/150x300" />
</div>
<div class="button">
<button>Click Me</button>
</div>
<div class="text">
<p>consectetur adipiscing elit.</p>
</div>
</div>
<div class="item">
<div class="image">
<img src="http://placehold.it/150x200" />
</div>
<div class="button">
<button>Click Me</button>
</div>
<div class="text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
<div class="item">
<div class="image">
<img src="http://placehold.it/150x250" />
</div>
<div class="button">
<button>Click Me</button>
</div>
<div class="text">
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<div class="item">
<div class="image">
<img src="http://placehold.it/150x270" />
</div>
<div class="button">
<button>Click Me</button>
</div>
<div class="text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
</div>

Bootstrap carousel items snapping into place and changing height of parent div

I've made a bootstrap carousel with items each containing three columns.
As the slide transition ends, the items snap into place and very briefly change the height of the parent div.
I've spent all day trying to find a solution but can't see anything! I'm assuming it is something to do with padding/margins as the slide happens. I've tried forcing the items to have no padding or margins but no luck.
Does anyone know anything about this issue? Is there something obvious I'm missing?
The link to the page with the issue is here
And the code itself:
.tourenEvents {
background: #2a2a2a;
}
.tourenEvents .tourenEventsInner {
padding-top: 30px;
padding-bottom: 50px;
color: #fff;
}
.tourenEvents .tourenEventsInner .carousel .item .carouselBlock {
margin: 0 !important; /* This was one of the attempts to fix the issue */
}
.tourenEvents .tourenEventsInner .carousel .item .carouselBlock img {
width: 100%;
}
/* == Carousel Control styles - I don't think the issue comes from here but I'm posting it just incase == */
#tourenCarousel .carousel-indicators {
display: none;
}
#tourenCarousel .carousel-control {
background-image: none !important;
color: #fff;
font-size: 50px;
top: 15vh;
opacity: 1;
-webkit-text-stroke: 2px #2a2a2a;
text-shadow: none;
}
#media (max-width: 768px) {
#tourenCarousel .carousel-control {
padding-top: 10vh;
}
}
#tourenCarousel .carousel-control:hover {
color: #fff;
}
#tourenCarousel .carousel-control:focus {
color: #fff;
}
#tourenCarousel .left {
padding-right: 15px;
}
#tourenCarousel .right {
padding-left: 15px;
}
<div class="tourenEvents col-sm-12">
<div class="tourenEventsInner col-lg-12 col-md-offset-1 col-md-10 col-sm-10 col-sm-offset-1 col-xs-10 col-xs-offset-1 text-center">
<h3 class="text-center">Check out our events</h3>
<!-- div:tourenCarousel is the carousel of events -->
<div id="tourenCarousel" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#tourenCarousel" data-slide-to="0" class="active"></li>
<li data-target="#tourenCarousel" data-slide-to="1"></li>
<li data-target="#tourenCarousel" data-slide-to="2"></li>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="item active">
<div class="col-xs-10 col-xs-offset-1">
<div class="carouselBlock col-lg-4 col-xs-10 col-xs-offset-1 text-center">
<p class="lightPara">Lorem ipsum dolor</p>
<h4>Lorem ipsum dolor</h4>
<p class="lightPara">Lorem ipsum dolor</p>
</div>
<div class="carouselBlock col-lg-4 col-xs-10 col-xs-offset-1 text-center">
<p class="lightPara">Lorem ipsum dolor</p>
<h4>Lorem ipsum dolor</h4>
<p class="lightPara">Lorem ipsum dolor</p>
</div>
<div class="carouselBlock col-lg-4 col-xs-10 col-xs-offset-1 text-center">
<p class="lightPara">Lorem ipsum dolor</p>
<h4>Lorem ipsum dolor</h4>
<p class="lightPara">Lorem ipsum dolor</p>
</div>
</div>
</div>
<div class="item">
<div class="col-xs-10 col-xs-offset-1">
<div class="carouselBlock col-lg-4col-xs-10 col-xs-offset-1 text-center">
<p class="lightPara">Lorem ipsum dolor</p>
<h4>Lorem ipsum dolor</h4>
<p class="lightPara">Lorem ipsum dolor</p>
</div>
<div class="carouselBlock col-lg-4 col-xs-10 col-xs-offset-1 text-center">
<p class="lightPara">Lorem ipsum dolor</p>
<h4>Lorem ipsum dolor</h4>
<p class="lightPara">Lorem ipsum dolor</p>
</div>
<div class="carouselBlock col-lg-4 col-xs-10 col-xs-offset-1 text-center">
<p class="lightPara">Lorem ipsum dolor</p>
<h4>Lorem ipsum dolor</h4>
<p class="lightPara">Lorem ipsum dolor</p>
</div>
</div>
</div>
<div class="item">
<div class="col-xs-10 col-xs-offset-1">
<div class="carouselBlock col-lg-4 col-xs-10 col-xs-offset-1 text-center">
<p class="lightPara">Lorem ipsum dolor</p>
<h4>Lorem ipsum dolor</h4>
<p class="lightPara">Lorem ipsum dolor</p>
</div>
<div class="carouselBlock col-lg-4 col-xs-10 col-xs-offset-1 text-center">
<p class="lightPara">Lorem ipsum dolor</p>
<h4>Lorem ipsum dolor</h4>
<p class="lightPara">Lorem ipsum dolor</p>
</div>
<div class="carouselBlock col-lg-4 col-xs-10 col-xs-offset-1 text-center">
<p class="lightPara">Lorem ipsum dolor</p>
<h4>Lorem ipsum dolor</h4>
<p class="lightPara">Lorem ipsum dolor</p>
</div>
</div>
</div>
</div>
<!-- Left and right controls -->
<a class="left carousel-control" href="#tourenCarousel" role="button" data-slide="prev">
<i class="fa fa-angle-left" aria-hidden="true"></i>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#tourenCarousel" role="button" data-slide="next">
<i class="fa fa-angle-right" aria-hidden="true"></i>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
Remove width:100% on .tourenEvents .tourenEventsInner .carousel .item .carouselBlock img
you are resizing width on active class.

Bootstrap 3, Adding button to list-group misaligns everything else vertically

I'm trying to achieve a simple thing:
I'm taking the basic example of a list-group with badges from de Bootstrap 3 Components documentation here.
The problem is that I need a button in the beginning of the line, but that is making the main text vertically misaligned and the pull-right text aligned at the top.
Please check this bootply.
Thanks.
I modified your code like this:
See updated bootply: http://www.bootply.com/129053
HTML
<ul class="list-group">
<li class="list-group-item">
<span class="badge">67512</span>
<button>w</button>
<a href="#" class="margin-sm">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit
</a>
</li>
<li class="list-group-item">
<span class="badge">67512</span>
<button>w</button>
<a href="#" class="margin-sm">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit
</a>
</li>
</ul>
CSS
.margin-sm,.list-group-item .badge {
margin: 4px;
}
I don't know if that's your desired effect....

Resources