19 Replies Latest reply: Aug 15, 2012 10:42 AM by jyeager11 RSS

    Any way to make "active" pseudo-class sticky?

    jyeager11 Community Member

      Here's how I do my "on-clicks" via CSS :

       

      a#button1, a#button2, a#button3 {

          display:block;

          float:left;

          width:50px;

          height:50px;

      }

       

      a#button1 { background:url(button1.png) 0 0 no-repeat }

      a#button1:active { background-position:-55px 0 }

       

      a#button2 { background:url(button2.png) 0 0 no-repeat }

      a#button2:active { background-position:-55px 0 }

       

      a#button3 { background:url(button3.png) 0 0 no-repeat }

      a#button3:active { background-position:-55px 0 }


      These buttons hide/unhide divs, and I'd like my menu to keep the active state visible after letting go of the mouse button. As an indicator of what div we're at.

       

      What's the best way to do this? Note : It's obviously important that when a new button lights up, the previously lit one goes back to its regular state.

        • 1. Re: Any way to make "active" pseudo-class sticky?
          Ken Binney MVP

          No, except as you were advied the last time you posted this question

          http://forums.adobe.com/thread/1046364

          • 2. Re: Any way to make "active" pseudo-class sticky?
            jyeager11 Community Member

            The last time I asked this question, a method was proposed to me that did not satisfy the "other buttons must un-highlight" requirement, and then the thread fell off the face of the earth. Hence the new thread, which makes that requirement more clear.

             

            I refuse to believe, as you are suggesting, that the answer is simply "no". Maybe you can't think of a way, but perhaps someone else can.

            • 3. Re: Any way to make "active" pseudo-class sticky?
              Jon Fritz II MVP

              The psudo class :active simply is not for what you are attempting. Here's an example I've created using CSS and HTML only for a menu where the "on" state stays when you click an item. Normally you would use a javascript link highlighter for that type of thing. You can tear apart and change it to your needs if you're interested...

               

              <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

              <html xmlns="http://www.w3.org/1999/xhtml">

              <head>

              <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

              <title>Untitled Document</title>

              <style type="text/css">

              b {
              margin:0;
              padding:0;
              }
              .rtb { /* background and rounded edges of entire nav area */
              margin:auto;
              position:relative;
              height:28px;
              width:376px;
              background-color:#099;
              border:1px solid black;
              border-top-left-radius:10px;
              border-bottom-left-radius:10px;
              border-top-right-radius:10px;
              border-bottom-right-radius:10px;
              padding:0 20px;
              clear:both;
              box-shadow:5px 5px 10px 10px #CCC;
              }
              .rtb input[type="radio"] { /* Hides the standard radio button from view */
                  position:relative;
              display:none;
              }
              .rtb label { /* Sets attributes for the label of each radio button, which is still displayed */
                  position:relative;
              display:block;
              float:left;
              top:0px;
              height:20px;
              width:70px;
                  background-color:#06C;
                  padding:4px 11px;
                  font-family:Arial;
                  font-size:16px;
              border-left:1px solid #06C;
              border-right:1px solid #06C;
              }
              .rtb input[type="radio"]:checked + label { /* Sets the radio button label checked state (when a radio button is checked) */
                  background-color:#bbb;
              border-left:1px solid black;
              border-right:1px solid black;
              }
              .rtb input[type="radio"] + label b { /* Makes all rb label information panels (inside the b tag inside the label) invisible */
              display:none;
              }
              .rtb input[type="radio"]:checked + label b { /* Sets the rb label information (b tag) checked state (when radio button is checked) */
              position:relative;
              top:5px;
              width:350px;
              display:block;
              font-weight:normal;
              padding:10px;
              border-radius:10px;
              border:1px solid black;
              background-color:white;
              margin-top:10px;
              box-shadow:5px 5px 10px 10px #CCC;

              }
              .btn1 { /* sets button 1 attributes */
              position:relative;
              width:276px;
              }
              .btn2 { /* sets button 2 attributes */
              position:relative;
              left:-94px;
              width:276px;
              }
              .btn3 { /* sets button 3 attributes */
              position:relative;
              left:-188px;
              width:276px;
              }
              .btn4 { /* sets button 4 attributes */
              position:relative;
              left:-282px;
              width:276px;
              }
              </style>

              </head>

              <body>

                  <div class="rtb">

                    
                     
              <input type="radio" id="radio1" name="radios" value="all" checked="checked" />

                      <label for="radio1">Look<b class="btn1">I have gone ahead and created a way</b></label>

                     
                     
              <input type="radio" id="radio2" name="radios" value="false" />

                      <label for="radio2">Open<b class="btn2">to display separate text boxes, on click using all CSS</b></label>

                 
                     
              <input type="radio" id="radio3" name="radios" value="true" />

                      <label for="radio3">Test<b class="btn3">no javascript was <a href="http://www.google.com" target="_blank">harmed</a>, er, written in the making of this menu</b></label>

                     
                     
              <input type="radio" id="radio4" name="radios" value="true" />

                      <label for="radio4">Like<b class="btn4">And it validates as XHTML 1.0 and CSS</b></label>

                     
                 
              </div>

              </body>

              </html>

               

              • 4. Re: Any way to make "active" pseudo-class sticky?
                jyeager11 Community Member

                Thanks, I know you meant well by making everything so pretty and adding the extra "display extra content" functionality... but I don't really need all of that, and it makes it more difficult for me to isolate the basic functionality I need and see if it works in my code.


                Any way you can bare-bones this, and keep only the part that makes the class change stick on click? Eliminate all unnecessary styling. Just use two different background colors to differentiate the regular and active states.

                 

                These are great CSS acrobatics, but they kind of scare me, especially when I don't need half of this functionality. I also don't trust myself to make a clean cut of what I need and what I don't without breaking something.

                • 5. Re: Any way to make "active" pseudo-class sticky?
                  Jon Fritz II MVP

                  Here's something that may work a little better for you. It's a simple javascript class switcher. Just make the active menu and inactive menu CSS do what you like. Then make sure to add the starting CSS class to the links in your page (for the "just loaded" states of each)...

                   

                  <!DOCTYPE html>

                  <html>

                  <head>

                  <script>

                  function changeClass(elClass) {
                    var divsLength =  document.getElementsByClassName("menu").length;
                    for (i = 0; i
                  < divsLength; i++) {

                      document.getElementsByClassName("menu")[i].className = "inactive menu";
                    }
                    elClass.className = "active menu";  
                  }
                  </script>

                  <meta charset=utf-8 />

                  <title>JS Bin</title>

                  <style>


                             .inactive {
                  color:red;
                  background-color:white;
                  height:20px;
                  width:200px;
                  vertical-align:middle;
                  font-family:Verdana, Geneva, sans-serif;
                  clear:both;
                   
                  }
                              .active {
                  color:white;
                  background-color:black;
                  font-weight:bold;
                  height:30px;
                  width:200px;
                  vertical-align:middle;
                  font-family:Verdana, Geneva, sans-serif;
                  clear:both;
                   
                  }
                  </style>

                  </head>

                  <body>

                    <p><a class="active menu" onClick="changeClass(this)">

                  Option 1
                  </a></p>

                    <p><a class="inactive menu" onClick="changeClass(this)">

                  Option 2
                  </a></p>

                    <p><a class="inactive menu" onClick="changeClass(this)">

                  Option 3
                  </a></p>

                  </body>

                  </html>

                  • 6. Re: Any way to make "active" pseudo-class sticky?
                    jyeager11 Community Member

                    That works well, but what if each option has its own custom "active" state?

                     

                    Take a look at the example in the OP. Each option calls its own background PNG, which repositions itself on click to display a different image.

                     

                    Your solution is great, but only accounts for a single active class, and a single inactive class.

                    • 7. Re: Any way to make "active" pseudo-class sticky?
                      Jon Fritz II MVP

                      I'll post a version that allows you to make as many buttons als you like, but changing it to accomplish what you want is pretty basic as far as CSS goes. You really should take some time to get the hang of how to create and work with cascading style sheets, I suggest the tutorials on this site:

                       

                       

                      http://www.w3schools.com

                       

                       

                      In the example below, I only changed the active background color, but you could change any and all of the CSS to fit your needs.

                       

                       

                      <!DOCTYPE html>

                      <html>

                          <head>

                              <script>

                      function changeClass(elClass) {

                        var divsLength =  document.getElementsByClassName("menu").length;

                        for (i = 0; i < divsLength; i++) {

                          document.getElementsByClassName("menu")[i].className = "inactive menu";

                        }

                        elClass.className = "active menu";  

                      }

                      </script>

                      <meta charset=utf-8 />

                      <title>Sticky Selection</title>

                       

                      <style>

                      p.button1 .inactive {

                          color:red;

                          background-color:white;

                          height:20px;

                          width:200px;

                          vertical-align:middle;

                          font-family:Verdana, Geneva, sans-serif;

                          clear:both;

                      }

                      p.button1 .active {

                          color:white;

                          background-color:black;

                          font-weight:bold;

                          height:30px;

                          width:200px;

                          vertical-align:middle;

                          font-family:Verdana, Geneva, sans-serif;

                          clear:both;

                      }

                      p.button2 .inactive {

                          color:red;

                          background-color:white;

                          height:20px;

                          width:200px;

                          vertical-align:middle;

                          font-family:Verdana, Geneva, sans-serif;

                          clear:both;

                      }

                      p.button2 .active {

                          color:white;

                          background-color:orange;

                          font-weight:bold;

                          height:30px;

                          width:200px;

                          vertical-align:middle;

                          font-family:Verdana, Geneva, sans-serif;

                          clear:both;

                      }

                      p.button3 .inactive {

                          color:red;

                          background-color:white;

                          height:20px;

                          width:200px;

                          vertical-align:middle;

                          font-family:Verdana, Geneva, sans-serif;

                          clear:both;

                      }

                      p.button3 .active {

                          color:white;

                          background-color:purple;

                          font-weight:bold;

                          height:30px;

                          width:200px;

                          vertical-align:middle;

                          font-family:Verdana, Geneva, sans-serif;

                          clear:both;

                      }

                              </style>

                              </head>

                          <body>

                                <p class="button1"><a class="inactive menu" onclick="changeClass(this)">Option 1</a></p>

                                <p class="button2"><a class="inactive menu" onclick="changeClass(this)">Option 2</a></p>

                              <p class="button3"><a class="inactive menu" onclick="changeClass(this)">Option 3</a></p>

                          </body>

                      </html>

                      • 8. Re: Any way to make "active" pseudo-class sticky?
                        jyeager11 Community Member

                        I'm sorry, I just can't adapt this code to the example in the OP. I've been trying for the past half hour. :-(

                        • 9. Re: Any way to make "active" pseudo-class sticky?
                          Jon Fritz II MVP

                          Could you post a link to a test page to show what you have so far?

                          • 10. Re: Any way to make "active" pseudo-class sticky?
                            jyeager11 Community Member

                            You're so very kind to keep at it like this, I can't thank you enough... but everything is still at the local stage right now, not uploaded anywhere yet. But the code used in the OP is the one I'm using. I'm stacking <a> tags as block elements, floating left, so as to produce a horizontal row of buttons. On mouse click, the backgrounds of these buttons change. I can't wrap <p> tags around them easily, as that will insert all kinds of nasty side-effects, and also break the class and id naming conventions. That's where the merging of the two really lost me.

                            • 11. Re: Any way to make "active" pseudo-class sticky?
                              Jon Fritz II MVP

                              :active represents only the period of time in which an element is being "actively" clicked in the same way that :hover represents the time in which an element is being "hovered" over. Neither of these can be "made sticky" but you can use other CSS definitions to create the appearance that they are (which is what I gave you).

                               

                              There's really nothing more I can do for you if you continue to try to get :active to work in a way that it cannot work.

                               

                              You should be adapting your show/hide elements to the active-link code I supplied, not the other way around.

                              • 12. Re: Any way to make "active" pseudo-class sticky?
                                jyeager11 Community Member

                                I don't insist that :active be used. I'm saying I don't know how to redistribute the class/id's to make my current layout work with your example. For one thing, you're using <p> tags which have all kinds of undesirable side-effects to a code that's based on float:left positioning. I tried replacing the <p> tags with unordered list elements, but that didn't work out well either.

                                • 13. Re: Any way to make "active" pseudo-class sticky?
                                  Jon Fritz II MVP

                                  What specific side-effects are you seeing with the <p> tag?

                                   

                                  Are you forgetting to remove the margin from the <p> in your CSS and getting the margin separation?

                                   

                                  try this...

                                   

                                  p.button1, p.button2, p.button3 {

                                       margin:0;

                                  }

                                  • 14. Re: Any way to make "active" pseudo-class sticky?
                                    jyeager11 Community Member

                                    Well, for one thing, the OP example is a horizontal row of buttons, so there are margin but also carriage return issues with using a <P> tag as an identifier.

                                     

                                    Also, I'm looking at this code again, and wondering why we're applying height/width values to the P tag rather than the A tag. How does the A tag know to fill the space determined by the P tag, when there's no text? Again, in the OP, there is no actual text -- these aren't text links. They're PNG buttons.

                                    • 15. Re: Any way to make "active" pseudo-class sticky?
                                      Jon Fritz II MVP

                                      The original post example is broken CSS that can't possibly work and shows exactly zero HTML markup information.

                                       

                                      The margin CSS I posted in my last response removes the "carriage return" effect of a <p>.

                                       

                                      I am using <p> as a block element (display:block) so you can use the background-image property and have a separate image in the active class from the inactive class. I only used the <a> tags to get the mouse pointer to switch to the finger when you mouse over. You can use any tag you like, you just don't get the automatic mouse switch when you add onclick to a non-a-tag.

                                      • 16. Re: Any way to make "active" pseudo-class sticky?
                                        jyeager11 Community Member

                                        Huh? What's so broken about the original CSS? It displays A tags as block elements, floats them left so they can be horizontally sequenced, and displays one background in normal state and a different background on mouseclick, by way of repositioning the background image (which actually contains 2 images, one being displayed at a time).

                                        a#button1, a#button2, a#button3 {

                                            display:block;

                                            float:left;

                                            width:50px;

                                            height:50px;

                                        }

                                         

                                        a#button1 { background:url(button1.png) 0 0 no-repeat }

                                        a#button1:active { background-position:-55px 0 }

                                         

                                        a#button2 { background:url(button2.png) 0 0 no-repeat }

                                        a#button2:active { background-position:-55px 0 }

                                         

                                        a#button3 { background:url(button3.png) 0 0 no-repeat }

                                        a#button3:active { background-position:-55px 0 }


                                        Here's the HTML portion :

                                         

                                        <div>

                                          <a href="javascript:slide('div-home')" id="button1"> </a>

                                          <a href="javascript:slide('div-vip1')" id="button2"> </a>

                                          <a href="javascript:slide('div-vip2')" id="button3"> </a>

                                        </div>

                                        • 17. Re: Any way to make "active" pseudo-class sticky?
                                          jyeager11 Community Member

                                          Even without margins, the P tag creates line breaks. And the A tags aren't there just to change the cursor pointer (we can change the cursor pointer via CSS or javascript) they actually contain all the class info. I tried moving that info to the P tag but of course this doesn't work either.

                                           

                                          I'm sorry, I have to give up on this solution. The way it's coded, it just doesn't work for my purposes (ie, a horizontal row of buttons that contain NO live text, just block elements that swap background positions to create active and inactive states).

                                          • 18. Re: Any way to make "active" pseudo-class sticky?
                                            Jon Fritz II MVP

                                            I'm sorry you can't figure it out. I really am, and I wish you luck on your future endeavors.

                                            • 19. Re: Any way to make "active" pseudo-class sticky?
                                              jyeager11 Community Member

                                              Don't ask me HOW, but I got it working... by removing all the <P> tags, and inserting the "button0-1-2-etc" class as an ID on the A tag.

                                               

                                              So the CSS now looks like this :

                                               

                                              a#button0.inactive{ background:url(/carousel_home.png) -55 0 no-repeat }
                                              a#button0.active{ background:url(/carousel_home.png) 0 0 no-repeat }
                                              a#button1.inactive{ background:url(/carousel_vip.png) -55px 0 no-repeat }
                                              a#button1.active{ background:url(/carousel_vip.png) 0 0 no-repeat }

                                               

                                              My apologies for losing patience with this script prematurely.

                                               

                                              Question : Is it possible to trigger a change in these buttons' state from remote? Say there's a link elsewhere in the page that takes you to a different area on the site, and you want the navigation menu to reflect this without actually having clicked on anything in that menu. Using Javascript, can I target id="button1" and change its active/inactive state (while simultaneously reverse the others, like it currently does now when you click on a button to make it active, all the others become inactive)?