RSS

Category Archives: CSS

Turn jQuery slider into a switch

jQuery slider
jQuery slider

Three simple steps to turn jQuery UI slider into a switch.

1. Create HTML structure of the slider:

<span id="slider">
    <label id="on">GapAd ON<img src="/media/images/vsep.png"></label>
    <label id="off">GapAd OFF<img src="/media/images/vsep.png"></label>
</span>

2. Initialise jQuery slider object with two positions – on (zero) and one (off). And assign a handler for “slide” event that will change slider image depending on switch state.

$( "#slider" ).slider({
    value: 0,
    min: 0,
    max: 1,
    step: 1,
    slide: function( event, ui ) {
        if (ui.value == 0) {
            $('.ui-slider-handle').css('backgroundImage','url(/media/images/on.png)');
        } else {
            $('.ui-slider-handle').css('backgroundImage','url(/media/images/off.png)');
        }
    }
});

3. Now make a slider look a bit more like a switch with use of some CSS:

#slider {
    width: 170px; 
    background: #d6d5d5; 
    height: 3px; 
    position: relative; 
    display: block; 
}
	   
#slider .ui-slider-handle {
    top: -16px; 
    background: url('/media/images/on.png') 0 0 no-repeat; 
    border: 0; 
    width: 35px; 
    height: 35px; 
    left: 20px;
}
	
/* styling for the labels */    
#slider #on { position: absolute; ... }
#slider #off {position: absolute; ... }

In the end you should get something like on the picture in the beginning of the post.

Advertisements
 
2 Comments

Posted by on May 28, 2011 in CSS

 

Tags: , ,

Hide page content accessibly

Method offered by Jeff Burnz in his AdaptiveThemes article and then improved by community now evolved into a reliable cross-browser technique.

.hidden 
{
    position: absolute !important;
    clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
    clip: rect(1px, 1px, 1px, 1px);
    padding: 0 !important;
    border: 0 !important;
    height: 1px !important;
    width: 1px !important;
    overflow: hidden;
}

This method takes the element out of flow so it doesn’t affect the layout around it. By using height of 1px it fixes the issue with VoiceOver screen reader (Apple) that will not read content of an element that has 0 height.

Though if your gole is to hide content from all users you should use visibility and display of none instead.

.hidden 
{
  visibility: hidden;
  display: none;
}
 
Leave a comment

Posted by on April 11, 2011 in CSS

 

Show/hide elements depending on form selection

Say you have several fields on a form. Some of these fields need to be hidden/shown depending on the state of other element, for instance, checkbox.

Suppose we have the following simple markup:

<form id="theform">

   <p><input type="checkbox">Jeans</p>
   <p>Jeans Size: <select><option>1</option><option>2</option></select></p>
   <p>Jeans Colour: <select><option>Blue</option><option>Green</option></select></p>

   <p><input type="checkbox">Skirt</p>
   <p>
      Skirt Size: <select><option>1</option><option>2</option></select>
      Skirt Colour: <select><option>Blue</option><option>Green</option></select>
      Skirt Type: <select><option>Mini</option><option>Maxi</option></select>
   </p>

</form>

As there are no multiple dependances between elements and only one element is responsible for either show or hide additional block, then we give an ID to main group elements like “jeans”,”skirts”, etc. and CLASS of the same value to additional block elements:

<form id="theform">

   <p class="main"><input type="checkbox" id="jeans" >Jeans</p>
   <p class="jeans">Jeans Size: <select><option>1</option><option>2</option></select></p>
   <p class="jeans">Jeans Colour: <select><option>Blue</option><option>Green</option></select></p>

   <p class="main"><input type="checkbox" id="skirt">Skirt</p>
   <p class="skirt">
      Skirt Size: <select><option>1</option><option>2</option></select>
      Skirt Colour: <select><option>Blue</option><option>Green</option></select>
      Skirt Type: <select><option>Mini</option><option>Maxi</option></select>
   </p>

