nested accordion menu in CSS html - html

Based on this thread, I tried to build myself a css/html only accordion menu. When I took what I learned from the above, and applied it to my divs, it worked perfectly. I also needed to add a submenu that acted the same to the first menu item, portfolio. I attempted it with no success. It was explained to me that the reason was that I was using the same target.
(To begin, I am novice when it comes to a lot of these things so while some questions I have might seem fundamental it is because I am learning as I go.)
Based on the feedback, I attempted to make a new version creating 2 accordion classes. While that did not break the functionality I wanted, it still had the problem of opening both of the submenus. When you click PORTFOLIO, BRANDING should appear. When you click BRANDING, CONTENT should appear. Instead when you click PORTFOLIO, BRANDING and CONTENT appear.
It was indicated that this is because the first accordion function includes all child objects. While I've touched on those briefly in the js I'm learning I didn't know how to work with them in css other than the :not(x) I've come across but that did not seem to resolve it in any attempt though I could be doing it wrong.
jsfiddle
Here is the css to the above jsfiddle link:
a {
color:inherit;
text-decoration:none;
font-style:normal;
}
/* ---------- SECTION ---------- */
.accordion p + div :not(.accordion2) {
height: 0;
overflow: hidden;
-webkit-transition: height 0.3s ease-in;
-moz-transition: height 0.3s ease-in;
-o-transition: height 0.3s ease-in;
-ms-transition: height 0.3s ease-in;
transition: height 0.3s ease-in;
}
.accordion :target p + div :not(.accordion2) {
height:auto;
}
.accordion .section.large:target p + div :not(.accordion2) {
overflow: auto;
}
.section p {
color:#FFFfff;
text-align:right;
min-width:200px;
background-color:#2d2d2d;
font-size:12px;
font-size-adjust:inherit;
padding:0px;
margin:0px;
border-top:#161616 1px solid;
text-decoration:none;
text-transform:uppercase;
text-decoration:none;
color:#ffffff;
}
.section p a {
display:block;
text-align:right;
padding-right:10px;
padding-left:10px;
padding-top:3px;
padding-bottom:3px;
min-width:180px;
}
.section p a:hover {
background-color:#c569f2;
}
/* ---------- SubSection ---------- */
.accordion2 p + div {
height: 0;
overflow: hidden;
-webkit-transition: height 0.3s ease-in;
-moz-transition: height 0.3s ease-in;
-o-transition: height 0.3s ease-in;
-ms-transition: height 0.3s ease-in;
transition: height 0.3s ease-in;
}
.accordion2 :target p + div {
height:auto;
}
.accordion2 .subsection.large:target p + div {
overflow: auto;
}
.subsection p {
color:#FFFfff;
text-align:right;
min-width:200px;
background-color:#3d3d3d;
font-size:12px;
font-size-adjust:inherit;
padding:0px;
margin:0px;
border-top:#161616 1px solid;
text-decoration:none;
text-transform:uppercase;
text-decoration:none;
color:#ffffff;
}
.subsection p a {
display:block;
text-align:right;
padding-right:10px;
padding-left:10px;
padding-top:3px;
padding-bottom:3px;
min-width:180px;
}
.subsection p a:hover {
background-color:#c39bda;
}
/* ---------- Sidebar ---------- */
#sidebar {
float: right;
right: 0px;
background-color:#161616;
position:fixed;
width:20%;
min-height: 100%;
min-width: 200px;
top:0px;
}
#side-menu {
right: 0px;
top:0px;
position:absolute;
height:75%;
width:100%;
min-width: 200px;
bottom:0px;
margin-bottom:0px;
min-height:600px;
}
Here is the html:
<div id="sidebar">
<div id="side-menu" class="accordion">
<div id="menu-portfolio" class="section">
<p> Portfolio
</p>
<div class="accordion2">
<div id="submenu-branding" class="subsection">
<p> Branding
</p>
<div>
<p> Content
</p>
</div>
</div>
</div>
</div>
<div id="menu-about" class="section">
<p> About
</p>
<div>
<p>Resume
</p>
</div>
</div>
<div id="menu-contact" class="section">
<p> Contact
</p>
<div>
<p>Content
</p>
<p>Content2
</p>
<p>Content3
</p>
</div>
</div>
</div>
</div>
Can anyone assist me in understanding what I am doing wrong?

It doesn't matter if you use divs or lists (though most tutorials will use lists). Its mostly referencing the right item. Looking briefly at the code, you are not specifying to not show the sub sub menu.
I've added a new class to your first content and what the target does in css - showing only the div right after:
HTML:
<div class="subsub"> <!--added a new class. I have never used :not, but it seems that it does't allow nesting inside :not selectors -->
<p>Content</p>
</div>
CSS:
.accordion :target p + div :not(.subsub) {
height:auto;
}
You have to reiterate what you have done to show the sub menu when clicking on portfolio onto the sub sub menu when clicking on branding.
A quick fiddle: http://jsfiddle.net/jennift/m4ADf/2/

I haven't looked into your code, but like you've said "it includes all child objects". You can prevent this by using the direct descendant selector ">". It will only get the direct child elements, e.g.
ul > li {
}
will only style the li element and no other li elements inside it.

Related

Fix elements so only the one hovered over extends?

I currently have a top menu consisting of four div's: Home, Menu, Order, and Review. I have set it so that each div extends 100px when hovered over. Everything worked fine at this point. I then added some words and an image within each of the div's extended area. Now whenever I hover over any of the div's, it extends, but it carry's the rest of the div's with it. I want it so that only the div I am hovering over will extend and the rest will remain where they were. Here's the html:
<div class="TopNav">
<a href="file:///C:/Users/Justin/SkyDrive/Documents/Websites/Snack%20Shack%202/SS2.html"><div class="Home">
<h4>Home</h4> <br><br>
<p>Learn about us!</p>
<img class="Hamburger" src="http://i.imgur.com/0htcpM2.png" title="source: imgur.com" />
</div></a>
<a href="file:///C:/Users/Justin/SkyDrive/Documents/Websites/Snack%20Shack%202/SS2%20Menu.html"><div class="Menu">
<h4>Menu</h4>
</div></a>
<a href="file:///C:/Users/Justin/SkyDrive/Documents/Websites/Snack%20Shack%202/SS2%20Order.html"><div class="Order">
<h4>Order</h4>
</div></a>
<a href="file:///C:/Users/Justin/SkyDrive/Documents/Websites/Snack%20Shack%202/SS2%20Review.html"><div class="Review">
<h4>Review</h4>
</div></a>
</div>
Here's the css:
.Home:hover, .Menu:hover, .Order:hover, .Review:hover{
height: 150px;
}
.Home, .Menu, .Order, .Review {
height:50px;
width:100px;
display:inline-block;
position:relative;
z-index:1;
transition: height .5s ease-in-out;
-webkit-transition: height .5s ease-in-out;
overflow:hidden;
}
.Home p, .Menu p, .Order p, .Review p {
text-align:right;
color:white;
position:relative;
right:2px;
bottom:5px;
}
.Home h4, .Menu h4, .Order h4, .Review h4 {
text-align:center;
color:white;
position:relative;
bottom:5px;
font-family:Garamond;
}
.Hamburger {
height:40px;
width:auto;
position:relative;
left:50px;
top:10px;
display:inline-block;
}
Does anyone know how to fix this?
add vertical-align: top; to .Home, .Menu, .Order, .Review
inline-block element aligns to the bottom of the highest element by taking vertical-align: baseline; as default but you can align it to the top by adding vertical-align:top
demo - http://jsfiddle.net/hsj2ebc2/1/

how to make input width larger and above the plant when focusing it?

I want the style of the input element at the top-left of github.com. When I click the input Search or type a command, the width of the input becomes larger and it will becomes above these elements back.
After doing some searches, I do not find the approach to it. This is what I have tried: jsfiddle
Thanks for any help.
If you want to add a similar animation, you need to add a transition:
#input-text {
position: relative;
width: 200px;
transition: width 100ms ease-in;
}
If you want the menu overlaying effect, you can use the below as a strating point:
Demo Fiddle
HTML
<div>
<input type='text' />
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
</ul>
</div>
CSS
div {
position:relative;
}
input {
position:absolute;
width:300px;
z-index:1;
transition:200ms width ease-in;
}
input:focus {
width:500px;
}
input:focus + ul{
opacity:0;
}
ul {
list-style:none;
position:absolute;
left:320px;
z-index:0;
opacity:1;
transition:200ms opacity ease-out;
}
ul, li {
margin:0;
padding:0;
}
ul, li {
display:inline-block;
vertical-align:middle;
}
I tried to do this a while ago - specifically the github search bar.
There are loads of articles already out there on how to do this. I would start with them?
http://java.dzone.com/articles/recreate-github-search-box
http://www.paulund.co.uk/create-a-slide-out-search-box
What you want are CSS transitions: http://css-tricks.com/almanac/properties/t/transition/
#input-text {
position: relative;
width: 200px;
transition: width 0.5s;
}
http://jsfiddle.net/Qxa5N/5/

Use table-cell to fill rest of div

