Sliding transition for list items when one is removed - css

It has been a while since I last used CSS. I'm having trouble with this one. I have a list of items. When I click on the cross it removes the item from the DOM. However what I'm looking for is to make the rest of the items slide up when one has been removed.
Currently it just removes the item as desired but instantly moves the other to 'fill in the space'. I know there is a way to do it with CSS transitions, but the question is how...
var remove = function(id) {
document.querySelector('#'+id).remove();
}
div {
border: 1px solid grey;
width: 100px;
margin: auto;
margin-bottom: 10px;
text-align: center;
padding: 10px
}
span {
float: right;
cursor: pointer;
}
<div id="one">One <span onclick="remove('one')">×</span></div>
<div id="two">Two <span onclick="remove('two')">×</span></div>
<div id="three">Three <span onclick="remove('three')">×</span></div>
<div id="four">Four <span onclick="remove('four')">×</span></div>

Like this?
I added a class called closeSlide which will animate the element to slide up. And after the transition, it is removed by setting up a timer.
And for visual prettiness, I've added overflow:hidden to your target style, which can alternatively, be added via JS using elem.style.overflow = 'hidden'. But for justification, I added that to the target style because I want to avoid any possible jitters when initiating the closing animation.
var remove = function(id) {
var elem = document.querySelector('#'+id);
elem.className += 'closeSlide';
setTimeout(function(){
elem.remove();
}, 200);
}
div {
border: 1px solid grey;
width: 100px;
margin: auto;
margin-bottom: 10px;
text-align: center;
padding: 10px;
overflow:hidden;
}
span {
float: right;
cursor: pointer;
}
.closeSlide {
margin-bottom:0;
height:0px;
padding-top:0;
padding-bottom:0;
transition: 0.2s all ease-out;
/*Just reverse any spacing styling you've applied to make it **magically** disappear*/
}
<div id="one">One <span onclick="remove('one')">×</span></div>
<div id="two">Two <span onclick="remove('two')">×</span></div>
<div id="three">Three <span onclick="remove('three')">×</span></div>
<div id="four">Four <span onclick="remove('four')">×</span></div>

Related

I want to use a transition for the moment when two icons switch with each other

I'm a beginner, i searched a lot for an answer on the internet but none of them managed to clarify why the transition doesn't work.
HTML:
<li><i class="material-icons menu-bar" id="menu-bar">menu</i></li>
<ul class="menu-bar-content hide" id="menu-bar-content">
This is my Js :
const menuBar = document.getElementById('menu-bar');
const menuBarContent = document.getElementById('menu-bar-content');
var menuOpen = false;
menuBar.addEventListener('click' , menuBarBtn)
function menuBarBtn() {
if ( menuOpen == false) {
menuBar.innerHTML = '<li><i class="material-icons undo-icon">undo</i></li>';
menuBarContent.className = 'menu-bar-content';
menuOpen = true;
}
else {
menuBar.innerHTML = '<li><i class="material-icons menu-bar" id="menu-bar">menu</i></li>';
menuBarContent.className = 'menu-bar-content hide'
menuOpen = false;
}
};
And this is my Css:
.menu-bar {
display: inline-block;
vertical-align: middle;
float: right;
color: white;
margin: -1.45% 0.7%;
font-size: 23px !important;
transition: .4s;
}
.undo-icon {
display: inline-block;
vertical-align: middle;
float: right;
color: #1ec7b9;
margin: 0.9% 3%;
transform: rotateZ(43.2deg);
font-size: 14px !important;
border: 2px solid rgb(255, 255, 255);
border-radius: 70%;
padding: 1.5px;
transition: .4s;
}
After the icons switch with each other, i wanted to do it with a transition effect. Thank you in advance!
The transition is not happening because the element is completely removed/replaced with another onclick.
It is CSS properties that transition and the browser thinks it's got a completely new element, not one that is to be transitioned in some way.
What we do is have both li elements in the document all the time, but one of them will be hidden. To do this gradually we can use opacity: 0 alongside the rotation in a new class which is called faded here.
On a click we don't replace the li elements but we set the one that has not been clicked to have class faded - it will rotate and end up invisible with opacity: 0 and we remove the class faded from the other li element so it will rotate back to normal and with normal opacity.
Javascript has a handy function, toggle, for adding and removing a class so we don't have to remember which element is hidden and which is in view - having or not having class faded is enough.
Here is the snippet. Note, the body has been given a background-color just so we can see the white menu and the white border. Also I do not have access to whatever icons you are using so the i elements are replaced with spans just for this demo.
const menuBar = document.getElementById('menu-bar');
const undoBar = document.getElementById('undo-bar');
menuBar.addEventListener('click' , menuBarBtn);
undoBar.addEventListener('click' , menuBarBtn);
function menuBarBtn() {
menuBar.classList.toggle('faded');
undoBar.classList.toggle('faded');
};
body {
background-color: gray; /* just for this test so we can see the white menu */
}
.menu-bar {
display: inline-block;
vertical-align: middle;
float: right;
color: white;
margin: -1.45% 0.7%;
font-size: 23px !important;
transition: .4s;
}
.undo-icon {
display: inline-block;
vertical-align: middle;
float: right;
color: #1ec7b9;
margin: 0.9% 3%;
font-size: 14px !important;
border: 2px solid rgb(255, 255, 255);
border-radius: 70%;
padding: 1.5px;
transition: .4s;
}
.faded { /* added this so when an element has class="faded" it cannot be seen and it is rotated */
opacity: 0;
transform: rotateZ(43.2deg);
}
<ul class="menu-bar-content" id="menu-bar-content" style="margin-top:30px;"> <!-- added just for this tesmargin t so we could see the white menu word in the snippet -->
<li><span class="menu-bar" id="menu-bar">menu</span></li> <!-- remember to put back the <i icon calls in here in place of the spans -->
<li><span class="menu-bar undo-icon faded" id="undo-bar">undo</span></li> <!-- ...and we start this off as faded so it isn't seen to begin with -->
</ul>

Hover property applies to child

Good day everyone, i have been trying to apply box-shadow property to a webpage but if i apply the effect to the normal state, everything works fine but on the hover state, if i hover on the child, it applies to both the parent and the child.
Normal state: everything works fine
hover state: property applies to each element in the div
I have tried using Jquery to toggle the state but it does not work.
HTML
<div class="results">
<div class="result_wrapper">
<div class="result">
<h2 class="single"><font size="4dp">A title</font></h2>
<div class="single">shortDiscription</div>
</div>
</div>
</div>
CSS
.result {
background-color: #fff0f0;
padding: 5px;
margin: 1%;
width: 600px;
box-shadow: 2px 2px 5px grey;
transition: all 0.5s ease;
}
.myClmass :hover {
display: block;
box-shadow: 2px 2px 5px grey;
transition: all 0.5s ease;
}
.singleHover {
all: revert;
}
.results {
float: left;
}
.vid {
float: right;
margin: 1%;
}
.vidHeader {
background-color: #d69797;
padding-top: 10px;
padding-bottom: 10px;
padding-right: 400px;
padding-left: 5%;
text-align: center;
}
This is my java servlet code:
out.println("<div class=\"results\">");
for(Element post : results){
String link = post.childNode(0).childNode(0).absUrl("href");
String title = post.getElementsByTag("a").text();
String shortDiscription = post.getElementsByClass("b_caption").get(0).child(1).toString();
out.println("<div class=\"result_wrapper\" >");
out.println("<div class=\"result\">");
out.println("<h2 class=\"single\"><font size=\"4dp\">"+title+"</font></h2>");
out.println("<div class=\"single\">"+shortDiscription+"</div>");
out.println("</div></div>");
}
out.println("</div>");
The selector .myClmass :hover means that the rule is applied to all descendant elements of the element with the class myClmass where the mouse is actually over. So your rule is applied to all elements that are within the element with the class myClmass
If you want to apply the box shadow to the element with the class myClmass then the selector has to be .myClmass:hover without the space between .myClmass and :hover
Try pointer-events:none; on your child element in your css

Hamburger Button in Bootstrap

I want to fix the classic bootstrap style hamburger button on my navbar, like the one that appears as a toggle button when the screen size gets sufficiently small.
Anyways, how can I display the button as is, without having to implement it through the navbar-toggle class?
EDIT: Here is the button I have:
<div>
<div class="center">
<button type="button" class="btn">☰</button>
</div>
</div>
body {
background: #222;
}
.center {
width: 100px;
margin: 50px auto;
}
.btn {
background-color: #222;
border: 1px solid #3A3A3A;
color: #D3D3D3;
width: 42px;
margin-left: 42px;
font-size: 23px;
height: 34px;
transition: color 0.45s;
transition: border 0.45s;
}
button.btn:hover {
color: #2978E0;
border: 1px solid #61A5FF;
}
https://jsfiddle.net/rstty1ye/
Using a UTF-8 character was mentioned on tutsplus.com
It's not my original finding or idea.
Nevermind, I figured it out.
Created a custom button and used an UTF-8 character: Trigram for Heaven for the bars.

appendChild probably keeps hover css state in IE9

I am strugling to make a simple function work in IE9. It works perfectly in Chrome and FF.
The purpose is to have 2 "ul" lists and move "li" elements between them, on click.
I would like to have li elements with blue background in the first container (MultiListAvailableElements), changing to green on mouse over. And opposite in the second container (MultiListSelectedElements) - green background, changing to blue on mouse over.
The problem is that in IE9 element's behave like they never loose hover state after I append them to opposite list. I have to move mouse over them (and out) to make them look like they should. So, for example, I click blue element from first container, it moves to second container and is still blue (blue in the second container is only for hover state, it should be green by default as the mouse is no longer over the element because the element has moved to different place). Then I have to move mouse over and out the elements in second container to make them come back to normal (green color).
HTML:
<div style="height: 210px; width: 600px;">
<div class="MultiListAvailableElements">
<ul id="OptionsUL">
<li id="id1" onclick="MLAdd(this)">1</li>
<li id="id2" onclick="MLAdd(this)">2</li>
<li id="id3" onclick="MLAdd(this)">3</li>
<li id="id4" onclick="MLAdd(this)">4</li>
<li id="id5" onclick="MLAdd(this)">5</li>
</ul>
</div>
<div class="MultiListSelectedElements">
<ul id="SelectedUL">
</ul>
</div>
</div>
CSS:
/* ------------------------------------ Available Elements --- */
.MultiListAvailableElements {
overflow-y: scroll;
width: 250px;
height: 200px;
border: 1px solid black;
}
.MultiListAvailableElements ul {
margin: 0px;
padding: 0px;
list-style-type: none;
}
.MultiListAvailableElements ul li {
background-color: #e5ecff;
border: 1px solid #c3caff;
width: 180px;
text-align: center;
margin-bottom: 2px;
padding: 2px;
cursor: pointer;
cursor: hand;
font-family: arial;
font-size: small;
}
.MultiListAvailableElements ul li:hover {
background-color: #e5ffec;
border: 1px solid #a3ffaa;
}
/* ------------------------------------ Selected Elements --- */
.MultiListSelectedElements {
overflow-y: scroll;
width: 250px;
height: 200px;
border: 1px solid black;
}
.MultiListSelectedElements ul {
margin: 0px;
padding: 0px;
list-style-type: none;
}
.MultiListSelectedElements ul li {
background-color: #e5ffec;
border: 1px solid #a3ffaa;
width: 180px;
text-align: center;
margin-bottom: 2px;
padding: 2px;
cursor: pointer;
cursor: hand;
font-family: arial;
font-size: small;
}
.MultiListSelectedElements ul li:hover {
background-color: #e5ecff;
border: 1px solid #c3caff;
}
JavaScript:
function MLAdd(Obj) {
document.getElementById("SelectedUL").appendChild(document.getElementById(Obj.id));
document.getElementById(Obj.id).onclick = function () { MLDel(Obj); }
}
function MLDel(Obj) {
document.getElementById("OptionsUL").appendChild(document.getElementById(Obj.id));
document.getElementById(Obj.id).onclick = function () { MLAdd(Obj);
}
You don't actually have to clone. Just remove it and append it elsewhere. Also, you don't have to request the element from the DOM because you are already passing it as an argument to the function (it's coming from the this in the original function call).
function MLAdd(Obj) {
Obj.parentNode.removeChild(Obj);
document.getElementById("SelectedUL").appendChild(Obj);
Obj.onclick = function () { MLDel(Obj); }
}
I'd also cache the results of document.getElementById("SelectedUL") as well by setting it in a variable from within a closure, but I'll leave that for you to figure out.

3 divs, middle div needs to be a variable length dotted line

I would like to create a restaurant style menu card.
I do not want to use tables. I'm trying to accomplish this using DIVs only.
This is what I have:
.review-row { // (1)
padding: 0;
}
.review-cat { // (2)
font-size: 25px;
float: left;
}
.review-dots { // (3)
padding-bottom: 5px;
float: left;
}
.review-dots-inner { // (3)
height: 5px;
border-bottom: 3px dotted #E65540;
}
.review-rating { // (4)
float: right;
font-size: 50px;
}
In the image think of (3) as being 2 DIVS, the inner div is there to get the dots on the same baseline as the text.
Now this doesn't work. How to proceed?
All DIVs should adjust width according to content
Middle DIV needs to act as a 'filler'
You don't need images..
See working example here..
do the following..
<!--Markup and styles-->
<div class="item-container">
<span class="item">Quality</span>
<span class="fill"></span>
<span class="score">8.0</span>
</div>
<div class="item-container">
<span class="item">Presentation</span>
<span class="fill"></span>
<span class="score">9.5</span>
</div>
<style>
.item-container{
width:200px;
/*border:1px solid #AAA;*/
display:block;
padding:5px;
margin:2px;
}
.item{
float:left;
margin:2px;
}
.score{
float:right;
margin:2px;
}
.fill{
border:none;
border-bottom:1px dotted #000;
display:inline-block;
}
</style>
And do this in your $().ready()
$('.item-container').each(function(){
//alert($('.fill', $(this)).width());
var item = $('.item', $(this));
var score = $('.score', $(this));
var itemWidth = item.width();
var scoreWidth = score.width();
var offset1 = item.offset().left;
var offset2 = score.offset().left;
var fillerWidth = (offset2 - offset1) - (itemWidth + scoreWidth);
$('.fill', $(this)).css('width', fillerWidth + 10);
});
Easy with Flexbox :) . See working example here..
<div class="row">
<div class="text-box">Breakfast</div>
<div class="dots-box"></div>
<div class="text-box">8:30 am - 9:30 am</div>
</div>
CSS
.row{
display: flex;
overflow:hidden;
padding:15px;
width:90%;
}
.text-box{
flex: 0 0 auto;
}
.dots-box{
flex: 1 1 auto;
position: relative;
}
.dots-box:before{
position:absolute;
bottom: 5px;
width: 94%;
border-bottom: 1px dotted #000;
content: '';
left: 3%;
}
You could set the dots as a repeating background, then add a white (or whatever) background for .review-cat and .review-rating.
This way you can then continue as you are going, float the rating to the right, make sure it is first in the html before (2) which is floated to the left.
background-color: white; is what you'll need to do
and for the .review-row you'll want to add the dots in as a repeating background
background: transparent url(../images/dots.png) repeat 0 0;
Good luck

Resources