I am trying to create a box that can expand and collapse with a simple slide out animation. If you run the example below, the idea is that it starts with one red line and when you click the button it separates into two read lines and gently expands to reveal the content like pulling a draw out of a table.
I've tried both transform, animation, relative: positioning with top, and i'm unable to get the desired effect.
The containing box should expand in size
function expandContract() {
const el = document.getElementById("expand-contract")
el.classList.toggle('expanded')
el.classList.toggle('collapsed')
}
#container {
border: 1px solid black;
padding: 15px;
}
#top-section {
border-bottom: 1px solid red;
}
#expand-contract {
border-bottom: 1px solid red;
}
.expand-contract {
transform: translateY(-100%)
overflow: hidden;
}
#keyframes slide-in {
100% {
transform: translateY(0%)
}
}
.expanded {
background-color: green;
animation-name: slide-in;
animation-duration: 1s;
}
.collapsed {
background-color: red;
transform: translateY(-100%)
}
<div id="container">
<div id="top-section">
This is always displayed
</div>
<div id="expand-contract" class="expanded">
This section expands and contracts
<table>
<tr><td>test1</td></tr>
<tr><td>test2</td></tr>
<tr><td>test3</td></tr>
<tr><td>test4</td></tr>
</table>
</div>
<div id="bottom-section">
This section is always displayed
</div>
</div>
<button onclick="expandContract()">Expand/Contract</button>
You can achieve this using the CSS transition along with toggled styles. Initially you may think to transition the height (from 0 to initial so that it expands dynamically based on height) but unfortunately CSS transition doesn't properly handle this.
Instead, you can wrap it in a container of its own with overflow: hidden and then use a margin-top: -100% to hide it, and 0 to show it.
Here is your code with this modification:
function expandContract() {
const el = document.getElementById("expand-contract")
el.classList.toggle('expanded')
el.classList.toggle('collapsed')
}
#container {
border: 1px solid black;
padding: 15px;
}
#top-section {
border-bottom: 1px solid red;
}
#expand-container {
overflow: hidden;
}
#expand-contract {
border-bottom: 1px solid red;
margin-top: -100%;
transition: all 1s;
}
#expand-contract.expanded {
background-color: green;
margin-top: 0;
}
<div id="container">
<div id="top-section">
This is always displayed
</div>
<div id="expand-container">
<div id="expand-contract" class="expanded">
This section expands and contracts
<table>
<tr><td>test1</td></tr>
<tr><td>test2</td></tr>
<tr><td>test3</td></tr>
<tr><td>test4</td></tr>
</table>
</div>
</div>
<div id="bottom-section">
This section is always displayed
</div>
</div>
<button onclick="expandContract()">Expand/Contract</button>
hope to help you
HTML
<div class="container">
<div id="top-section">
This is always displayed
</div>
<div id="expand-container">
<div class="expanded" id="expand-contract">
<table>
<tr><td>test1</td></tr>
<tr><td>test2</td></tr>
<tr><td>test3</td></tr>
<tr><td>test4</td></tr>
</table>
</div>
</div>
</div>
<button class="header" onclick="expandContract()">Expand/Contract</button>
css
.container {
width:100%;
border:1px solid #d3d3d3;
}
.container div {
width:100%;
}
.header {
background-color:#d3d3d3;
padding: 2px;
cursor: pointer;
font-weight: bold;
}
.container .expanded {
display: none;
padding : 5px;
}
js
function expandContract() {
$header = $(".header");
$content = $("#expand-contract")
$content.slideToggle(500, function () {
$header.text(function () {
return $content.is(":visible") ? "Collapse" : "Expand";
});
});
};
see here enter code here
Related
I am bit troubled in aligning the content as shown in the image. Along with that I need to redirect to page 1 by clicking on content section and redirect to page 2 by clicking the icon separately. How can I solve it using javascript?
These things can be achieved without the use of JavaScript besides the point that it's generally bad practice to manipulate DOM with JavaScript as much can be done with css rules, animations, basic html.
To align the icon first you should try these css rules applied on icon element:
.your-icon {
top: 0;
right: 0;
}
Assuming your icon in html is declared like this:
<img src="foo.img" class="your-icon">
Although it depends on current rules applied (e.g. you should use other rule set if flex is enabled on parent element). Perhaps spacing with fixed values between content section is involved that is pushing the icon out of the way (padding, margin rules applied?).
As for navigation html href is good enough
.a {
/* width:400px; */
height: 300px;
border: 1px solid;
}
.b {
width: 100%;
float: left;
/* border:1px solid red; */
}
.c {
width: 70%;
/* border:1px solid; */
float: left;
/* display:flex; */
float: left;
}
.c div{padding: 5px;}
.d {
border: 1px solid;
}
.box {
width: 29%;
float: left;
border: 1px solid;
height: 100%;
}
.rTable {
display: block;
width: 100%;
}
.rTableHeading,
.rTableBody,
.rTableFoot,
.rTableRow {
clear: both;
}
.rTableHead,
.rTableFoot {
/* background-color: #DDD; */
font-weight: bold;
}
.rTableCell,
.rTableHead {
/* border: 1px solid #999999; */
float: left;
height: 17px;
overflow: hidden;
padding: 5px;
width: 20%;
}
.rTable:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
<div class='a'>
<div class='b'>
<div class='c'>
<div>Name</div>
<div>Address</div>
<div>PIN</div>
</div>
<div class='box'>ICON</div>
</div>
<div class='d'>
<div class="rTable">
<div class="rTableRow">
<div class="rTableHead"><strong>Time</strong></div>
<div class="rTableHead"><span style="font-weight: bold;">Duration</span></div>
<div class="rTableHead"><strong>Amount</strong></div>
<div class="rTableHead"><strong>Position</strong></div>
</div>
<div class="rTableRow">
<div class="rTableCell">5</div>
<div class="rTableCell">2</div>
<div class="rTableCell">3</div>
<div class="rTableCell">4</div>
</div>
</div>
</div>
</div>
I am 95% of the way done with what I would like to have this webpage do. On this page I am looking to have my search bar filter the boxed options and fill them towards the top left. Right now, the boxes filter correctly and fill upwards (not quite sure why they filter upwards), but they don't fill upwards AND to the left. Any help would be greatly appreciated!
Note: The snippet runs, but there is no container for the boxes where as squarespace naturally makes these.
function search_topics() {
let input = document.getElementById('searchbar').value
input = input.toLowerCase();
let x = document.getElementsByClassName('text');
let y = document.getElementsByClassName('overlay-image _b1')
for (i = 0; i < x.length; i++) {
if (!x[i].innerHTML.toLowerCase().includes(input)) {
y[i].style.display = "none";
} else {
y[i].style.display = "table-cell";
}
}
/* Main container */
.overlay-image {
position: relative;
width: 100%;
}
/* Original image */
.overlay-image .image {
display: block;
width: 100%;
height: auto;
}
/* Original text overlay */
.overlay-image .text {
color: #fff;
font-size: 2.0em;
text-shadow: 2px 2px 2px #000;
text-align: center;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
}
/* Text on hover formatting */
.overlay-image .text_2 {
color: #fff;
font-size: 0.75em;
line-height: 1.5em;
text-align: center;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
}
/* New overlay on hover */
.overlay-image .hover {
position: absolute;
top: 0;
height: 100%;
width: 100%;
opacity: 0;
transition: 0.5s ease;
background-color: rgba(0, 0, 0, 0.5);
}
/* New overlay appearance on hover */
.overlay-image:hover .hover {
opacity: 1;
}
.overlay-image .normal {
transition: 0.5s ease;
}
.overlay-image:hover .normal {
opacity: 0;
}
#searchbar{
margin-left: 15%;
padding:15px;
border-radius: 10px;
width: 70%;
}
<body>
<input id="searchbar" onkeyup="search_topics()" type="text"
name="search" placeholder="Search topics....">
</body>
<div class=" overlay-image _b1 ">
<a href="url for block">
<img class=" image _b2 " src="https://i.redd.it/m3u40szpez231.jpg" />
<div class=" normal _b4 ">
<div class="text">Title of a block</div>
</div>
<div class=" hover _b3 ">
<div class=" text_2 ">Test that appears when block is hovered</div>
</div>
</a>
</div>
<div class=" overlay-image _b1 ">
<a href="url for block">
<img class=" image _b2 " src="https://i.redd.it/m3u40szpez231.jpg" />
<div class=" normal _b4 ">
<div class="text">Title of a block 2</div>
</div>
<div class=" hover _b3 ">
<div class=" text_2 ">Test that appears when block is hovered</div>
</div>
</a>
</div>
Your items move upward because the rows above are emptied of displayed content, allowing them to collapse. They don't move to the left because there are still table cells there. The problem you're having is that you're using a table to do work that tables were not designed to do. Css has a tool to do what you want called flexbox. Here's an example: https://codesandbox.io/s/tender-sky-9yyxf
<body>
<input id="search" type="text" placeholder="search"></input>
<div id="options">
<div value="coriander">Coriander</div>
<div value="anise">Anise</div>
<div value="lavender">Lavender</div>
<div value="fennel">Fennel</div>
<div value="ginger">Ginger</div>
<div value="sage">Sage</div>
<div value="cinnamon">Cinnamon</div>
</div>
<script src="src/index.js"></script>
</body>
import "./styles.css";
const search = document.getElementById("search");
if (search) {
search.addEventListener("change", event => {
if (event.target.value) {
// Normalize the search term.
const value = event.target.value.toLowerCase();
console.log(value);
// Hide all non matching elements.
document
.querySelectorAll(`#options :not([value*=${value})`)
.forEach(item => {
item.classList.add("hidden");
});
// Show all matching elements.
document.querySelectorAll(`#options [value*=${value}]`).forEach(item => {
item.classList.remove("hidden");
});
} else {
// If there are no search terms, show all elements.
document.querySelectorAll(`#options div`).forEach(item => {
item.classList.remove("hidden");
});
}
});
}
#options {
/* Set the options to fit three items in a row, and wrap them. */
display: flex;
flex-direction: row;
/* Setting max-width instead of width will allow your list to automatically adjust to smaller screen sizes. */
max-width: 70em;
flex-wrap: wrap;
}
#options div {
/* Set the items to a fixed width */
width: 20em;
border: 1px solid red;
margin: 0.5em;
text-align: center;
}
#options div.hidden {
/* Add a style to hide items when they don't apply to the search. */
display: none;
}
I have this simple horizontal chart script.
When you click on the button, width of the filler changes to 100%.
I've tried to add transition to the .filler, but it does not work.
How can I animate it?
$("#button").on("click", function() {
$(".filler").css("width", "100%");
$(".filler").html("100%");
});
.borders {
margin: 10px 0px 10px 0px;
width: 200px;
border: 1px solid black;
}
.filler {
background-color: green;
white-space: nowrap;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="button">Click me to fill the chart</button>
<div class="borders">
<div class="filler" style="width:15%;">15%</div>
</div>
Add transition to filter class
.filter {transition: all 0.5s;}
I am trying to insert a collapsible table with HTML Box in a Google site. The code of the collapsible table is from http://tutorials.seowebpower.com/google-sites-advanced/collapsible-table. The code is
<html>
<head>
<style>
.container {
background-color:deepskyblue;
width: 600px;
height:50px;
position: relative;
}
.title {
font-size: 16pt;
font-weight: bold;
color: aliceblue;
position: absolute;
left: 20px;
top:25%;
}
#opened {
display: none;
}
.arrow-up {
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid white;
}
.arrow-down {
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid white;
}
.arrow-up, .arrow-down {
position: absolute;
top: 40%;
right:15px;
}
.hidden-content {
margin:0 0 20px 0;
padding: 10px 20px 10px 20px;
border: 1px solid deepskyblue;
border-top: none;
background-color: aliceblue;
}
</style>
<script>
var collapse;
var uncollapse;
var turnOn = true;
// Chrome Sites Fix
var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
function tempChromefix() {
// To turn off set true to false
if (turnOn == false && is_chrome) {
document.getElementById("opened").style.display = "block";
document.getElementById("closed").style.display = "none";
} else {
return false;
}
}
function uncollapse() {
document.getElementById("closed").style.display = "block";
document.getElementById("opened").style.display = "none";
}
function collapse() {
document.getElementById("opened").style.display = "block";
document.getElementById("closed").style.display = "none";
}
</script>
</head>
<body onLoad="tempChromefix()">
<table id="closed">
<tr>
<td>
<div class="container" onclick="collapse()">
<div class="title">Click to open drop-down</div>
<div class="arrow-down"></div>
</div>
</td>
</tr>
</table>
<table id="opened">
<tr>
<td>
<div class="container" onclick="uncollapse();">
<div class="title">Click to close drop-down</div>
<div class="arrow-up"></div>
</div>
<div class="hidden-content">
<h3>It works!</h3>
<p>This content is to be hidden from the user until clicked. </p>
</div>
</td>
</tr>
</table>
</body>
</html>
The problem I am facing is with width of the table. I would like it to have maximum possible width depending on the screen size. For example, I would like to have the table expand to the screen size in my MacBook as well as in iMac.
The logical way is to use the width: 100% so that the table inherits its parent's screen size. However it seems that inside an HTML Box the different categories does not inherit parent's attribute.
For example in the .container section, if I use width: 100%, it collapses to zero width instead of full size of the screen.
Would appreciate any help!
--- Madhur
I had this issue also, and eventually figured out (the very un-intuitive) way is to hover over the HTML box, and then click on the "Align center" icon. When you save, elements will be the full width (my div's were at least).
I would like to be able to add an animation to this simple query for when the div is transitioned to its new position.
<div class="container">
<div class="left-side-bar">
<div class="long blue" id="1">
1
</div>
<div class="short red" id="2">
2
</div>
</div>
<div class='middle-side-bar'>
<div class='long green' id="3">
3
</div>
</div>
<div class='right-side-bar'>
<div class='short yellow' id="4">
4
</div>
</div>
</div>
the CSS
.left-side-bar{
clear: both;
width: 32%;
text-align: center;
float: left;
margin-top: 1%;
margin-bottom: 100px;
}
.middle-side-bar{
width: 32%;
text-align: center;
float: left;
margin: 1% 0 1% 1.6%;
}
.right-side-bar{
width: 32%;
text-align: center;
float: left;
margin: 1% 0 1% 1.6%;
}
.green {
background-color: green;
}
.long {
height: 300px;
}
.short {
height: 200px;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
.yellow {
background-color: yellow;
}
Basically I want the div to be moved to its new place as an animated transition, rather than have it simply appear.
here is the jsfiddle
DEMO
Unfortunately, the replaceWith method does not work with animate in jQuery. Instead, you will probably need to find an alternative method to your solution. Here's one that slowly transitions the red box on top of the yellow box... http://jsfiddle.net/aeyg89rd/4/
I added the following jQuery, note that I used offset() to get the left and top properties of the yellow box, then I moved the red box to those left and top positions using animate() :
$(document).ready(function () {
var num4 = $("#4").offset();
$("#2").animate({ top: num4.top, left: num4.left }, 1000);
});
And I changed some CSS attributes for .red class so that I can move it around with the jQuery code above. More specifically, I changed its position to absolute, and gave it a width dimension:
.red {
position: absolute;
top: 320px;
background-color: red;
width: 150px;
}