</form>

Then in window.onload event holder I create an object of the following structure that holds links to P elements which we want to hide/show.

obj['jeans'][0] = p1;
obj['jeans'][1] = p2;
obj['skirt'][0] = p3;

As we store the references then position of the element in the document doesn’t matter for us.

window.onload = function(){

   elemObj = new Object();
   var formP = document.getElementById("theform").getElementsByTagName("p");

   for(var i=0; i&lt;formP.length; i++){

      if(formP[i].className!="main") {
         if(typeof elemObj[formP[i].className]=='undefined') 
            elemObj[formP[i].className] = new Array(); 
         elemObj[formP[i].className].push(formP[i]);
         formP[i].style.display = 'none'; 
      } else formP[i].getElementsByTagName("input")[0].onclick = hideshow;
   }

}

At the same time I hide additional blocks (formP[i].style.display = ‘none’;) so if Javascript is disabled all inputs stay visible.

It’s a very simple solution for very simple markup structure. In situations where more than one element is responsible for additional block behaviour this method doesn’t work and you need to look for a more complex solution.

 
3 Comments

Posted by on May 15, 2009 in CSS, HTML, JavaScript

 

Tags:

Tiny class for an easy IFrame shim

Recently I had to add IFrame shims to several projects and I quite like the idea of darking the background and focusing user’s attention on particular part of the form. I have created a very simple tiny class that creates the shim and brings up a div or any other element you would want to show.

 
//constructor takes 2 parameters: 
//ID of the shim. If element with specified ID doesn't exist it will be created and added to the end of body element 
//Second parameter is the boolean true/false value that says if the IFrame should be used for the shim
var shim = function(shimId,addIframe){
	//Function that gets current document height and width. Used to stretch the shim to the very bottom of the page 
        var getHeightWidth = function(){
		if( window.innerHeight && window.scrollMaxY )  {
			pageWidth = window.innerWidth + window.scrollMaxX;
			pageHeight = window.innerHeight + window.scrollMaxY;
		}
		else if( document.body.scrollHeight > document.body.offsetHeight )	{
			pageWidth = document.body.scrollWidth;
			pageHeight = document.body.scrollHeight;
		} else { 
			pageWidth = document.body.offsetWidth + document.body.offsetLeft; 
			pageHeight = document.body.offsetHeight + document.body.offsetTop; 
		}
		return [pageWidth,pageHeight]
	}
	var windowSize = getHeightWidth();
	var getWindowSize = function(){	return windowSize; }
	//Function creates the shim and IFrame if required
	var createShim = function(){
		shimDiv = document.createElement('div');
		shimDiv.id = shimId;
		shimDiv.style.position = 'absolute';
		shimDiv.style.top = 0;
		shimDiv.style.left = 0;
		shimDiv.style.width = "100%";
		shimDiv.style.height = getWindowSize()[1]>600 ? getWindowSize()[1]+ 'px' : "100%";
		shimDiv.style.display = 'none';
		shimDiv.style.backgroundColor = '#000';
		shimDiv.style.opacity = '0.75';
		shimDiv.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=75)';
		document.body.appendChild(shimDiv);   
	
		if(addIframe) {
			var iframe = document.createElement('iframe');
			iframe.id = shimId+'_iframe';
			iframe.style.position = 'absolute';
			iframe.style.top = 0;
			iframe.style.left = 0;
			iframe.style.width = "100%";
			iframe.style.height = getWindowSize()[1]>600 ? getWindowSize()[1]+ 'px' : "100%";
			iframe.style.display = 'none';
			iframe.style.backgroundColor = '#000';
			iframe.style.opacity = '0.1';
			iframe.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=10)';
			iframe.setAttribute("src", "javascript:false");
			document.body.appendChild(iframe);     
		}   
	}
	//Function that makes shim visible
	this.showShim = function(showElem,zindex){
		shimDiv.style.display = 'block';
		shimDiv.style.zIndex = zindex - 1;
		if(document.getElementById(shimDiv.id+'_iframe')) {
                      document.getElementById(shimDiv.id+'_iframe').style.display = 'block';                     
                      document.getElementById(shimDiv.id+'_iframe').style.zIndex = zindex - 2;
                }
		var showElem = document.getElementById(showElem);
		showElem.style.position = 'absolute';
		showElem.style.display = 'block';
		showElem.style.left = (Math.round(getWindowSize()[0]/2) - Math.round(showElem.offsetWidth/2))-15+'px';
		showElem.style.top = '200px';(Math.round(document.body.offsetHeight/2) - Math.round(showElem.offsetHeight/2))+'px';
		showElem.style.zIndex = zindex;
	}
        //Function hides the shim
	this.hideShim = function(showElem){
		shimDiv.style.display  = 'none';
		if(document.getElementById(showElem)) 
                      document.getElementById(showElem).style.display = 'none';
		if(document.getElementById(shimDiv.id+'_iframe')) 
                      document.getElementById(shimDiv.id+'_iframe').style.display = 'none';
	}
	this.shimDiv = (document.getElementById(shimId)) ? document.getElementById(shimId): createShim();	
}

Shim will be created only once and then the existing link to the object will be used. Class works in IE6 as long as in IE7, last Opera, FF and Chrome.

Class is very simple but can be useful. Will be updated soon 😉

 
4 Comments

Posted by on May 6, 2009 in CSS, HTML, JavaScript

 

Tags: ,

Highlighting table rows

It would be great one day when we could finally highlight table rows with one line of CSS code like this:

table tr:hover td { background:#ccc; }

But unfortunately IE6 only supports :hover pseudo-class on <a> elements. And my testing showed that Opera and Firefox had weird problems with this code on TDs with borders. A way round this is to add a bit of JavaScript instead of pure CSS solution.

Let’s say there are several tables on the page with the same highlight behavior. Table structure doesn’t matter so I chose the very simple one:

<table>
   <tr>
      <td>row 1 column 1</td>
      <td>row 1 column 2</td>
      <td>row 1 column 3</td>
   </tr>
   <tr>
      <td>row 2 column 1</td>
      <td>row 2 column 2</td>
      <td>row 2 column 3</td>
   </tr>
</table>

On page load the script goes through all the TRs and apply “onhover” event handler to each one. To add event handlers I use a great cross-browser function “addEvent” by Peter-Paul Koch. It’s code looks like this:

function addEvent(obj, evType, fn){ 
 	if (obj.addEventListener){ 
   		obj.addEventListener(evType, fn, false); 
   		return true; 
 	} else if (obj.attachEvent){ 
   		var r = obj.attachEvent("on"+evType, fn); 
   		return r; 
 	} else { 
   		return false; 
 	} 
}

And bellow is an example of how to use it:

addEvent(window, 'load', rowHighlightSet);

The function “rowHighlightSet” will be execuled each time you move the mouse over the TR. It goes through all the tables on the page and through each TR of each table and assign “rowHighlight” function as onmouseover and onmouseout event handler. The way I am doing this is the following:

var rowHighlightSet = function(){
 var tables = document.getElementsByTagName('table');
	
 for(var i=0,trs; i<tables.length;i++){
    var trs = tables&#91;i&#93;.getElementsByTagName('tr');
    for(var j=0; j<trs.length;j++){
      trs&#91;j&#93;.onmouseover = trs&#91;j&#93;.onmouseout = rowHighlight;
    }
 }
}
&#91;/sourcecode&#93;

<p>To change the background colour function "rowHighlight" adds "hovered" class to the row. If there are already classes applied to this rows then you should remove (or replace) only the value of the highlighting class name (and don't forget about spaces between class names).</p>


var rowHighlight = function(){
   if(this.className!='hovered') 
      this.className='hovered'; 
   else 
      this.className='';
}

And the last bit to add is definition of hovered class in the CSS. I am using a nice colour for my TRs 🙂

.hovered td {background:#d2ebfb;}

Nice and easy!

Link to the source file

 
2 Comments

Posted by on April 27, 2009 in CSS, HTML, JavaScript

 

Tags: ,

Moving images continuously

Yesterday I got a task to create a script that would make images move continuously. Of course the easiest way is to use flash for such sort of animation. But the client insisted on JavaScript.

First we need to prepare HTML – 2 dives with a few images inside.

<div id="picsholder">

   <div id="movingpics">

      <img src="/img/1.jpg">

      <img src="/img/2.jpg">

      <img src="/img/3.jpg">

      <img src="/img/4.jpg">

   </div>

</div>

The outer div limits of the visible area of the slidshow and must have width and height specified.

#picsholder { overflow:hidden; width:950px; height:135px; }

As we don’t want the images to move to the next line if the slideshow has length greater than desirable visible area, we position them absolutely in a positioning context generated by the outer div:

#picsholder { overflow:hidden; width:950px; height:135px; position:relative}
#picsholder img { width:200px; height:130px; position:absolute; }

Notice position:relative rule has been added to the outer div css to create positioning context.

Now all the images are stuck to the left side of the outer div. All we need to do is specify left property for each image. And then make them move!

For that I add some JavaScript on window onload event:

var movingpics = document.getElementById('movingpics');

if((movingpics)&amp;&amp;(movingpics.getElementsByTagName('img'))) {
   var links = movingpics.getElementsByTagName('img');
   var totallength = 0;
   movingpics.style.display = 'inline';
   for(var i=0, link; i&lt;links.length;i++){
      link = links[i];
      link.style.left = totallength + 'px';
      totallength+= link.offsetWidth;
   }
}

The code above gives each image of the slide show it’s own value of the left property accordingly to the position in the list. To make images move all I need is change the left property. For that I use the following function.

var movepic = function(){

   var movingpics = document.getElementById('movingpics');

   if((movingpics)&amp;&amp;(movingpics.getElementsByTagName('img'))) {

      var links = movingpics.getElementsByTagName('img');
      var totallength = 1250;

      for(var i=0, link; i&lt;links.length;i++){
      link = links[i];

      if(link.style.left.replace('px','')*1&lt;=0-link.offsetWidth){
            if(i==0){link.style.left =  (links[links.length-1].style.left.replace('px','')*1)+links[links.length-1].offsetWidth+'px';}
            else{link.style.left =  (links[i-1].style.left.replace('px','')*1)+links[i-1].offsetWidth+'px';	}

         } else {link.style.left =  ((link.style.left.replace('px',''))*1)-1+'px';}

      }

   }
}

I add it to the same onload function and make it execute every 50 milliseconds.

setInterval ( "movepic()", 50 );

That’s it!

Link to source file

 
Leave a comment

Posted by on April 24, 2009 in CSS, HTML, JavaScript

 

Tags: , ,

UL formatted to two or more columns

Very simple way to format UL or OL to two or more columns is to use float property.

Take this example – UL element with 8 LIs:

<ul>
   <li>Item 1</li>
   <li>Item 2</li>
   <li>Item 3</li>
   <li>Item 4</li>
   <li>Item 5</li>
   <li>Item 6</li>
   <li>Item 7</li>
   <li>Item 8</li>
</ul>

This is how UL looks without float property.

  • Item 1
  • Item 2
  • Item 3
  • Item 4
  • Item 5
  • Item 6
  • Item 7
  • Item 8

To make the list look like we want it, we do the following:

<style>
   ul { width:400px; }
   li  { width:200px; float:left; }
</style>

And we get two column list like that:

If you want you can set width in percents. The number of columns depends on the width of the columns. For instance, to change the example above to 3 colums view, you would need to decrease the column size to 30%.

 
4 Comments

Posted by on August 16, 2008 in CSS, HTML

 

Tags: , ,

 
%d bloggers like this: