Link to home
Start Free TrialLog in
Avatar of jmsproductions
jmsproductions

asked on

How do I use multiple background images for the tabs in DreamWeavers Spry Tabbed Panels?

I am trying to create a Tabbed Panel Using DreamWeavers Spry Tabbed Panels. I would like the tabs to have different background images for each tab similar to what is done on these pages:

http://www.nutrisystem.com/jsps_hmr/catalog/men/basic.jsp?categoryId=358
(Under Men's Basic Plan Features the tabs that read -  28-Day Meal Plan, FREE Online Membership and Special Offers

Another example is the tabs on this page:
http://search.barnesandnoble.com/booksearch/isbninquiry.asp?r=1&ean=9780312367527
that start with Overview and Editorial Reviews

Each tab will have two images - one that shows when you are on that particular tab and one that will show as the unselected tab.

Is there a way to do this with the DreamWeaver Spry Tabbed Panels?
Avatar of knonie
knonie
Flag of Pakistan image

DW's Spry tabs have general styles, applicable on all the elements that are alike.
Like, the class of drop-down link's text is defined in a class/ID, and is applied on all of them.
Similarly, BG for main navigation tabs is defined in a single class.

In order to use different styles for each tab, you need to write separate classes for each tab, having different BG image.

If it feels somewhat complicated to customize, look for some better code from some free scripts site.

:-)
Avatar of jmsproductions
jmsproductions

ASKER

I tried changing the class for each tab - and was able to get the background image different for each tab, but then could not get it to switch for the Selected State. If I applied the Selected button to the .TabbedPanelsTabSelected the of course it applied theSelected button to all the tabs - not just the one. I then created a .TabbedPanelsTabEventSelected and .TabbedPanelsTabTrainSelected with the Selected button as the background, but it is not working:

http://www.jasonstudley.com/clients/tabs/tab.html

Not sure what I am doing wrong - do I need to change the .js file too or is it just something I am doing wrong in the .css file:

http://www.jasonstudley.com/clients/tabs/SpryAssets/SpryTabbedPanels.css

I have attached the button images so you can see what they look like and their file name.
live-events-btn.gif
live-events-over-btn.gif
training-networking-btn.gif
training-networking-over-btn.gif
ASKER CERTIFIED SOLUTION
Avatar of knonie
knonie
Flag of Pakistan image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks for your help. I will repost this as a javascript question.
A third option would have been to use id's for the tabs and then style each tab using:
#tabId.TabbedPanelsTabSelected {
 /*tab-unique options in here*/
}

I have yet to see style-related issues that cannot be solved with the right markup and css-selector ;)
Kindly apply your suggestions to actual Spry menu code and see if it works.

We just have one place in HTML code to set CSS ID of selected tab, and it gets applied on any tab that's currently selected,
so I can't see any way to apply different IDs on selected tab without making big changes in JS.

:-)
An id is NOT CSS! Neither is class/classname CSS. Class and ID are, and always should be html-attributes, CSS can be use to target elements based on those attributes. I find it hard to believe that Spry would break with such conventions.

My suggestion is not to alter the script, or supply the script with additional information, my suggestion was to add significance to your html-code.

My only assumption is that the html-code does not rely on scripts to generate it, if it does, I would strongly suggest to bury Spry a 100 feet under and start looking for something a little more friendly to Standards compliant methods.
Unfortunately, the default that comes with Adobe Dreamweaver has this limitation...
And I tried to look for some other code, but all I found out was that identical code.

If you find some related code, do post here.

:-)
If, the original posters' link to the html has not had its' scripts modified, then a selected tab looks like this:
<li class="TabbedPanelsTabEvent TabbedPanelsTabSelected" tabindex="0"/>

In this "TabbedPanelsTabEvent" should have been an 'id' not a class. Even so, since Spry actually adds the class "TabbedPanelsTabSelected", you can make a distinction between the different tabs. You'll just have to be smart about it (or one might call this cheating ;).

For each tab make a single image that contains all the different stats of the tab, make sure that for each tab the offset from the first, to the second state is equal to those of the other tabs (for instance, pick 512 pixels as the offset from the left-most pixel of state 1 to the left-most pixel of state 2). You could then define the css, along the lines of:
.TabbedPanelsTabEvent {
  background: transparent url(panelEvent.gif) no-repeat 0 0;
}

.TabbedPanelsTabSelected {
  background-position: -512px 0; /*Move state 1 out of view and state 2 into view*/
}

This could be a usefull implementation of the 'sprite' technique... Not quite as comfortable as using id's, but hey, if Spry is crippled only a little, this would be a possible work-around :)
Actually
  • comes only once, so whatever you define in class ".TabbedPanelsTabSelected" would effect both tabs, whichever is selected.

    :-)
    I know, so let's assume tab1 is 200 pixels wide and tab2 is 300 pixels wide:
    .TabbedPanelsTab1 {
      background: transparent url(panel1.gif) no-repeat 0 0;
      width: 200px;
    }
    .TabbedPanelsTab2 {
      background: transparent url(panel2.gif) no-repeat 0 0;
      width: 200px;
    }

    As long as both gifs have the different states of the tabs set at an equal distance from left-most to left-most, and I've chosen 512 pixels in my example, the selected state would work the same for both tabs:
    .TabbedPanelsTabSelected {
      background-position: -512px 0; /*Move state 1 out of view and state 2 into view*/
    }

    Since all I do is shift the position of the background-image, and that image is defined elsewhere, the effect would work for as many tabs as you want. After all, the class only affects one tabs at a time, once it swaps to another tab the first one gets reset to the default background-position...
    correction for first style snippet:
    .TabbedPanelsTab1 {
      background: transparent url(panel1.gif) no-repeat 0 0;
      width: 200px;
    }
    .TabbedPanelsTab2 {
      background: transparent url(panel2.gif) no-repeat 0 0;
      width: 300px;
    }
    Yes, this idea really makes sense, but I need to test it.

    :-)
    To illustrate the idea a little better, I've added a sprite based on the OPs' images.
    sprite.gif
    I am a little confused - could you show me how the CSS code should be written. I have included the original CSS code that comes with the Tabbed Panels. Thanks for all your help.

    Jason


    @charset "UTF-8";
     
    /* SpryTabbedPanels.css - Revision: Spry Preview Release 1.4 */
     
    /* Copyright (c) 2006. Adobe Systems Incorporated. All rights reserved. */
     
    /* Horizontal Tabbed Panels
     *
     * The default style for a TabbedPanels widget places all tab buttons
     * (left aligned) above the content panel.
     */
     
    /* This is the selector for the main TabbedPanels container. For our
     * default style, this container does not contribute anything visually,
     * but it is floated left to make sure that any floating or clearing done
     * with any of its child elements are contained completely within the
     * TabbedPanels container, to minimize any impact or undesireable
     * interaction with other floated elements on the page that may be used
     * for layout.
     *
     * If you want to constrain the width of the TabbedPanels widget, set a
     * width on the TabbedPanels container. By default, the TabbedPanels widget
     * expands horizontally to fill up available space.
     *
     * The name of the class ("TabbedPanels") used in this selector is not
     * necessary to make the widget function. You can use any class name you
     * want to style the TabbedPanels container.
     */
    .TabbedPanels {
    	margin: 0px;
    	padding: 0px;
    	float: left;
    	clear: none;
    	width: 100%; /* IE Hack to force proper layout when preceded by a paragraph. (hasLayout Bug)*/
    }
     
    /* This is the selector for the TabGroup. The TabGroup container houses
     * all of the tab buttons for each tabbed panel in the widget. This container
     * does not contribute anything visually to the look of the widget for our
     * default style.
     *
     * The name of the class ("TabbedPanelsTabGroup") used in this selector is not
     * necessary to make the widget function. You can use any class name you
     * want to style the TabGroup container.
     */
    .TabbedPanelsTabGroup {
    	margin: 0px;
    	padding: 0px;
    }
     
    /* This is the selector for the TabbedPanelsTab. This container houses
     * the title for the panel. This is also the tab "button" that the user clicks
     * on to activate the corresponding content panel so that it appears on top
     * of the other tabbed panels contained in the widget.
     *
     * For our default style, each tab is positioned relatively 1 pixel down from
     * where it wold normally render. This allows each tab to overlap the content
     * panel that renders below it. Each tab is rendered with a 1 pixel bottom
     * border that has a color that matches the top border of the current content
     * panel. This gives the appearance that the tab is being drawn behind the
     * content panel.
     *
     * The name of the class ("TabbedPanelsTab") used in this selector is not
     * necessary to make the widget function. You can use any class name you want
     * to style this tab container.
     */
    .TabbedPanelsTab {
    	position: relative;
    	top: 1px;
    	float: left;
    	padding: 4px 10px;
    	margin: 0px 1px 0px 0px;
    	font: bold 0.7em sans-serif;
    	background-color: #DDD;
    	list-style: none;
    	border-left: solid 1px #CCC;
    	border-bottom: solid 1px #999;
    	border-top: solid 1px #999;
    	border-right: solid 1px #999;
    	-moz-user-select: none;
    	-khtml-user-select: none;
    	cursor: pointer;
    }
     
    /* This selector is an example of how to change the appearnce of a tab button
     * container as the mouse enters it. The class "TabbedPanelsTabHover" is
     * programatically added and removed from the tab element as the mouse enters
     * and exits the container.
     */
    .TabbedPanelsTabHover {
    	background-color: #CCC;
    }
     
    /* This selector is an example of how to change the appearance of a tab button
     * container after the user has clicked on it to activate a content panel.
     * The class "TabbedPanelsTabSelected" is programatically added and removed
     * from the tab element as the user clicks on the tab button containers in
     * the widget.
     *
     * As mentioned above, for our default style, tab buttons are positioned
     * 1 pixel down from where it would normally render. When the tab button is
     * selected, we change its bottom border to match the background color of the
     * content panel so that it looks like the tab is part of the content panel.
     */
    .TabbedPanelsTabSelected {
    	background-color: #EEE;
    	border-bottom: 1px solid #EEE;
    }
     
    /* This selector is an example of how to make a link inside of a tab button
     * look like normal text. Users may want to use links inside of a tab button
     * so that when it gets focus, the text *inside* the tab button gets a focus
     * ring around it, instead of the focus ring around the entire tab.
     */
    .TabbedPanelsTab a {
    	color: black;
    	text-decoration: none;
    }
     
    /* This is the selector for the ContentGroup. The ContentGroup container houses
     * all of the content panels for each tabbed panel in the widget. For our
     * default style, this container provides the background color and borders that
     * surround the content.
     *
     * The name of the class ("TabbedPanelsContentGroup") used in this selector is
     * not necessary to make the widget function. You can use any class name you
     * want to style the ContentGroup container.
     */
    .TabbedPanelsContentGroup {
    	clear: both;
    	border-left: solid 1px #CCC;
    	border-bottom: solid 1px #CCC;
    	border-top: solid 1px #999;
    	border-right: solid 1px #999;
    	background-color: #EEE;
    }
     
    /* This is the selector for the Content panel. The Content panel holds the
     * content for a single tabbed panel. For our default style, this container
     * provides some padding, so that the content is not pushed up against the
     * widget borders.
     *
     * The name of the class ("TabbedPanelsContent") used in this selector is
     * not necessary to make the widget function. You can use any class name you
     * want to style the Content container.
     */
    .TabbedPanelsContent {
    	padding: 4px;
    }
     
    /* This selector is an example of how to change the appearnce of the currently
     * active container panel. The class "TabbedPanelsContentVisible" is
     * programatically added and removed from the content element as the panel
     * is activated/deactivated.
     */
    .TabbedPanelsContentVisible {
    }
     
    /* Vertical Tabbed Panels
     *
     * The following rules override some of the default rules above so that the
     * TabbedPanels widget renders with its tab buttons along the left side of
     * the currently active content panel.
     *
     * With the rules defined below, the only change that will have to be made
     * to switch a horizontal tabbed panels widget to a vertical tabbed panels
     * widget, is to use the "VTabbedPanels" class on the top-level widget
     * container element, instead of "TabbedPanels".
     */
     
    /* This selector floats the TabGroup so that the tab buttons it contains
     * render to the left of the active content panel. A border is drawn around
     * the group container to make it look like a list container.
     */
    .VTabbedPanels .TabbedPanelsTabGroup {
    	float: left;
    	width: 10em;
    	height: 20em;
    	background-color: #EEE;
    	position: relative;
    	border-top: solid 1px #999;
    	border-right: solid 1px #999;
    	border-left: solid 1px #CCC;
    	border-bottom: solid 1px #CCC;
    }
     
    /* This selector disables the float property that is placed on each tab button
     * by the default TabbedPanelsTab selector rule above. It also draws a bottom
     * border for the tab. The tab button will get its left and right border from
     * the TabGroup, and its top border from the TabGroup or tab button above it.
     */
    .VTabbedPanels .TabbedPanelsTab {
    	float: none;
    	margin: 0px;
    	border-top: none;
    	border-left: none;
    	border-right: none;
    }
     
    /* This selector disables the float property that is placed on each tab button
     * by the default TabbedPanelsTab selector rule above. It also draws a bottom
     * border for the tab. The tab button will get its left and right border from
     * the TabGroup, and its top border from the TabGroup or tab button above it.
     */
    .VTabbedPanels .TabbedPanelsTabSelected {
    	background-color: #EEE;
    	border-bottom: solid 1px #999;
    }
     
    /* This selector floats the content panels for the widget so that they
     * render to the right of the tabbed buttons.
     */
    .VTabbedPanels .TabbedPanelsContentGroup {
    	clear: none;
    	float: left;
    	padding: 0px;
    	width: 30em;
    	height: 20em;
    }

    Open in new window

    I've posted the changed portion of the CSS code, which meant changing the images to the sprites and adding a single line of CSS to move the background-image when the tab is selected. In essence you could easily add another state to this images to do the same for hover, just add another state to the sprite and add another background-position for "TabbedPanelsTabHover".

    I've also attached the two sprites that would be needed for this version, I tested this using the html you originally linked in one of your posts.
    /* This is the selector for the TabbedPanelsTab. This container houses
     * the title for the panel. This is also the tab "button" that the user clicks
     * on to activate the corresponding content panel so that it appears on top
     * of the other tabbed panels contained in the widget.
     *
     * For our default style, each tab is positioned relatively 1 pixel down from
     * where it wold normally render. This allows each tab to overlap the content
     * panel that renders below it. Each tab is rendered with a 1 pixel bottom
     * border that has a color that matches the top border of the current content
     * panel. This gives the appearance that the tab is being drawn behind the
     * content panel.
     *
     * The name of the class ("TabbedPanelsTab") used in this selector is not
     * necessary to make the widget function. You can use any class name you want
     * to style this tab container.
     */
    .TabbedPanelsTab {
    	}
     
    .TabbedPanelsTabEvent {
    	position: relative;
    	float: left;
    	list-style: none;
    	-moz-user-select: none;
    	-khtml-user-select: none;
    	cursor: pointer;
    	background-image: url(live-events-sprite.gif);
    	background-repeat: no-repeat;
    	background-position: 0 0;
    	height: 58px;
    	width: 130px;
    }
     
    .TabbedPanelsTabTrain {
    	position: relative;
    	float: left;
    	list-style: none;
    	-moz-user-select: none;
    	-khtml-user-select: none;
    	cursor: pointer;
    	background-image: url(training-networking-sprite.gif);
    	background-repeat: no-repeat;
    	background-position: 0 0;
    	height: 58px;
    	width: 177px;
    }
     
    /* This selector is an example of how to change the appearnce of a tab button
     * container as the mouse enters it. The class "TabbedPanelsTabHover" is
     * programatically added and removed from the tab element as the mouse enters
     * and exits the container.
     */
    .TabbedPanelsTabHover {
    }
     
    /* This selector is an example of how to change the appearance of a tab button
     * container after the user has clicked on it to activate a content panel.
     * The class "TabbedPanelsTabSelected" is programatically added and removed
     * from the tab element as the user clicks on the tab button containers in
     * the widget.
     *
     * As mentioned above, for our default style, tab buttons are positioned
     * 1 pixel down from where it would normally render. When the tab button is
     * selected, we change its bottom border to match the background color of the
     * content panel so that it looks like the tab is part of the content panel.
     */
    .TabbedPanelsTabSelected {
    	background-position: -256px 0;
    }

    Open in new window

    live-events-sprite.gif
    training-networking-sprite.gif