I'm trying to make a table where the final column of the table fills the rest of the table.
I'm using divs to design the table and using the borders of the div to make the borders between each element, but if you look at my link http://subjectplanner.co.uk/Me/test.php, you can see that the last elements don't fill the end of the table resulting in the border falling short.
CSS
.Larger{
font-size: 125%;
}
.Smaller{
font-size: 85%;
}
.Block{
display: block;
}
.TodayList{
font-family:'Proxima Nova',Helvetica,Arial,sans-serif;
display:table;
width:100%;
margin:0 0 1em 0;
-webkit-border-radius:15px;
border-radius:15px;
overflow:hidden;
border:0 none;
border-collapse:collapse;
background-color:#247B2B;
font-size:1.5em;
position:relative;
padding:0;
}
.TodayItem{
position:relative;
display:table-row;
border-collapse:collapse;
overflow:hidden;
color:#70BB75;
-webkit-transition:background-color 0.2s linear;
-moz-transition:background-color 0.2s linear;
-o-transition:background-color 0.2s linear;
-ms-transition:background-color 0.2s linear;
transition:background-color 0.2s linear;
background-color:rgba(0,0,0,0.001);
}
.TodayItem:hover{
background-color:#95FA9D;
}
.TodayItem a{
color:#fff;
}
.TodayItem .smaller,.TodayItem .TodayInfo{
color:#fff;
}
.TodayItemWrapper{
display:block;
position:relative;
overflow:hidden;
height:100%;
width:100%;
}
.TodayIcon,.TodayTitle,.TodayInfo{
display:table-cell;
border-collapse:collapse;
border:1px solid #31AE33;
border-width:0 1px 1px 0;
padding:2em;
margin:0;
font-size:100%;
min-height:120px;
font-weight:normal;
}
.TodayItem:last-of-type .TodayIcon,.TodayItem:last-of-type .TodayTitle,.TodayItem:last-of-type .TodayInfo{
border-bottom-width:0;
}
.TodayIcon{
width:130px;
vertical-align:middle;
text-align:center;
}
.TodayTitle{
width:260px;
}
.TodayInfo{
border-right-width:0;
}
.TodayTitle a{
text-decoration:none;
}
.TodayTitle a:hover{
text-decoration:underline;
}
.TodayLink{
position:absolute;
left:0;
top:0;
width:100%;
height:100%;
background-color:rgba(0,0,0,0.001);
vertical-align:top;
z-index:2;
}
HTML
<ul class="TodayList">
<li class="TodayItem">
<div class="TodayItemWrapper">
<span class="TodayIcon"></span>
<h3 class="TodayTitle">
Monday<span class="TodayLink"></span> <span class="Block Smaller">You've 3 lessons today</span>
</h3>
<div class="TodayInfo">
<ul>
<li>9 - 10: Maths</li>
<li>10 - 11: English</li>
<li>12 - 13: ICT</li>
</ul>
</div>
</div>
</li>
<li class="TodayItem">
<div class="TodayItemWrapper">
<span class="TodayIcon"></span>
<h3 class="TodayTitle">
Tuesday<span class="TodayLink"></span> <span class="Block Smaller">You've 2 lessons on this day</span>
</h3>
<div class="TodayInfo">
<ul>
<li>10 - 11: Art</li>
<li>11 - 13: Double Business</li>
</ul>
</div>
</div>
</li>
</ul>
Here's a fiddle if you want it http://jsfiddle.net/tR7WX/
Simply add this rule to your style:
ul.TodayList>li:last-child {
width:100%;
}
Btw, you're not obliged to have a class for every level of tag. You can user CSS node rules to select specific tag and apply style. Should you go for it, you get a simpler (and lighter) HTML file.
Is there a specific reason why you're not using a table for this? I know tables are often seen as old school, but you've got table data here and scenario that requires table logic. I think to use DIVs and CSS to replicate tables would be complex and difficult to change/maintain and make it quite fragile.
Another possible solution would be to not use table-cell at all and instead use DIVs with percentage widths, so they always fill the total width. You could then have a container inside each DIV with display:table to vertically centre the content.
Sorry if I've misunderstood anything.

asp.net invoke "target" pseudo css class

