5

I'm trying to make a talkbubble styled div- box change colors completely upon being clicked.

I ran into a problem of getting the :before pseudo element that I'm using (to shape the arrow for the talkbubble) to actually change colors with the rest of the element, as seen here:

HTML

<div class="clickables">
        <div class="talkbubble">
            <input type="hidden" class="tbselector" value="sbselection_1">
            <div class="thumbnail">
               <img src="images/thumbnail1.png" height="33" width="30" />
             </div>
             <div class="words">Commons</div>
         </div>
         <div class="talkbubble">
             <input type="hidden" class="tbselector" value="sbselection_2">
             <div class="thumbnail">
                 <img src="images/thumbnail1.png" height="33" width="30" align="middle" />
             </div>
             <div class="words">crossroads</div>
         </div>
         .
         . More and more
         .
    </div>
</div>

CSS Just Relevant

.talkbubble {
   background: white;
   color: rgb(0,0,0);
   height: 40px;
   margin-top: 1%;
   margin-left: 48%;
   margin-right: auto;
   position: relative;
   width: 150px;    
 }
.talkbubble:before {
   border-top: 10px solid transparent; 
   border-right: 10px solid white; 
   border-bottom: 10px solid transparent; 
   content:""; 
   height: 0; 
   position: absolute; 
   right: 100%; 
   top: 10px; 
   width: 0;    
}
.talkbubble:before.clicked {
   border-right-color:#666666;
}
.talkbubble:hover{
    background-color: rgb(194,194,194)!important;
    color:rgb(255,255,255);
}
.talkbubble:hover:before{
   border-right-color: rgb(194,194,194)!important;
}

JQUERY

$('.clickables').on('click','.talkbubble',function () {
     $(this).parent().find('.talkbubble').css('background-color','#ffffff');
     $(this).css('background-color', '#666666');
 });

Here is a Demo http://jsfiddle.net/petiteco24601/3xuuq2fx/

I did some research and it seems a little inconclusive. For the most part, a lot of what I found was basically saying that there's no way to really force javascript on a pseudo element, since the pseudo element doesn't REALLY exist.

However, with more research, I found things like http://css-tricks.com/pseudo-element-animationstransitions-bug-fixed-in-webkit/ and Change an HTML5 input's placeholder color with CSS that say that those bugs were fixed and it is possible with some browsers to use javascript on pseudo elements. What's the actual deal? How extensively can a person control pseudo elements?

Community
  • 1
  • 1

3 Answers3

2

The way you can go is add or remove a new class.

  • First remove the !important declaration on your CSS is bad practice and can be conflictive later.

  • Then make a new class with the change you want :

    .clicked {
        background:#666;
    }
    .clicked:before {
        border-right-color:#666;
    }
    
  • Then with Jquery add / remove the class:

    $('.clickables').on('click','.talkbubble',function () {
        $(this).siblings('.talkbubble').removeClass('clicked');
        $(this).addClass('clicked');
    });
    

Check this DemoFiddle

DaniP
  • 37,813
  • 8
  • 65
  • 74
  • Thank you! That makes a lot of sense to do the class. I take that to mean that they still haven't exactly made it possible to automatically attach the pseudo-elements with the elements when you give it a jquery command. Do you think it'll be likely in the near future, or will we just always have to stick with finding these round-about ways to manage pseudo-elements? – petiteco24601 Oct 23 '14 at 15:55
  • @CosetteGirardot I don't think that can be a good idea to me inline styles must be avoided. But can be a godd tool to access another properties like change the content or fade the pseudo elements. And many others. – DaniP Oct 23 '14 at 16:00
2

If you are looking for only CSS solution without using javascript. Here it is:

Working Fiddle

I wrapped each list-item block with a label and radio button in HTML code. and in CSS, I added the following code:

.talkbubble {
    display: inline-block;
    /* other styles */
}

:checked + .talkbubble {
    background-color: #666;
}
:checked + .talkbubble:before {
    border-right-color: #666;
}
:checked + .talkbubble:hover:before {
    border-right-color: #666;
}
.clickables input[type="radio"] {
    position: absolute;
    visibility: hidden;
    pointer-events: none;
}

..and also removed !important as suggested by Danko.

Mr_Green
  • 40,727
  • 45
  • 159
  • 271
1

The only way I have been able to change pseudo CSS declarations has been to create individual <style> tags with and id associated with the class of the elements they are applied to. I.E.

<style id="talkbubble_style">
    .talkbubble:before{
    border-right-color:#666666;
    }
</style>

So, when you handle the click event, you get the style element and change the innerHTML to whatever CSS you want, along with the !important option added to each definition. Like this:

$('.clickables').on('click','.talkbubble',function () {
     $(this).parent().find('.talkbubble').css('background-color','#ffffff');
     $(this).css('background-color', '#666666');
     $('#talkbubble_style').html('.talkbubble:before{border-right-color:#666666!important;}');
});
Ryan Willis
  • 624
  • 3
  • 13