thinking stiff

CSS transitions with Javascript

Posted in Programming by thinkingstiff on 2013/02/08

Assigning CSS transitions in Javascript can be tricky due to both order of assignment and timing. Stepping though while debugging can give you different results than running live, which makes it difficult to find the problem. In answering CSS transitions do not work when assigned trough JavaScript on Stackoverflow, I came up with the following guidelines.

To make transition work, three things have to happen.

1. the element has to have the property explicitly defined (ex: opacity: 0;)
2. the element must have the transition defined: transition: opacity 2s;
3. the new property must be set: opacity: 1

If you are assigning #1 and #2 dynamically, there needs to be a delay before #3 so the browser can process the request. If you are debugging, it will often appear to work because you are creating this delay by stepping through it, giving the browser time to process. Adding transition to an element is not what triggers the animation, changing the property does.

To create this delay you can either add the first two steps to the HTML at design time, or create the delay in Javascript with .setTimeout().

Demo: http://jsfiddle.net/ThinkingStiff/QNnnQ/

HTML:

    <div id="fade1" class="fadeable">fade 1 - works</div>
    <div id="fade2">fade 2 - doesn't work</div>
    <div id="fade3">fade 3 - works</div>

CSS:

    .fadeable {
        opacity: 0;
    }
    
    .fade-in {
        opacity: 1;
        transition:             opacity 2s;
            -moz-transition:    opacity 2s;
            -ms-transition:     opacity 2s;
            -o-transition:      opacity 2s;
            -webkit-transition: opacity 2s;
    }

Script:

    //works
    document.getElementById( 'fade1' ).className += ' fade-in';
    
    //doesn't work
    document.getElementById( 'fade2' ).className = 'fadeable';
    document.getElementById( 'fade2' ).className += ' fade-in';
    
    //works
    document.getElementById( 'fade3' ).className = 'fadeable';
    window.setTimeout( function() {
        
        document.getElementById( 'fade3' ).className += ' fade-in';
        
    }, 100);

Highlight <table> column on :hover using CSS with no Javascript

Posted in Programming by thinkingstiff on 2012/06/26

While HTML allows the :hover pseudo-class on <tr> elements, unfortunately the same does not hold true for <col> elements. All solutions I’ve seen to highlight columns in tables involve Javascript.

I’ve tried to solve this with CSS a couple of times before with no luck. I recently saw this question on Stackoverflow, cols, colgroups and css :hover psuedoclass, which was looking to highlight both rows and columns at the same time. I gave it a shot and was able to do it using the ::after pseudo-element and no Javascript.

I saw another question looking for just a column solution, html: hover table column, and I simplified the code to what you see below. This works in all modern browsers except Firefox, which requires a little tweak. The function firefoxFix() below takes care of this.

Demo: http://jsfiddle.net/ThinkingStiff/2XeYe

CSS:

table {
    border-spacing: 0;
    border-collapse: collapse;
    overflow: hidden;
    z-index: 1;
}

td, th, .ff-fix {
    cursor: pointer;
    padding: 10px;
    position: relative;
}

td:hover::after,
.ff-fix:hover::after {
    background-color: #ffa;
    content: '\00a0';
    height: 10000px;
    left: 0;
    position: absolute;
    top: -5000px;
    width: 100%;
    z-index: -1;
}

HTML:

</pre>
<table>
<tbody>
<tr>
<th></th>
<th>50kg</th><th>55kg</th><th>60kg</th><th>65kg</th><th>70kg</th>
</tr>
<tr>
<th>160cm</th>
<td>20</td><td>21</td><td>23</td><td>25</td><td>27</td>
</tr>
<tr>
<th>165cm</th>
<td>18</td><td>20</td><td>22</td><td>24</td><td>26</td>
</tr>
<tr>
<th>170cm</th>
<td>17</td><td>19</td><td>21</td><td>23</td><td>25</td>
</tr>
<tr>
<th>175cm</th>
<td>16</td><td>18</td><td>20</td><td>22</td><td>24</td>
</tr>
</tbody>
</table>
<pre>