I have an html accordion that is essentially a bunch of tags with some css
A section then gets styled as being active through the :target pseudo class.
problem being, any server controls that cause a postback, then we loose the the selected section.
I was thinking to try add something so make my run on the server, and inject a class name, but I am not sure how to tell it to be active.
I have also tried setting the focus
example:
<div class="accordion vertical">
<section id="Section1">
<h2>LALALA LALa</h2>
<asp:Button ID="Button1" runat="server" Text="Button" />
</section>
<section id="Section2">
<h2>ZZZZZZZZZZZZZZZz</h2>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
</section>
</div>
css:
.accordion {
width:300px;
height:650px;
overflow:hidden;
color:#474747;
background:#fff;
padding:10px;
text-align: center;
}
.accordion section{
float:left;
overflow:hidden;
color:#333;
cursor:pointer;
margin:3px;
}
.accordion section:hover {
background:#ececec;
}
.accordion section p {
width: 92%;
display:none;
text-align: left;
}
.accordion section:after{
position:relative;
font-size:24px;
color:#000;
font-weight:bold;
}
.accordion section:nth-child(1):after{ content:'1'; }
.accordion section:nth-child(2):after{ content:'2'; }
.accordion section:nth-child(3):after{ content:'3'; }
.accordion section:nth-child(4):after{ content:'4'; }
.accordion section:nth-child(5):after{ content:'5'; }
.accordion section:target {
width: 92%;
background: #f3fbe5;
padding:10px;
}
.accordion section:target:hover {
background: #f3fbe5;
}
.accordion section:target h2 {
width:100%;
color:#fff;
}
.accordion section:target h2 a{
color:#333;
padding:0;
font-weight: 700;
}
.accordion section:target p {
width: 90%;
display:block;
}
.accordion section h2 a{
padding:15px 10px;
display:block;
font-size:16px;
font-weight:normal;
color:#000;
text-decoration:none;
font-family: MyraidProReg;
}
.vertical section{
width:100%;
height:40px;
-webkit-transition:height 0.2s ease-out;
-moz-transition:height 0.2s ease-out;
-o-transition:height 0.2s ease-out;
transition:height 0.2s ease-out;
}
/*Set height of the slide*/
.vertical :target{
height:250px;
width:97%;
}
.vertical section h2 {
position:relative;
}
/*Set position of the number on the slide*/
.vertical section:after{
top:-60px;
left:250px;
}
.vertical section:target:after{
left:-9999px;
}
I managed to solve this one. just putting down my solution here incase someone needs it (or I get hit by a car and develop amnesia and need to resolve this in the future - hello future crudler).
Ok the problem isnt linked to either the accordian, or the controls underneath. The root cause is that a postback doesnt preserve the hashtag location.
So you can either do some funny stuff with the form's action, or catch the post back (on each control) and then set a startupscript as such
Page.ClientScript.RegisterStartupScript(this.GetType(), "anchor", "#Section2", true);
or if you are using a update panel to be nice and ajaxy (named pnl in my case)
ScriptManager.RegisterStartupScript(pnl, pnl.GetType(), "anchor", "#Section2", true);
you can then do some sneaky things like put the # name as one of your html tags, strip it out on the post back and make your method more generic

nav and logo issue when screen resolution is less than common size

I have a header like:
<header id="wrapper">
<div class="container clearfix">
<h1 id="logo" class="alignleft"> logo </h1>
<nav class="alignright">
<ul id="nav">
<li>menu 1</li>
<li>menu 2</li>
<li>menu 3</li>
<li>menu 4</li>
</ul>
</nav>
<div class="clear"></div>
</div>
</header>
And a nav in css definition
ul#nav {
margin-top: 30px;
margin-right: 50px;
}
ul#nav li { float:left; }
ul#nav li a {
color:#9a9a9a;
font-family: "champagne__limousinesbold", Arial, Helvetica, sans-serif;
font-size:18px;
font-weight:600;
text-decoration:none;
margin:0px 0px 0px 15px;
display:inline-block; -webkit-transition: all 0.2s ease 0s; -moz-transition: all 0.2s ease 0s; -o-transition: all 0.2s ease 0s; transition: all 0.2s ease 0s; padding:5px 10px; }
ul#nav li a:hover, ul#nav li a.active { color:#474747;}
ul#nav li.active a { color:#fff; background:#474747; }
So it works fine when the screen size is reasonable big so:
But if screen is small this happens:
Is there a way to minimize both logo (make smaller) and nav menu (make font small or something) so this does not happen?
Please take a look at the fiddle
To work with responsive design, two main techniques come into play: Percents, Floats, and Position: Relative. I have edited your fiddle to reflect these changes. Notable, I added % margins/padding on your elements instead of pxs, adjusted the image container to have % dimensions, and adjusted some css on your lists. You can see the results here:
http://jsfiddle.net/NUgEf/5/
In a word, yes. You will want to use a media query to adjust your CSS based on the screen size.
For example:
#media screen and (max-width : 600px) {
#logo {
width: /* New width */
}
ul#nav li a {
font-size: /* New font size */
}
}
More on media queries here
It kind of depends on what you want the menu to do when there's not enough room for it. You could force the links to start wrapping onto separate lines on small screens without using #media rules with some changes like this:
h1#logo {
float: left;
margin-left: 10px;
margin-top: 0px;
}
h1#logo a {
display:block;
width:239px;
height:147px;
text-indent:-9999px;
text-decoration:none;
background:url(http://blog.logobee.com/free-logo1.jpg) left top no-repeat;
}
nav.alignright {display: block; overflow: hidden;}
.alignright {
/* float: right; */ /* remove this */
}
Here's a live demo: http://codepen.io/anon/pen/miFyx