I'm making a collapsible panel and the issue is with the [data-panel] not keeping the css transition when it's set to height: 100%. it works fine for fixed height i.e. height: 150px , but it's important to keep height dynamic since I don't know the available space of the content inside. i'd prefer not modifying the html or js but i'm open to suggestions...
Codepen: issue on line 44 in css
https://codepen.io/oneezy/pen/bGBpXaW
function activeLinks() {
document.addEventListener('click', e => {
let linkEl = e.target.closest('[data-link]');
if (linkEl) {
let url = linkEl.dataset.link;
let linkEls = document.querySelectorAll('[data-link]');
let ActivelinkEls = document.querySelectorAll(`[data-link="${url}"]`);
// remove "active" class from all links
Array.from(linkEls).forEach( (el) => {
el.classList.remove('active');
});
// add "active" class to all matching links
Array.from(ActivelinkEls).forEach( (el) => {
let prevLink = el.parentElement.previousElementSibling;
let prevPrevLink = el.parentElement.parentElement.previousElementSibling;
el.classList.add('active');
if (prevLink && prevLink.dataset.link) {
prevLink.classList.add('active');
prevLink.parentElement.classList.add('active');
}
if (prevPrevLink && prevPrevLink.dataset.link) {
prevPrevLink.classList.add('active');
prevPrevLink.parentElement.classList.add('active');
}
});
}
});
}
activeLinks();
/* Reset
*********************************/
* { margin: 0; padding: 0; box-sizing: border-box; font-family: roboto; }
html, body { height: 100%; overflow-x: hidden; }
a { text-decoration: none; display: block; }
/* Layout
*********************************/
#page { display: grid; grid-template-columns: 160px 1fr; gap: 3rem; height: 100%; }
#nav { background: black; display: block; align-items: start; align-content: start; justify-content: stretch; padding: 2rem 1rem; }
#main { display: flex; justify-content: space-around; padding: 2rem 5rem 0 0; }
/* Navigation
*********************************/
/* Sections */
#nav .link-level__one { margin: 1rem 0; }
#nav .link-level__two { }
#nav .link-level__three { position: relative; }
#nav .link-level__three::after { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px; width: 100%; background: gray; }
/* Links */
#nav .link-level__one a { padding: .25rem .5rem; color: gray; font-weight: 900; }
#nav .link-level__one a.active { color: white; }
#nav .link-level__two a { padding: .25rem .5rem; color: gray; font-weight: normal; }
#nav .link-level__two a.active { color: white; }
#nav .link-level__three a { padding: .25rem .5rem; color: gray; }
#nav .link-level__three a.active { color: white; font-weight: normal; }
/* Main
*********************************/
#main section { }
#main a { color: black; padding: 1rem .5rem; }
#main a.active { background: blue; color: white; }
/* Panel
*********************************/
[data-panel] { height: 0; overflow: hidden; transition: .22s .22s ease-in-out; }
.active ~ [data-panel] { height: 150px; } /* I NEED THIS TO BE DYNAMIC HEIGHT! */
<div id="page">
<nav id="nav">
<!-- LINK 1
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
<!-- LEVEL 1 -->
<section class="navigation-links__wrapper link-level__one">
Link 1
<!-- LEVEL 2 -->
<section class="link-level__two" data-panel>
Link 1a
<!-- LEVEL 3 -->
<section class="link-level__three" data-panel>
Link 1a-1
Link 1a-2
Link 1a-3
</section>
</section>
</section>
<!-- LINK 2
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
<!-- LEVEL 1 -->
<section class="navigation-links__wrapper link-level__one">
Link 2
<!-- LEVEL 2 -->
<section class="link-level__two" data-panel>
Link 2a
<!-- LEVEL 3 -->
<section class="link-level__three" data-panel>
Link 2a-1
Link 2a-2
Link 2a-3
</section>
</section>
</section>
<!-- LINK 3
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
<!-- LEVEL 1 -->
<section class="navigation-links__wrapper link-level__one">
Link 3
<!-- LEVEL 2 -->
<section class="link-level__two" data-panel>
Link 3a
<!-- LEVEL 3 -->
<section class="link-level__three" data-panel>
Link 3a-1
Link 3a-2
Link 3a-3
</section>
</section>
</section>
</nav>
<main id="main">
<section>
<h2>Link Level 1</h2>
Link 1
Link 2
Link 3
</section>
<section>
<h2>Link Level 2</h2>
Link 1a
Link 2a
Link 3a
</section>
<section>
<h2>Link Level 3</h2>
Link 1a-1
Link 1a-2
Link 1a-3
Link 2a-1
Link 2a-2
Link 2a-3
Link 3a-1
Link 3a-2
Link 3a-3
</section>
</main>
</div>
It's a duplicate question that has been answered here:
How can I transition height: 0; to height: auto; using CSS?
You can use a max-height greater than it will ever be to accomplish this.
#menu #list {
max-height: 0;
transition: max-height 1s ease-out;
overflow: hidden;
background: #d5d5d5;
}
#menu:hover #list {
max-height: 1000px;
transition: max-height 1s ease-in;
}
I've somewhat came up with a solution I'm proud of; however, it's not perfect. The main trick in getting this to work was giving the [data-panel] a line-height: 0 and transitioning it when it becomes active (THE LINE-HEIGHT ONLY). Also you'll need to make sure the contents of the [data-panel] don't have any margin or padding (until the panel becomes active) or it will completely throw off the UI.
https://codepen.io/oneezy/pen/bGBBEmp
/* Panel
*********************************/
[data-panel] {
overflow: hidden;
line-height: 0;
opacity: 0;
pointer-events: none;
transition: line-height .22s ease-in-out;
}
.active + [data-panel] {
line-height: 1.4;
opacity: 1;
pointer-events: auto;
}
I'm answering my own question; however, I'm not accepting it as the chosen answer. I'd love to see more unique solutions added to this thread.
The short answer is that you can't. Height transitions will only work on elements that use a unit based value for their height property.
Here's an article detailing different techniques to achieve the same outcome: https://css-tricks.com/using-css-transitions-auto-dimensions/
Related
Hoping for a little guidance. I'm making a "slide up" menu for a site i'm using and I have it working, except it's not responsive. Ideally, i'd like to have it so whatever I put in the content under "Book Now" would be hidden no matter the size, while keeping "Book Now" shown.
The way I have it set up now, I have to be very verbose about heights, and it doesn't seem to really want to work on mobile.
Hoping you kind folks could point me in the right direction of what CSS I actually need to make this work!
Here is the JSFiddle:
https://jsfiddle.net/yg13exft/
<style>
/* footer fixed Menu stuff */
.bottomNav{
overflow: hidden;
position: fixed;
bottom: -210px;
width: 100%;
transition: all .7s ease-in-out;
z-index: 9999;
}
.tipBar{
text-align: center;
transition: all .7s ease-in-out;
}
.tipBar a{
color: #6c0505;
background: orange;
display: inline-block;
padding: 5px 15px 5px 15px;
}
.menuBar{
background-color: #6c0505;
display: grid;
grid-template-columns: auto auto;
justify-content: center;
padding-top: 10px;
height: 100%;
}
.bottomNav p{
color: black;
}
.displayNone{
display: none;
}
.tipToggleAnim{
bottom: 46px;
}
.bottomMenuAnim{
bottom: 0;
}
.rightCol img{
max-height: 200px;
}
</style>
<div class="bottomNav" id="bottomNav">
<div class="tipBar" id="tipBar">
<a id="bookNowButton" class="animate__animated animate__backInUp">
Book Now!
</a>
</div>
<div id="dialog" class="menuBar" >
<div class="leftCol">
<p>
TEST TEXT HERE! :)
</p>
</div>
<div class="rightCol">
<img src="https://images.unsplash.com/photo-1589883661923-6476cb0ae9f2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1374&q=80" alt="cat">
</div>
</div>
</div>
<script>
let toggledVar = false;
function popupMenu(){
let menuToggle = document.getElementById("bottomNav");
let divButton = document.getElementById("tipBar");
if (toggledVar == true){
toggledVar = !toggledVar;
menuToggle.classList.remove('bottomMenuAnim');
}
else {
toggledVar = !toggledVar;
menuToggle.classList.add('bottomMenuAnim');
}
}
let buttonTest = document.getElementById("bookNowButton");
buttonTest.addEventListener("click", popupMenu, false);
</script>
Thank you.
I would use clientHeight to get the height of the dialog section and then set that as the bottom attribute so it will always be hidden. That way no matter what the height of the content, it will always know how many pixels to set bottom to and hide the div, but keep the Book Now showing.
There is a window load event because we need the DOM to fully load before we retrieve dialog div height.
Then, we use animate to smooth the change of the bottom attribute. Animate takes two parameters, the keyframes and the options. In the options, fill makes the animation run and stay in its end state. You can adjust the duration to fit your liking.
// We wait for the page to fully load, then we can grab the height of the div
window.addEventListener('load', function() {
// Toggle boolean
let toggledVar = false;
// Set toggle to Book now button
let menuToggle = document.getElementById("bookNowButton");
// Get bottomNav section
let bottomNav = document.getElementById("bottomNav");
// Get the height of the div
let hiddenSection = document.getElementById("dialog").clientHeight;
// Set bottom css attribute
bottomNav.style.bottom = `-${hiddenSection}px`;
function popupMenu(){
if (toggledVar == false) {
// Set bottom css attribute to 0px to reveal it
bottomNav.animate([
// keyframes
{ bottom: `-${hiddenSection}px` },
{ bottom: '0px' }
], {
duration: 1000,
fill: 'forwards'
});
toggledVar = true;
} else {
// Set bottom css attribute to hide it
bottomNav.animate([
// keyframes
{ bottom: '0px' },
{ bottom: `-${hiddenSection}px` }
], {
duration: 1000,
fill: 'forwards'
});
toggledVar = false;
}
}
menuToggle.addEventListener('click', popupMenu);
});
* {
box-sizing: border-box;
}
html, body {
padding: 0;
margin: 0;
width: 100%;
min-height: 100vh;
}
#bottomNav {
max-width: 100%;
position: fixed;
overflow: hidden;
left: 0px;
}
#bookNowButton {
display: block;
margin: 0 auto;
text-align: center;
padding: 1rem;
max-width: 200px;
background-color: yellow;
cursor: pointer;
}
#dialog {
background-color: #6c0505;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 1rem;
padding: 1rem;
}
.rightCol img {
max-width: 100%;
}
<div id="bottomNav">
<span id="bookNowButton">Book Now!</span>
<div id="dialog">
<div class="leftCol">
<p>
TEST TEXT HERE! :)
</p>
</div>
<div class="rightCol">
<img src="https://images.unsplash.com/photo-1589883661923-6476cb0ae9f2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1374&q=80" alt="cat">
</div>
</div>
</div>
I am creating my first html css website and would like to add a 'fill up' dot navigation style vertically on my page so my visitors know what page they are on.
Look at the website I have linked for clarification.
https://tympanus.net/Development/DotNavigationStyles/
I assume I should use js but I don't know how to actually code it into my website.
Here is my code for my website.
HTML:
<div class="container">
<nav class="navbar">
<ul>
<li>Home</li>
<li>About</li>
<li>Services</li>
<li>Contact</li>
</ul>
</nav>
<section id="home">
<img id="derrick-ogole-logo" src="images/derrick-ogole-logo.png" alt="Derrick Ogole Official Logo">
</section>
An example of my sections to indicate layout and page change.
CSS:
.container{
widows:100%;
height:100%;
/* CSS Smooth Scroll */
overflow-y:scroll;
scroll-behavior:smooth;
scroll-snap-type:y mandatory;
}
.navbar{
position:fixed;
top:0;
z-index:1;
display:flex;
width:100%;
height:60px;
background:rgba(0,0,0,0.7);
}
.navbar ul{
display:flex;
list-style:none;
width:100%;
justify-content:center;
}
.navbar ul li{
margin:0 1rem;
padding:1rem;
}
What JS code do I add and how do I link it to HTML and CSS?
If I click the second dot, it fills up, goes to that page and then unfills but the first dot stays red (active) so their isn't a transition.
In my html for the dot:
<script src="dot-nav.js"></script>
In my js file
// listen for clicks on the navbar
document.querySelector('.navbar').addEventListener('click', (e) => {
// ignore it if the click isn't on an anchor element
if (e.target.tagName.toLowerCase() === 'a') {
// remove the 'active' class from all of the nav anchors
document.querySelectorAll('.navbar a')
.forEach(e => e.classList.remove('active'));
// add the 'active' class to the clicked element
e.target.classList.add('active');
}
});
CSS for the dot:
/* position the navbar center right */
.navbar{
position:fixed;
right:32px;
top:50%;
transform: translateY(-50%);
}
/* style the individual nav items */
.navbar a {
/* make them little circles */
display: block;
border-radius: 50%;
border: 1px solid white;
width: 20px;
height: 20px;
/* with some space between them */
margin: 20px 0;
/* hide the text content */
text-indent: -999px;
overflow: hidden;
/* establish positioning conext for the ::after pseudo-elements (below)*/
position: relative;
}
/* the "fill" */
.navbar a::after {
/* won't render without a 'content' rule */
content:"";
/* red fill */
background-color: #ff0000;
/* zero height until it's active */
position: absolute;
bottom: 0;
height: 0;
left: 0;
right: 0;
width: 100%;
/* animate the height when it changes */
transition: height 0.3s ease;
}
/* active and hovered elements */
.navbar a:hover::after,
.navbar a.active::after {
/* change the height to 100%.
the transition rule above will cause this to animate */
height: 100%;
}
Here's a basic implementation of what i think you're asking for.
The javascript is only there to add/remove the active css class. Everything is really happening in the CSS. I've added comments in the code to explain how it works, but feel free to hit me up if you have questions.
// listen for clicks on the navbar
document.querySelector('.navbar').addEventListener('click', (e) => {
// ignore it if the click isn't on an anchor element
if (e.target.tagName.toLowerCase() === 'a') {
// remove the 'active' class from all of the nav anchors
document.querySelectorAll('.navbar a')
.forEach(e => e.classList.remove('active'));
// add the 'active' class to the clicked element
e.target.classList.add('active');
}
});
html, body {
font-family: sans-serif;
letter-spacing: 2px;
margin: 0;
padding: 0;
}
ul {
list-style: none;
padding: 0;
margin: 0;
}
/* position the navbar center right */
.navbar {
position: fixed;
right: 32px;
top: 50%;
transform: translateY(-50%);
}
/* style the individual nav items */
.navbar a {
/* make them little circles */
display: block;
border-radius: 50%;
border: 1px solid white;
width: 20px;
height: 20px;
/* with some space between them */
margin: 20px 0;
/* hide the text content */
text-indent: -999px;
overflow: hidden;
/* establish positioning conext for the ::after pseudo-elements (below)*/
position: relative;
}
/* the "fill" */
.navbar a::after {
/* won't render without a 'content' rule */
content: '';
/* white fill */
background-color: #fff;
/* zero height until it's active */
position: absolute;
bottom: 0;
height: 0;
left: 0;
right: 0;
width: 100%;
/* animate the height when it changes */
transition: height 0.3s ease;
}
/* active and hovered elements */
.navbar a:hover::after,
.navbar a.active::after {
/* change the height to 100%.
the transition rule above will cause this to animate */
height: 100%;
}
/* make the sections occupy the full screen height */
section {
height: 100vh;
background: tomato;
color: bisque;
display: grid;
place-items: center;
}
<div class="container">
<nav class="navbar">
<ul>
<li><a class="active" href="#home">Home</a></li>
<li>About</li>
<li>Services</li>
<li>Contact</li>
</ul>
</nav>
<section id="home">home</section>
<section id="about">about</section>
<section id="services">service</section>
<section id="contact">contact</section>
</div>
I built a navbar in HTML and also some Divs which are populated with a bunch of content that pertains to each nav element.
What I want to do is show the div which pertains to the selected nav element when it is clicked and hide the other divs that pertain to the other nav elements.
Basically what needs to happen is when a user clicks on a Nav Item, the class for that nav item needs to be set to 'navItem active on' in the html. Not sure if this is something that happens automatically or not.
After that, the display property defined in the CSS for the content panel of that nav item needs to be changed to 'block' and all other content panels should then have their 'display' property changed to 'none' so that they are not displayed in the page.
In the example given, I only have two content panels defined in the CSS and HTML (Capabilities and Tutorials), but each navItem will receive it's own content panel which should be toggled on when it is clicked.
I really have no idea where to begin with this. I'm pretty sure this requires JavaScript but this is literally my first attempt at building a web page and it took me 2 days even after copying a lot from another website I used for inspiration. Any help, guidance or insight is greatly appreciated.
CSS + HTML:
var links = document.getElementsByClassName("navItem");
for (i = 0; i < links.length; i++) {
var link = links[i];
link.addEventListener('click',function(sender, event) {
event.preventDefault();
/* hide all panels */
var panels = document.getElementsByClassName("panel");
for (j = 0; j < panels.length; j++) {
panels[j].style.display = 'none';
}
/* Show the selected panel */
var panel_id = sender.target.getAttribute("panel-id");
document.getElementById(panel_id).style.display = 'block';
}
}
/* FONT ASSIGNMENTS
--------------------------- */
/* General Use */
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
p,
small {
font-family: 'Avenir LT W01 35 Light', Arial, Helvetica, sans-serif;
}
p.large-text {
font-size: 18px !important;
}
hr {
background-color: #e0e0e0;
color: #e0e0e0;
}
.center-content {
text-align: center !important;
}
/* Special Use */
h1,
h2,
h1 a,
h2 a,
h3,
h3 a,
infoBar,
.gisFont1,
.gisFont1 a {
font-weight: normal !important;
font-style: normal;
line-height: normal;
font-variant: normal;
font-family: 'Avenir LT W01 35 Light', Arial, Helvetica, sans-serif;
}
/*-- END FONT ASSIGNMENTS --*/
/* INFOBAR - The Infobar is the navigation element at the top
used to navigate the subpages of the document and change the content
panel's content depending on the selected infoBar navigation element
--------------------------- */
/* infoBar Bottom Border */
#infoBar {
background: #FFF;
/*border-top: 1px solid #e5e5e5;*/
border-bottom: 1px solid #e5e5e5;
max-width: 940px;
text-align: center;
/*display: table;*/
margin: 0 auto;
}
/* infoBar Bottom Border onHover or Active element*/
#infoBar a:hover,
#infoBar a.active {
border-bottom: 4px solid #2889DE;
text-decoration: none;
}
/* infoBar Link Text */
#infoBar a {
background: transparent;
color: #000;
display: inline-block;
font-size: 16px;
font-family: 'Avenir LT W01 35 Light', Arial, Helvetica, sans-serif;
padding: 1.4em;
text-decoration: none;
}
/* infoBar Link Text onHover */
#infoBar a:Hover {
background: transparent;
color: #2889DE;
display: inline-block;
font-size: 16px;
font-family: 'Avenir LT W01 35 Light', Arial, Helvetica, sans-serif;
padding: 1.4em;
text-decoration: none;
}
/* infoBar Active element */
#infoBar a.active {
font-family: 'Avenir LT W01 65 Medium', Arial, Helvetica, sans-serif;
}
/* Media Queries */
#media screen and (max-width: 960px) {
#infoBar a {
font-size: 14px;
}
}
#media screen and (max-width: 830px) {
#infoBar a {
padding: 1em 0.6em;
}
}
#media screen and (max-width: 760px) {
#infoBar {
display: none;
}
}
/*-- END INFOBAR --*/
/* PAGE SECTIONS
--------------------------- */
/* Page Section Styling */
.page-section {
background-position: center top;
color: #4d4d4d;
min-height: 200px;
padding: 60px 0;
text-align: center;
width: 940px;
margin: auto;
}
/* Page Section - Header2 Styling */
.page-section h2 {
font-size: 24px;
margin-bottom: 20px;
}
/* Page Section Paragraph Styling */
.page-section p {
color: #333;
font-size: 18px;
line-height: 1.5;
/*margin: 10px 0 45px 0;*/
}
/* Foreword-Section-Top Styling */
.foreword-section-top {
padding: 0;
min-height: 160px;
}
/* Foreword-Section-Top Header1 Styling*/
.foreword-section-top h1 {
color: #222;
font-size: 36px;
}
/* Foreword-Section-Top Paragraph Styling */
.foreword-section-top p {
color: #4d4d4d;
margin-bottom: 10px;
}
.grid-100 {
width: 100%;
margin: auto;
}
/* CONTENT PANELS
----------------------------- */
/* Capabilties Panel*/
#capabilities-panel {
max-width: 980px;
margin: 0 auto;
display:block;
}
/*Tutorials Panel */
#tutorials-panel {
max-width: 980px;
margin: 0 auto;
display:none;
}
.product-row {
margin-bottom: 50px;
/*width: 100%; */
max-width: 940px;
margin: 0 auto;
display: inline-block;
}
.product-box {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
float: left;
overflow: hidden;
margin: 0.5%;
position: relative;
text-align: center;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
width: 24%;
}
#media screen and (max-width: 960px) {
.product-box {
width: 48%;
}
}
#media screen and (max-width: 480px) {
.product-box {
display: block;
float: none;
margin: 10px auto;
width: 95%;
}
}
.product-box a {
color: #FFF;
display: block;
font-weight: bold;
}
.product-box a:hover .inner-box-padding {
position: relative;
width: 100%;
-ms-transform: scale(1.1);
-moz-transform: scale(1.1);
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
.product-box .inner-box-padding {
background-color: #007ac2;
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
-ms-transition: all .2s ease-in-out;
-moz-transition: all .2s ease-in-out;
-webkit-transition: all .2s ease-in-out;
transition: all .2s ease-in-out;
width: 100%;
}
.product-box .inner-box-padding:before {
content: "";
display: block;
padding-top: 87%;
}
.product-box h3 {
font-size: 22px;
color: #FFF;
position: absolute;
left: 0;
right: 0;
bottom: 0;
}
.product-box.dark-text h3 {
color: #333;
}
.product-box .capability-one {
background-image: url('http://i64.tinypic.com/2mi16l1.png');
}
.product-box .capability-two {
background-image: url('http://i68.tinypic.com/10gwm75.png');
}
.product-box .capability-three {
background-image: url('http://i65.tinypic.com/5djxwh.png');
}
.product-box .capability-four {
background-image: url('http://i67.tinypic.com/15e7hu8.png');
}
.product-box .tutorial-one {
background-image: url('http://i68.tinypic.com/efhvfc.png');
}
.product-box .tutorial-two {
background-image: url('http://i66.tinypic.com/50199u.png');
}
.product-box .tutorial-three {
background-image: url('http://i63.tinypic.com/wvwcif.png');
}
.product-box .tutorial-four {
background-image: url('http://i67.tinypic.com/1zp1or8.png');
}
/* END PRODUCT BOXES */
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<!-- include jQuery -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<!-- INFO BAR -->
<div id="infoBar">
Capabilities
Tutorials
Use Cases
Services
Security
What's New
Request Access
</div>
<!-- END GIS INFO BAR -->
<!-- FOREWORD -->
<div class="page-section foreword-section-top">
<h1>Some Cool Tagline</h1>
<p>blah blah blah. We're so awesome. Now give us money.</p>
</div>
<!-- CAPABILITIES PANEL -->
<div id="capabilities-panel" class="panel">
<!-- Capability One -->
<div class="product-box">
<a href="/capabilities/capability-one">
<div class="inner-box-padding capability-one"></div>
<h3>Capability 1</h3>
</a>
</div>
<!-- Capability Two box -->
<div class="product-box dark-text">
<a href="/capabilities/capability-two">
<div class="inner-box-padding capability-two"></div>
<h3>Capability 2</h3>
</a>
</div>
<!-- Capability Three box -->
<div class="product-box">
<a href="/capabilities/capability-three">
<div class="inner-box-padding capability-three"></div>
<h3>Capability 3</h3>
</a>
</div>
<!-- Capability Four box -->
<div class="product-box">
<a href="/capabilities/capability-four">
<div class="inner-box-padding capability-four"></div>
<h3>Capability 4</h3>
</a>
</div>
</div>
<!-- END CAPABILITIES PANEL -->
<!-- TUTORIALS PANEL -->
<div id="tutorials-panel" class="panel">
<!-- Tutorial One box -->
<div class="product-box">
<a href="/tutorials/tutorial-one">
<div class="inner-box-padding tutorial-one"></div>
<h3>Tutorial 1</h3>
</a>
</div>
<!-- Tutorial Two box -->
<div class="product-box dark-text">
<a href="/tutorials/tutorial-two">
<div class="inner-box-padding tutorial-two"></div>
<h3>Tutorial 2</h3>
</a>
</div>
<!-- Tutorial Three box -->
<div class="product-box">
<a href="/tutorials/tutorial-three">
<div class="inner-box-padding tutorial-three"></div>
<h3>Tutorial 3</h3>
</a>
</div>
<!-- Tutorial Four box -->
<div class="product-box">
<a href="/tutorials/tutorial-four">
<div class="inner-box-padding tutorial-four"></div>
<h3>Tutorial 3</h3>
</a>
</div>
</div>
<!-- END TUTORIALS PANEL -->
Pretty sure that this might do something like you'd want.
There are more elegant pieces of code (not to mention that there should be loads of plugins) for this though, this is just out of the top of my head (dont use $.attr to find the corresponding panel etc).
$(document).ready(function(){
$(".navItem").click(function(event) {
event.preventDefault();
$('.navItem').removeClass("active").removeClass("on");
$(this).addClass("active").addClass("on");
var panel = $(this).attr('panel-id');
$(".panel").hide();
$("#"+panel).show();
});
});
In order to use this script you need to import jQuery into your page though, which literally putting 1 line in your page (just google that).
You need to give every panel the class panel (i.e. instead of just the 'id' attribute. This will allow for the $(".panel") to find all html that is in a
The var panel = $(this).attr('panel-id'); line finds the panel belonging to the anchor the user clicked, as long as you add an attribute to each anchor containing the id of the corresponding panel as the value (e.g. <a (..) panel-id="capabilities-panel">)
=======
Updated answer so OP can use vanilla javascript per his request.
(function () {
alert('hello');
var links = document.getElementsByClassName("navItem");
for (i = 0; i < links.length; i++) {
var link = links[i];
link.addEventListener('click',function(event) {
event.preventDefault();
for(int k = 0; k < links; k++) {
links[k].className = "navItem";
}
event.target.className += " active on";
var panels = document.getElementsByClassName("panel");
for (j = 0; j < panels.length; j++) {
panels[j].style.display = 'none';
}
var panel_id = event.target.getAttribute("panel-id");
document.getElementById(panel_id).style.display = 'block';
});
}
})();
I haven't tested this so there's probably some syntactic errors here and there, and Im not too sure how one gets the sender element from a click event in vanilla javascript (though this shouldn't be too hard to google).
You need to put scripts in between <script></script> tags in order for your browser to recognize javascript.
Note how the number of lines and readability decreased by abandoning jQuery.
Hope this helps you!
Also, if this is just not working for you I recommend checking out the link the other guy posted under your question.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
How do i add a transition effect on this expanding list?
<div class="container">
<div class="outerBG">
<div class="innerBG">
<h2 class="info">➤ Show text</h2>
<ul id="infoContent" style="display:none">
<li>TEST 1 TEST 1 TEST 1 TEST 1</li>
<li>TEST 2 TEST 2 TEST 2 TEST 2</li>
</ul>
</div>
</div>
</div>
I'm using JavaScript to toggle the UL's display:
function expand () {
infoContent.style.display = infoContent.style.display === 'none' ? '' : 'none';
}
Is it possible to make a transition effect out of this?
jsfiddle: https://jsfiddle.net/mqy2c80u/
You cannot use display: none to animate elements into view.
However, you can update your expand function to the change the class from open to close like so:
JavaScript Change:
function expand () {
infoContent.className = infoContent.className === 'open' ? 'close' : 'open';
}
And then apply the CSS animation using max-height (in case the content inside the animated div is dynamic):
CSS Addition:
#infoContent {
margin: 0; // Remove the margins
overflow: hidden;
}
#infoContent.close {
max-height: 0; // Set max height to zero
transition: max-height 0.3s ease;
}
#infoContent.open {
max-height: 300px; /* Set max height as big as you think it will ever go */
transition: max-height 0.3s ease;
}
Demo: JSFiddle
This can be solved using CSS only, no Javascript required here.
https://jsfiddle.net/mqy2c80u/10/
.container {
height: 300px;
}
.innerBG {
width: 260px;
margin: 0 auto;
}
.outerBG {
width: 260px;
background-color: #4f322a;
margin: 15px auto 25px auto;
border-radius: 15px;
}
.container {
width: 100%;
background-color: #70463a;
}
.info {
color: white;
cursor: pointer;
}
.info h2 {
display: inline-block;
}
.info h2:after {
content:"Show content";
}
#demo {
display: none;
}
#demo:checked ~ #infoContent {
max-height: 400px;
}
#demo:checked + .info h2:after {
content:"Hide content";
}
.innerBG h2 {
font-size: 20px;
font-family: lato;
color: #ffffff;
font-weight: 100;
}
#infoContent {
transition-duration: 0.4s;
max-height: 0;
overflow: hidden;
}
#infoContent li {
font-size: 20px;
font-family: lato;
color: #ffffff;
font-weight: 100;
}
<div class="container">
<div class="outerBG">
<div class="innerBG">
<input type="checkbox" id="demo" />
<label class="info" for="demo">➤
<h2></h2>
</label>
<ul id="infoContent">
<li>TEST 1 TEST 1 TEST 1 TEST 1</li>
<li>TEST 2 TEST 2 TEST 2 TEST 2</li>
</ul>
</div>
</div>
</div>
You want to add a transition to max-height and toggle that and not display. The reason being that display is not an ordinal value so cannot be animated as transitional values cannot be interpolated. max-height is ordinal, so can be transitioned.
With that in mind, it is important to note that the 'show' value for max-height should be enough to accommodate the content, otherwise the transition will elongate. Its also better than animating on height as a known value is not required, the height will only grow to that required.
var infoContent = document.getElementById("infoContent");
var info = document.querySelector(".info");
function expand() { // do this on maxHeight not display
infoContent.style.maxHeight = infoContent.style.maxHeight ? 0 : '100px';
}
info.addEventListener("click", expand, false);
.innerBG {
width: 260px;
margin: 0 auto 0 auto;
overflow: auto;
}
.outerBG {
width: 260px;
background-color: #4f322a;
margin: 15px auto 25px auto;
border-radius: 15px;
overflow: auto;
}
.container {
width: 100%;
background-color: #70463a;
overflow: auto;
}
.innerBG h2 {
font-size: 20px;
font-family: lato;
color: #ffffff;
font-weight: 100;
}
#infoContent li {
font-size: 20px;
font-family: lato;
color: #ffffff;
font-weight: 100;
}
#infoContent {
max-height: 0; /* collapse by default */
overflow: hidden; /* <-- hide content when collapsed */
transition: max-height 200ms; /* <-- animate on change */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="outerBG">
<div class="innerBG">
<h2 class="info">➤ Show text</h2>
<ul id="infoContent">
<li>TEST 1 TEST 1 TEST 1 TEST 1</li>
<li>TEST 2 TEST 2 TEST 2 TEST 2</li>
</ul>
</div>
</div>
</div>
I've got this issue that i can't resolve myself.
I've got css tabs like in this site: http://www.sitepoint.com/css3-tabs-using-target-selector/
but i've got a fixed menu in the top of the page. So, when i click in one tab, the html navigate to the anchor that is under this menu and the content jump to top.
I want to scroll the content on top of the page, I've searched a lot, tried `$('body').scrollTop(0); what they said in this answer: Scroll to the top of the page using JavaScript/jQuery?
but nothing work. This is my code, HTML:
<body class="centered">
<div id="main-container">
<!-- header -->
<div class="col_1_of_1 blue header">
<div class="col_1_of_5 menu-icon">
<img src="img/menu.png">
</div>
<div class="col_3_of_5">
<p class="main_title" id="headerTitle"></p>
</div>
<div class="col_1_of_5 img-icon">
<img src="*">
</div>
</div>
<!-- body -->
<div class="body" id="list">
<article class='tabs'>
<section id='tab1'>
<h2><a href='#tab1' id='sayit'>Person1</a></h2>
<div class='col_1_of_1'>
<img src='img/bike/img.png'>
</div>
<div class='col_1_of_1'>
<p class='fausto_title'>dscdsvdvds</p>
<p class='fausto_text'>vdlisvd shvgldk sgvds gvgsd kjbvds ds uidshiu diui guig uig uig g g gl ffyolg f f h hj lhfh ff yfyufolyf uhyf <p>
</div>
</section>
<section id='tab2'>
<h2><a href='#tab2'>John</a></h2>
<div class='col_1_of_1'>
<img src='img/moto/img2.png'>
</div>
<div class='col_1_of_1'>
<p class='fausto_title'>dcdsdvdvds </p>
<p class='fausto_text'>dsvdvdhvihiu ugig piogv hgho ghvh vhvhv hvo vohv hovhjvhjvhvh vhvvhv vhvh vhvhv hv hjvp8ythtuy ty tygt gtg68g 6g 6g 6g tg tr gytrg <p>
</div>
</section>
</article>
</div> <!-- end body -->
</div>
CSS:
tabs.css
/* --- container's width --- */
article.tabs
{
position: relative;
display: block;
width: 100%;
}
article.tabs section
{
position: absolute;
top: 1.8em;
left: 0;
height: 12em;
background-color: #ddd;
z-index: 0;
width: 100%;
}
article.tabs section .table {
display: none;
}
article.tabs section:first-child
{
z-index: 1;
}
article.tabs section h2
{
position: absolute;
font-size: 1em;
font-weight: normal;
width: 33%;
height: 1.8em;
top: -1.8em;
padding: 0;
margin: 0;
color: #999;
background-color: #ddd;
border-top: 1px solid #ddd;
}
article.tabs section:nth-child(2) h2
{
left: 33%;
}
article.tabs section:nth-child(3) h2
{
left: 66%;
}
article.tabs section h2 a
{
display: block;
width: 100%;
line-height: 1.8em;
text-align: center;
text-decoration: none;
color: inherit;
outline: 0 none;
}
/* --- active section --- */
article.tabs section:target,
article.tabs section:target h2
{
background-color: #fff;
z-index: 2;
}
article.tabs section:target {
width: 100%;
position: absolute;
top: 1.8em;
left: 0;
height: 12em;
}
article.tabs section:target h2 {
width: 33%;
border-right: 1px solid rgb(27,47,105);
border-left: 1px solid rgb(27,47,105);
border-top: 1px solid rgb(27,47,105);
color: rgb(27,47,105);
}
article.tabs section:target .table{
display: block;
}
/* --- transition effect --- */
article.tabs section,
article.tabs section h2
{
-webkit-transition: all 500ms ease;
-moz-transition: all 500ms ease;
-ms-transition: all 500ms ease;
-o-transition: all 500ms ease;
transition: all 500ms ease;
}
menu.css:
.menu-icon {
padding-top: 9% !important;
}
.menu-icon img {
width: 40%;
}
.header {
position: fixed;
height: 64px;
top: 0;
z-index: 1000;
}
.header div {
float: left;
padding-top: 8%;
}
Thanks in advice for any help!
EDIT:
This is a phonegap application and i'm compling in iOS just now. It seems like the command scrollTop isn't recognize.
I'm using zepto.js, a jQuery like library but much faster.
EDIT 2:
Zepto.js / jQuery:
function clickButton()
{
document.getElementById('sayit').click();
return true;
}
$(function() {
//..other code (nothing to do with tabs)
//simulate the first click on a tab
clickButton();
$('a').on('click', function(event){
var anchor = $(this);
alert($(anchor.attr('href')).offset().top);
$('html, body').stop().animate({
scrollTop: $(anchor.attr('href')).offset().top
}, 100);
event.preventDefault();
});
});
Add the class .tab to your tab links.
<h2><a href='#tab1' id='sayit' class='tab'>Person1</a></h2>
Include jQuery in the <head> of your page:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Bind a click event to tabs that scrolls the page to the top:
$('.tab').click(function(event) {
event.preventDefault(); //Prevent the link from jumping.
$('html,body').animate({scrollTop:0}, 400); //Scroll to top
});
Try this :
JS :
//To scroll top of the Tab
$(function() {
$('a').bind('click',function(event){
var $anchor = $(this);
$('html, body').stop().animate({
scrollTop: $($anchor.attr('href')).offset().top
}, 1000);
event.preventDefault();
});
});
HTML :
<div class="col_1_of_5 img-icon">
<img src="*" alt="TOP"/>
</div>
Also, I added Anchor tag over the image which shows the Top arrow.
DEMO HERE
Kindly reply if your are able to figure it out.