Firefox Fix:

function firefoxFix() {

    if ( /firefox/.test( window.navigator.userAgent.toLowerCase() ) ) {

        var tds = document.getElementsByTagName( 'td' );

        for( var index = 0; index < tds.length; index++ ) {
            tds[index].innerHTML = '<div class="ff-fix">' + tds[index].innerHTML + '</div>';                     
        };

        var style = '<style>'
            + 'td { padding: 0 !important; }' 
            + 'td:hover::before, td:hover::after { background-color: transparent !important; }'
            + '</style>';
        document.head.insertAdjacentHTML( 'beforeEnd', style );

    };

};
Tagged with: , , ,

How to make a contenteditable <div> look like an <input> element or <textarea>

Posted in Programming by thinkingstiff on 2012/01/22

Webkit browsers (Chrome/Safari) have a very old, and still outstanding, bug (#38943) with the ::selection pseudo-element: they totally ignore the background-color property.

In my answer to How to style the selected text in textareas and inputs in Chrome? on Stack Overflow, I outline that it is possible, to get around this issue using the contenteditable attribute because the ::selection background-color property is not ignored on <divs>. The look of both <input> and <textarea> elements can be can be duplicated with a <div>, contenteditable, and some CSS.

I further expanded the code in my answer in How do I make an editable DIV look like a text field?. The resulting <input> and <textarea> clones look nearly identical to their native counterparts on Chrome, Safari and Firefox. Opera and IE9 don’t look the same, but are still decent.

Demo: http://jsfiddle.net/ThinkingStiff/FcCgA/

CSS:

textarea {
    height: 28px;
    width: 400px;
}

#textarea {
    -moz-appearance: textfield-multiline;
    -webkit-appearance: textarea;
    border: 1px solid gray;
    font: medium -moz-fixed;
    font: -webkit-small-control;
    height: 28px;
    overflow: auto;
    padding: 2px;
    resize: both;
    width: 400px;
}

input {
    margin-top: 5px;
    width: 400px;
}

#input {
    -moz-appearance: textfield;
    -webkit-appearance: textfield;
    background-color: white;
    background-color: -moz-field;
    border: 1px solid darkgray;
    box-shadow: 1px 1px 1px 0 lightgray inset;  
    font: -moz-field;
    font: -webkit-small-control;
    margin-top: 5px;
    padding: 2px 3px;
    width: 398px;    
}

HTML:

<textarea>I am a textarea</textarea>
<div id="textarea" contenteditable>I look like textarea</div>

<input value="I am an input" />
<div id="input" contenteditable>I look like an input</div>

iPhone Notification Badge in CSS

Posted in Programming by thinkingstiff on 2012/01/21

iPhone Notification Badge - CSS

In answering this question, Vertically and horizontally centering text in circle in CSS, on Stack Overflow, I expanded upon an earlier solution I had to this problem and made them expandable.

These look good in webkit (and great on the iPhone), and pretty decent in -moz, -o, and -ms.

Demo: http://jsfiddle.net/ThinkingStiff/mLW47/

HTML:

<div class="badge">1</div>

CSS:

.badge {
background: radial-gradient( center -9px, circle closest-side, white 0, red 26px );
background: -moz-radial-gradient( center -9px, circle closest-side, white 0, red 26px );
background: -ms-radial-gradient( center -9px, circle closest-side, white 0, red 26px );
background: -o-radial-gradient( center -9px, circle closest-side, white 0, red 26px );
background: -webkit-radial-gradient( center -9px, circle closest-side, white 0, red 26px );
background-color: red;
border: 2px solid white;
border-radius: 12px; /* must be 1/2 of ( border-width*2 + width ) */
box-shadow: 1px 1px 1px black;
color: white;
font: bold 17px/15px Helvetica, Verdana, Tahoma;
height: 18px; /* height + padding-top must equal width */
padding-top: 2px; /* height + padding-top must equal width */
text-align: center;
width: 20px;
}
Tagged with: , , , ,
%d bloggers like this: