Bootstrap carousel refuses to transition smoothly after css adjustments - javascript

For the last 3 hours I've been trying to make a simple adjustment to Bootstrap 3's carousel transitions.
I've tried changing the slide speed where this is the only thing that seems to have any effect:
.carousel-inner .item {
-webkit-transition-duration: 2s;
-moz-transition-duration: 2s;
-o-transition-duration: 2s;
transition-duration: 2s;
}
but it hides the 'leaving' content too soon, and I have no clue what property to modify to fix that.
I've also tried changing it to a fade transition with
.carousel-fade .item {
opacity: 0;
-webkit-transition: opacity 2s ease-in-out;
-moz-transition: opacity 2s ease-in-out;
-ms-transition: opacity 2s ease-in-out;
-o-transition: opacity 2s ease-in-out;
transition: opacity 2s ease-in-out;
left: 0 !important;
}
.carousel-fade .active {
opacity: 1 !important;
}
.carousel-fade .left {
opacity: 0 !important;
-webkit-transition: opacity 0.5s ease-in-out !important;
-moz-transition: opacity 0.5s ease-in-out !important;
-ms-transition: opacity 0.5s ease-in-out !important;
-o-transition: opacity 0.5s ease-in-out !important;
transition: opacity 0.5s ease-in-out !important;
}
.carousel-fade .carousel-control {
opacity: 1 !important;
}
And just about every other snippet to do so that I've come across, but every single one always first removed the leaving content, showing a featureless background, before fading in the next. What am I missing? All I need is some plain CSS to override the existing transition details, but I don't know where to look any more.

I think different aspects of bootstrap's carousel plugin give the effects you mention.
Active items have display: block while not active items have display: none
This can be solved by giving all items display: block and then setting the position to absolute with top: 0 and left: 0, resulting in the items overlapping. Setting opacity: 0; makes them invisible by default.
Less:
.carousel-inner > .item {
opacity: 0;
top: 0;
left: 0;
width: 100%;
display: block;
position: absolute;
}
One problem of the position: absolute is that the container does not get a height. The preceding can be solved by setting the position of the first item to relative (it is add the right position already). In Less code, it is as follows:
.carousel-inner > .item {
:first-of-type {
position:relative;
}
}
Bootstrap uses translate3ds to change the position of the item in the space. You won't need these transformations, so reset them. Leveraging Less, code shown below:
.carousel-inner > .item {
transform: translate3d(0,0,0) !important;
}
The CSS transitions are triggered by adding and removing CSS classes with jQuery. The time between these class changes has been hardcoded in the carousel plugin code (Carousel.TRANSITION_DURATION = 600). So, after 600 ms, one item becomes active (having the .active class). That is the reason for the unexpected behavior if your css transition-duration is greater than 0.6 seconds.
The CSS class changes are as follows:
The active item has class .active -> .active.left -> none
The next item has no class -> .next.left -> .active
So the .active.left and .next.left are important (or .prev.right and .active.right when you slide backwards).
Because all images are already stacked, you can use the z-index property to make an image in the stack visible, because we can change the opacity at the same time. You can use the following Less code to fade in the next slide:
.carousel-inner {
> .next.left {
transition: opacity 0.6s ease-in-out;
opacity: 1;
z-index:2;
}
> .active.left {
z-index:1;
}
}
To make sure that the controls are visible as well, use:
.carousel-control {
z-index:4;
}
Putting all together, see the results in this demo, which uses the following Less code:
.carousel-inner {
> .item {
opacity: 0;
top: 0;
left: 0;
width: 100%;
display: block;
position: absolute;
z-index:0;
transition: none;
transform: translate3d(0,0,0) !important;
&:first-of-type {
position:relative;
}
}
> .active {
opacity: 1;
z-index:3;
}
> .next.left,
> .prev.right {
transition: opacity 0.6s ease-in-out;
opacity: 1;
left: 0;
z-index:2;
}
> .active.left,
> .active.right {
z-index:1;
}
}
.carousel-control {
z-index:4;
}
The above code can be compiled with the Less autoprefixer plugin plugin into CSS with the following command:
lessc --autoprefix="Android 2.3,Android >= 4,Chrome >= 20,Firefox >= 24,Explorer >= 8,iOS >= 6,Opera >= 12,Safari >= 6' code.less
which outputs:
.carousel-inner > .item {
opacity: 0;
top: 0;
left: 0;
width: 100%;
display: block;
position: absolute;
z-index: 0;
-webkit-transition: none;
-o-transition: none;
transition: none;
-webkit-transform: translate3d(0, 0, 0) !important;
transform: translate3d(0, 0, 0) !important;
}
.carousel-inner > .item:first-of-type {
position: relative;
}
.carousel-inner > .active {
opacity: 1;
z-index: 3;
}
.carousel-inner > .next.left,
.carousel-inner > .prev.right {
-webkit-transition: opacity 0.6s ease-in-out;
-o-transition: opacity 0.6s ease-in-out;
transition: opacity 0.6s ease-in-out;
opacity: 1;
left: 0;
z-index: 2;
}
.carousel-inner > .active.left,
.carousel-inner > .active.right {
z-index: 1;
}
.carousel-control {
z-index: 4;
}

I was struggling with this and it was driving me insane - on Bootstrap's Introduction page, if you look under Components, it lists Carousel as one of the components requiring JS. I had to add their CSS stylesheet before all other stylesheets, then their Bootstrap / JS plugin bundle right before the closing body tag. Finally fixed the issue. I've linked them below in order, starting with the Introduction page.
https://getbootstrap.com/docs/5.1/getting-started/introduction/

Related

Hovering Issue With Nav Menu

My mega menu nav has a hovering issue. It activates when hovering over invisible child list items (mousing over from bottom to top, you'll notice the issue on this codepen).
This is the block of CSS that's triggering the hover:
.nav:hover > li > .subnav-block {
opacity: 1;
visibility: visible;
overflow: visible;
}
I'm thinking a JavaScript solution would help out but trying to find CSS fix for this first.
Your sub-navigation menu is taking up space, even though it is not visible. That is why you can see it whenever you are hovering above it. Adding height:0 to your .subnav-block and then setting it back to auto when hovering, should do the trick. Your css should look something like the one below.
.subnav-block {
position: static;
display: block;
width: 100% !important;
top: 54px;
left: 0;
height: 0;
overflow: hidden;
background: gray;
-webkit-transition: all 0.3s ease 0.15s;
-moz-transition: all 0.3s ease 0.15s;
-o-transition: all 0.3s ease 0.15s;
-ms-transition: all 0.3s ease 0.15s;
transition: all 0.3s ease 0.15s;
}
.nav:hover > li > .subnav-block {
height: auto;
visibility: visible;
overflow: visible;
}
UPDATE
If you want to add paddings to your sub-navigation menu, setting the height to 0 won't suffice, and you would need to change both the height and the padding when hovering. There is another way, which Hadi77 mentioned, which is setting the default display to none and then change it to block. Just like the example below.
.subnav-block {
position: static;
width: 100% !important;
top: 54px;
left: 0;
display: none;
background: gray;
-webkit-transition: all 0.3s ease 0.15s;
-moz-transition: all 0.3s ease 0.15s;
-o-transition: all 0.3s ease 0.15s;
-ms-transition: all 0.3s ease 0.15s;
transition: all 0.3s ease 0.15s;
}
.nav:hover > li > .subnav-block {
display: block;
}
UPDATE 2
Since display won't let us use transitions, the other workaround would be using a bit of JS. Since it is not much code, it is solid way to achieve this. We would need to remove the CSS hover in this.
JS
const nav = document.querySelectorAll('.nav > li');
nav.forEach(elem => {
elem.addEventListener('mouseenter', () => {
const subnav = document.querySelectorAll('.subnav-block');
subnav.forEach(sub => {
sub.classList.add('display-block');
setTimeout( () => {
sub.style.opacity = 1;
sub.style.height = 'auto';
}, 100);
});
});
elem.addEventListener('mouseleave', () => {
const subnav = document.querySelectorAll('.subnav-block');
subnav.forEach(sub => {
sub.classList.remove('display-block');
sub.style.opacity = 0;
});
});
});
CSS
.subnav-block {
position: static;
width: 100% !important;
top: 54px;
left: 0;
display: none;
opacity: 0;
height: 0;
background: gray;
-webkit-transition: all 0.3s ease 0.15s;
-moz-transition: all 0.3s ease 0.15s;
-o-transition: all 0.3s ease 0.15s;
-ms-transition: all 0.3s ease 0.15s;
transition: all 0.3s ease 0.15s;
}
.display-block {
display: block;
}
Setting visibility to hidden, is somewhat like making it transparent: The element takes space as it should (display is set to block).
Using display property is what you want. Set it to none when you want the element to be "not displayed" and set it to block to "display it".
Also if you don't want all menus to drop-down together, move the :hover pseudo-selector in .nav:hover > li > .subnav-block to li, so it would become .nav > li:hover > .subnav-block.

Applying animation when removing a class from div [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have the following code which applies .upper class to #top-btn and it appears at the bottom when the user scrolls down by a certain amount and removes it when they scroll back up. It animates #top-btn from the bottom of the page.
However when the class is removed while scrolling up, I want it to animate back down. The way I have it it just blinks away (because the class upper is just removed).
jQuery(document).ready(function($){
// adjust this number to select when your button appears on scroll-down
var offset = 300,
scroll_top_duration = 3000,
// bind with the button link
$animation = $('#top-btn');
// apply animation
$(window).scroll(function(){
( $(this).scrollTop() > offset ) ? $animation.addClass('upper') :
$animation.removeClass('upper');
});
});
body,html{
width:100%;
position:relative;
height:100%;
}
body{
background-color:green;
height:4000px;
}
#top-btn {
position: fixed;
z-index: 999;
padding: 0; margin: 0;
bottom: -100px; right: 0;
}
#top-btn.upper {
bottom: 0;
-webkit-transition: bottom 0.35s ease;
-moz-transition: bottom 0.35s ease;
-ms-transition: bottom 0.35s ease;
-o-transition: bottom 0.35s ease;
transition: bottom 0.35s ease;
}
#top-btn-BG {
display: block;
position: relative;
z-index: 950;
border-width: 0 0 100px 100px;
border-color: transparent transparent #fff transparent;
border-style: solid;
right: 0; bottom: 0;
width: 0; height: 0;
-webkit-transform:rotate(360deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="top-btn">Button</button>
Instead of removing .upper you should add a class .lower which will have bottom:-30px;. If you don't know height of the button then you can set it from jquery.
Then your jquery will become like this:
( $(this).scrollTop() > offset ) ?
$animation.addClass('upper').removeClass("lower"):
$animation.addClass('lower').removeClass("upper");
jQuery(document).ready(function($){
// adjust this number to select when your button appears on scroll-down
var offset = 300,
scroll_top_duration = 3000,
// bind with the button link
$animation = $('#top-btn');
// apply animation
$(window).scroll(function(){
( $(this).scrollTop() > offset ) ? $animation.addClass('upper').removeClass("lower"):
$animation.addClass('lower').removeClass("upper");
});
});
body,html{
width:100%;
position:relative;
height:100%;
}
body{
background-color:green;
height:4000px;
}
#top-btn {
position: fixed;
z-index: 999;
padding: 0; margin: 0;
bottom: -100px; right: 0;
}
#top-btn.upper {
bottom: 0;
-webkit-transition: bottom 0.35s ease;
-moz-transition: bottom 0.35s ease;
-ms-transition: bottom 0.35s ease;
-o-transition: bottom 0.35s ease;
transition: bottom 0.35s ease;
}
#top-btn.lower {
bottom:-30px;
-webkit-transition: bottom 0.35s ease;
-moz-transition: bottom 0.35s ease;
-ms-transition: bottom 0.35s ease;
-o-transition: bottom 0.35s ease;
transition: bottom 0.35s ease;
}
#top-btn-BG {
display: block;
position: relative;
z-index: 950;
border-width: 0 0 100px 100px;
border-color: transparent transparent #fff transparent;
border-style: solid;
right: 0; bottom: 0;
width: 0; height: 0;
-webkit-transform:rotate(360deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="top-btn">Button</button>
You can call a function in conditional operator for removing the class and scroll the page down. something like this:
( $(this).scrollTop() > offset ) ? $animation.addClass('upper') :
scrollDown();
function scrollDown(){
$('#top-btn').removeClass('upper');
//here goes the code to scroll down//;
}

Using Headroom.js with WordPress

I would like to use headroom.js on my site to be able to hide the header as I scroll down and have it reappear as I scroll up. I am using WordPress.
I tried putting the js file in the theme folder and calling it with functions.php, but it didn't seem to work, so instead I am using this plugin: https://twd.wordpress.org/plugins/headroomjs/.
I have the following in the additional CSS:
.headroom {
transition: transform 200ms linear;
}
.headroom--top .x-navbar {
background-color: transparent;
border-bottom: none;
box-shadow: none;
}
.sub-menu ul li{
color: #ddd !important;
}
.headroom--top .x-navbar a{
color: #fff !important;
}
.headroom--top .x-navbar .desktop .sub-menu a{
color: black !important;
}
.headroom--not-top .x-navbar {
background-color: #fff;
}
.headroom {
transition: transform 200ms linear;
}
.headroom--pinned {
transform: translateY(0%);
}
.headroom--unpinned {
transform: translateY(-100%);
webkit-transition: all .3s ease-in-out;
-moz-transition: all .3s ease-in-out;
-o-transition: all .3s ease-in-out;
transition: all .3s ease-in-out;
}
.headroom {
position: fixed;
z-index: 12;
right: 0;
left: 0;
top: 0;
webkit-transition: all .3s ease-in-out;
-moz-transition: all .3s ease-in-out;
-o-transition: all .3s ease-in-out;
transition: all .3s ease-in-out;
}
.masthead {
height:0px;
}
The header color is changing as I scroll down, but it is still fixed, and does not disappear on scroll down. What am I doing wrong?
Thanks!
You either need to apply the classes to your templates or use the plugin.
See documentation to correct your install: http://wicky.nillia.ms/headroom.js/
Specifically add an id or data element to your :
<!-- selects $("[data-headroom]") -->
or
<header id="header">
And enqueue the js to functions php, it should call itself; if not, you need to add its document call in the footer template of your theme.
The WordPress plugin hasn't been updated in 3 years so I don't recommend it but you could give it a look and compare it with your install to fix it..

Transition on overlay

I have a left menu that slides in when the user clicks on the hamburger. Behind it is an overlay with the following SCSS:
.overlay {
background-color: $glb-nav-80-opacity-white;
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 200;
cursor: pointer;
}
.left-menu {
background: $glb-nav-dark-blue;
position: fixed;
overflow-x: hidden;
overflow-y: auto;
margin: 0;
padding: 0;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
transition: all 0.3s ease;
a:hover {
color: $glb-nav-white;
}
}
When people click on the hamburger menu, the overlay shows up abruptly. I need it to fade in. How can I do that using CSS?
Here's the HTML:
<div class="overlay"></div>
<div class="left-menu"></div>
When the user opens the page the left-menu has a left position of -284px. Then when people click on the hamburger icon, I add a class to the div that sets its left position to 0.
Instead of adding a class, you can set the opacity using jQuery's .CSS
For example:
$(".overlay").css({opacity:50});
To reset it, use
$(".overlay").removeAttr("style");
Use CSS transitions as you did for the menu:
.overlay {
background-color: $glb-nav-80-opacity-white;
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 200;
cursor: pointer;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
transition: all 0.3s ease;
}
Use css transitions as you did with the menu, ie:
.overlay {
// other css
-webkit-transition: opacity 500ms ease;
-moz-transition: opacity 500ms ease;
-o-transition: opacity 500ms ease;
transition: opacity 500ms ease;
}
Or, if using SASS: #include transition(opacity 500ms ease);
Note, you can set the timing and style to be what you like, more here: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions
just add transition to the overlayed div
div {
/* -transition: 2 seconds- */
-webkit-transition: width 2s; /* For Safari 3.1 to 6.0 */
transition: 2s;
}
div:hover {
height: 200px;
background: red;
}
<div>transition on hover</div>

transform from center of text line

I have transform css applied to a line of text (font-size), but it animates from the left side, I want it to animate from the center. I am using Bootstrap framework so the div is vert/horiz centred.
HTML
<article class="col-md-12">
<div class="lg-indx-img">
<div class="cat-icn">
<?php the_title(); ?>
</div>
</div>
</article>
CSS
article {
position: relative;
margin-bottom: 10px;
width: 100%;
}
.linkage {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
.lg-indx-img { padding: 20% 0; }
.cat-icn {
position: absolute;
z-index: 9;
left: 50%;
top: 50%;
opacity: 0;
font-size: 15px;
color: #fff;
text-align: center;
transform-origin: 50% 50%;
-webkit-transition: all 0.4s ease;
-moz-transition: all 0.4s ease;
-o-transition: all 0.4s ease;
-ms-transition: all 0.4s ease;
transition: all 0.4s ease;
}
.linkage:hover + .cat-icn {
opacity: 1;
font-size: 25px;
}
when .linkage is hovered the title in .cat-icn increases in size. I don't know the length of the text line since it's generated by Wordpress post.
EDIT - The top picture is what it does now, the bottom picture is what I want it to do
Instead of setting a new font size, you can try using the transform property, which should do the right thing since you have transform-origin already set to the center.
.linkage:hover + .cat-icn {
transform: scale(1.5);
}
Try this out.
http://codepen.io/Chevex/pen/bdRvvJ
.linkage:hover + .cat-icn {
opacity: 1;
transform: scale(3);
}
Instead of animating the font size, animate the transform property instead. Then in your hover rule use the transform property to adjust the scale of the element.

Categories

Resources