Using Multiple Classes

I have two groups of Radio Buttons which are all but identical, except that one is a 5-point Scale and the other a 10-point Scale, so I need different padding for each.

Currently, I just made a copy of my code like this…


	// LIKERT 5-POINT QUESTION.
	case 'LIKERT-5':
		echo "<li>
				<fieldset class='radioLikert5'>
				<legend>$articleSurveyQuestionID.) $questionStem</legend>


	// LIKERT 10-POINT QUESTION.
	case 'LIKERT-10':
		echo "<li>
				<fieldset class='radioLikert10'>
				<legend>$articleSurveyQuestionID.) $questionStem</legend>

And so I have two nearly identical sets of Styles called “radioLikert5” and “radioLikert10” which seems silly.

Is there a way to create a global style called “radioGroup” which applies to both blocks of code, but then create another style called “Likert10” which I can “AND” to the main style so that I get all of style #1 plus the slight change of style #2??

(I tried this but it didn’t work?!)

If I get “fancy” here, I want to be sure that I have solid Browser support for everything except maybe IE6, as I hate using fancy code which isn’t well supported!!

Also, I am using only HTML4…

Is there an easy way to clean things up? :-/

Thanks,

Debbie

Why not just have a style for “radioLikert” that contains all the common styles, and then have styles specific to each different kind, like widths and paddings?

So you’d end up with

<fieldset class='radioLikert five'>

<fieldset class='radioLikert ten'>

I’m not seeing how to apply that to my case.

Here is some more code for my 5-Point Question…


	// LIKERT 5-POINT QUESTION.
	case 'LIKERT-5':
		$surveyItem =
					"<li>
						<fieldset class='radioLikert'>
							<legend>$questionNo.) $questionStem</legend>
							<table cellspacing='1'>
								<tbody>
									<tr>
										<td>
											<input id='Question" . $articleSurveyQuestionID . "_Opt1' name='responseToQuestion[" . $articleSurveyQuestionID . "]' type='radio' value='1' />
											<label for='Question" . $articleSurveyQuestionID . "_Opt1'>1<span>$labelLower</span></label>
										</td>

										<td>
											<input id='Question" . $articleSurveyQuestionID . "_Opt2' name='responseToQuestion[" . $articleSurveyQuestionID . "]' type='radio' value='2' />
											<label for='Question" . $articleSurveyQuestionID . "_Opt2'>2</label>
										</td>

										and so on...
									</tr>
								</tbody>
							</table>
						</fieldset>
					</li>";
		return $surveyItem;
		break;

The code for the 10-Point Question would be identical, just more Radio Buttons.

And here are my styles for the 5-Point Question…


/* LIKERT Question */
#rateThisArticle .radioLikert{
	padding: 0;
	border: none;
}

#rateThisArticle .radioLikert table{
	margin: 0 0 0 25px;
}

#rateThisArticle .radioLikert td{
	width: 60px;
	vertical-align: top;
	border: none;
}

#rateThisArticle .radioLikert td label{
	display: block;
	margin: 0;
	padding: 0;
	font-size: 0.9em;
	line-height: 1.4em;
	font-weight: bold;
}

#rateThisArticle .radioLikert td label span{
	display: block;
	margin: 0;
	padding: 0;
	font-size: 0.9em;
	line-height: 1.4em;
}

The styles for the 10-Point Question would be the same except for this…


#rateThisArticle .radioLikert10 td{
	width: 50px;
	vertical-align: top;
	border: none;
}

Sorry for being dense, Ralph, but can you please help me “connect the dots” here? (:

Thanks,

Debbie

Hope you don’t mind if I take a shot at this.

Using the example you provided, the width of the <td> element is the only property that is different between a 5 point question and a 10 point question.

Door number 1 …

Ralph’s suggestion is easy to implement and uses what you have already done to your advantage. I think he directly address what you are trying to do. He says to code the common properties for both Likerts, which you have already done; and then to assign the differentiators to separate classes, as in the following example:


/* LIKERT Question */

#rateThisArticle .radioLikert {
	padding: 0;
	border: none;
}

#rateThisArticle .radioLikert table {
	margin: 0 0 0 25px;
}

#rateThisArticle .radioLikert td {        /* notice that the width property has been deleted */
	vertical-align: top;
	border: none;
}

#rateThisArticle .radioLikert td label {
	display: block;
	margin: 0;
	padding: 0;
	font-size: 0.9em;
	line-height: 1.4em;
	font-weight: bold;
}

#rateThisArticle .radioLikert td label span {
	display: block;
	margin: 0;
	padding: 0;
	font-size: 0.9em;
	line-height: 1.4em;
}

#rateThisArticle .five td {       /* the width for a 5 point question is added via this class */
	width: 60px;
}

#rateThisArticle .ten td {       /* the width for a 10 point question is added via this class */
	width: 50px;
}

That method requires three classes, and there will ALWAYS be two classes used for each question in the markup, as shown in Ralph’s example. Think of them as the primary class with the common descriptors for both groups (.radioLikert) and the secondary classes with unique properties that describe a five or ten question group (.five and .ten). Efficient.

The HTML would contain class=“radioLikert five” or class=“radioLikert ten”

Door number 2 …

This is another method of accomplishing the same thing. The css isn’t as clean looking but the html only requires one class. Assign 2 unique selectors to all common property groups. Then apply unique properties to differentiate the individual selectors. (I think this is the method you didn’t care for.)


/* LIKERT Question */

#rateThisArticle .radioLikert5,
#rateThisArticle .radioLikert10 {
	padding: 0;
	border: none;
}

#rateThisArticle .radioLikert5 table,
#rateThisArticle .radioLikert10 table {
	margin: 0 0 0 25px;
}

#rateThisArticle .radioLikert5 td,
#rateThisArticle .radioLikert10 td {        /* notice that the width property has been deleted */
	vertical-align: top;
	border: none;
}

#rateThisArticle .radioLikert5 td label,
#rateThisArticle .radioLikert10 td label {
	display: block;
	margin: 0;
	padding: 0;
	font-size: 0.9em;
	line-height: 1.4em;
	font-weight: bold;
}

#rateThisArticle .radioLikert5 td label span,
#rateThisArticle .radioLikert10 td label span {
	display: block;
	margin: 0;
	padding: 0;
	font-size: 0.9em;
	line-height: 1.4em;
}

#rateThisArticle .radioLikert5 td {        /* the width for the 5 point question is added here */
	width: 60px;
}

#rateThisArticle .radioLikert10 td {       /* the width for the 10 point question is added here */
	width: 50px;
}

The HTML will contain class=“radioLikert5” or class=“radioLikert10”

I don’t know what fieldsets are, but I think that’s where these classes would be applied in your code.

Food for thought intended to help connect the dots.

Thanks for the examples.

I think I get it, but this code still seems un-intuitive to me…


#rateThisArticle .radioLikert td {        /* notice that the width property has been deleted */
	vertical-align: top;
	border: none;
}


#rateThisArticle .five td {       /* the width for a 5 point question is added via this class */
	width: 60px;
}

#rateThisArticle .ten td {       /* the width for a 10 point question is added via this class */
	width: 50px;
}

I guess I have to sleep on this and look at it again tomorrow.

It just seems like those two styles would conflict/over-write each other?! :-/

To me, they look like 3 unique styles, but I guess my browser is smart enough to merge them together so that…


#rateThisArticle .radioLikert td{
}

and


#rateThisArticle .five td{
}

become this…


#rateThisArticle .radioLikert .five td{
}

BTW, I made the changes you and Ralph suggested and things seems to be working, but I still need to let it sink in.

Thanks!!

Debbie

No, not at all. They specifically apply to a single element. This is what CSS is designed for, and the browsers well knows it. It’s like the element has a specific name. If I say “Debbie, go to be”, no one else is going to think I’m talking to them.

Your analogy isn’t the best.

In the code below…


<form id="rateThisArticle" action="" method="post">
	<fieldset class='optionLikert scale10Point'>
		<legend>6.) Overall, how would you rate this article?</legend>
		<table cellspacing='1'>
			<tbody>
				<tr>
					<td>
						<input id='Question6_Opt1' name='responseToQuestion[6]' type='radio' value='1' />
						<label for='Question6_Opt1'>1<span>Poor<br />Article</span></label>
					</td>


#rateThisArticle .optionLikert td{
	vertical-align: top;
	border: none;
}

#rateThisArticle .scale10Point td{
	width: 45px;
}

…I would expect browsers to treat optionLikert scale10Point as an “AND” condition.

Apparently, browsers treat…


	<fieldset class='optionLikert scale10Point'>

…as optionLikert OR scale10Point OR optionLikert scale10Point

Debbie

Indeed, you just have to know how browsers are designed to read CSS. Any of those classes that relate to the element will be applied—so it’s very much an OR situtation … or EITHER/OR, so to speak. You can force them only to take effect if both apply by chaining them in the style sheet:

.optionLikert.scale10Point {
  [I]styles go here[/I]
}

But that’s not what you want here.

How well is each concept (i.e. OR’ing and AND’ing) supported by browsers?

Debbie

I think they can be a tad dodgy in IE6, but fine otherwise.

When I start thinking in “logical” terms, I sometimes put my foot in my mouth.

That said, I think Debbie’s expectation that the two classes should behave as an AND situation is essentially correct.

Either class alone will certainly apply, and both classes together should be ANDed and both should be applied since the properties are different. Or so I believe. If that’s not happening or if there are browser specific exceptions, I’d like to learn why.

Debbie, can you please give a good example where this does not seem to be working as expected?

The ability to apply multiple classes to an element is extremely handy. Indeed, it’s saying “apply this style AND this style”, but it’s not a condition or anything.

Either class alone will certainly apply, and both classes together should be ANDed and both should be applied since the properties are different. Or so I believe.

Indeed, yes, that’s how it works … except perhaps in some buggy IE6 situations. I have a vague memory that in some circumstances IE6 would only apply the first class, but I may be confusing that with class chaining in the actual style sheet: e.g.


.optionLikert.scale10Point {
  [I]apply these styles on any element that has both the class .optionLinkert AND scale10Point[/I]
}

Multiple classes within one attribute

It is possible to add more than one class to an HTML element. For example, you can add two classes to an <li> element like this:

<li class=“page-1 current-page”><a href=“#”>Home</a></li>

The two classes are written within the same attribute, with spaces separating each class.