Replace HTML element with same id value - css

I am learning CSS recently and got across this requirement in my project. My HTML looks like this.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<div id="lvl1_nav">
<table border="0" cellpadding="0" cellspacing="1" width="100%">
<tbody>
<tr>
<td> </td>
</tr>
<tr>
<td id="leftheaderlogo" style="height: 25px !important;"
class="logoPadding" rowspan="2"></td>
<td width="25%"><span id="lvl1_nav_title"
style="font-weight: normal;">PRODUCT TITLE</span></td>
<td rowspan="2" width="75%">...</td>
</tr>
<tr>
<td width="25%"><span id="lvl1_nav_title"
style="cursor: default; font-weight: bold;">PRODUCT 2nd
Level Title</span></td>
</tr>
</tbody>
</table>
<select id="portalModuleGroups" class="modulemenu"
style="display: none;">
</select>
</div>
</body>
</html>
I dont have any option to use any other techniques other than CSS due to code limitations.
I am looking for the best options to replace the "PRODUCT TITLE" and "PRODUCT 2nd Level Title" using CSS. The main problem I am facing is, both the span's are having same id span id="lvl1_nav_title".
Is it possible?

Duplicate ID issue
Several others have pointed out the issue of the duplicate IDs. Yes, that makes your HTML non-conformant. Yes, bad things could happen. However, in practice it will work OK:
#lvl1_nav_title { color: purple; }
will apply the color to all the elements with that ID.
If it's possible to write JS, but for some reason not possible to change the multiple IDs, although you cannot address both elements with
document.getElementById('lvl1_nav_title')
because that just returns one element, you can address them with
document.querySelectorAll('[id=lvl1_nav_title]')
Cannot change HTML content with CSS
The basic roadblock you face is that you cannot change HTML content via CSS. Bottom line, you cannot do what you want without JS.
Therefore, at the end of the day, you really need to fix your HTML to have unique IDs, and in any case you'll have to use JS to replace text within the elements.
The ultimate hack with CSS
This is not recommended unless you absolutely, positively cannot touch the HTML or write JSS and must have a CSS-only solution.
The idea is to move the element way off to the edge of the screen, where it will be hidden. Then, apply an ::after pseudo-element providing the new text, positioned so it will be back where the the original element was supposed to be originally.
CSS:
span {
text-indent: -9999px;
display: block;
}
span::before {
position: relative;
top: 0;
left: 9999px;
}
span:first-child::before { content: 'NEW PRODUCT TITLE'; }
span:last-child::before { content: 'NEW 2nd LEVEL TITLE'; }
HTML:
<span id="lvl1_nav_title">PRODUCT TITLE</span>
<span id="lvl1_nav_title">PRODUCT 2nd Level Title</span>
Obviously, you will have to adjust things to work with your specific HTML structure, but this is the basic idea.

Related

How to only select a displayed element using CSS

In my program, I have a text element that displays in 2 different sections. It will display is section A, and again in section B (popup). I was hoping to create 1 object using CSS that could be used for both sections. That way I could call the same object to check this element regardless of where it is displayed. I can't seem to figure it out. Maybe its not possible, or maybe I need someone who has more experience with HTML and CSS to show me the light.
Here is the HTML for this element in section A when it is displayed
<td id="treeCol" valign="top" style="overflow: hidden; display: block;">
<div id="orgTreeAndSearch">
<div class="orgSelection">
<span id="selection" class="" title="Select an org unit">Select an org unit</span>
Here is the HTML for this element in section A when it is NOT displayed (hidden when section B is displayed)
<td id="treeCol" valign="top" style="overflow: hidden; display: none;">
<div id="orgTreeAndSearch">
<div class="orgSelection">
<span id="selection" class="" title="Select an org unit">Select an org unit</span>
Here is the HTML for this element in section B when it is displayed
<div class="blockUI blockMsg blockPage PopUp White" style="z-index: 1011; position: absolute; padding: 0px; margin: 0px; width: 1365px; top: 50px; left: 50px; text-align: left; color: rgb(0, 0, 0); border: 0px none; background-color: rgb(255, 255, 255);">
<div class="White" style="margin: 0px 20px 20px; display: block;">
<div class="PopUpClose" align="right">
<div>
<div align="center">
<table style="width: 100%;">
<tbody>
<tr>
<td valign="top" align="left" style="width: 410px;">
<div class="orgSelection">
<span id="dataAccessOrgSelection" class="">Select org unit(s)</span>
Here is the HTML for this element in section B when it is NOT displayed (hidden when section A is displayed)
<div class="White" style="margin: 0px 20px 20px; display: none;">
<div class="PopUpClose" align="right">
<div>
<div align="center">
<table style="width: 100%;">
<tbody>
<tr>
<td valign="top" align="left" style="width: 410px;">
<div class="orgSelection">
<span id="dataAccessOrgSelection" class="">Select org unit(s)</span>
To select the element in section A, I could use the ID and it will work
css=#selection
To select the element in section B, I could also use it's id and it will work
css=#dataAccessOrgSelection
I wanted to have 1 selector for this element, so I tried this. However, it selects both the displayed and hidden elements. So if I'm on section A, it will select the element for both A and B, even though B is hidden (and vice-versa)
div.orgSelection span[id]
Is there a way to have 1 selector for this element, that will only select the visible element? I could check for "display:none" in the style attribute, but I'm not sure how to do this when it is located in td for section A, and div for section B.
Okay, if I understand your question right, you need CSS selector valid for both A and B in visible state.
td#treeCol[style*=block] span#selection, div.PopUp>div[style*=block] span#dataAccessOrgSelection
A tiny explanation. Comma - is for logical OR in CSS selectors. Visible divs of yours have a part of their style attribute - block ([style*=block]). So for both selectors we find span with needed id being contained inside a visible div. If the sectors are not right enough, play with attributes a little more.
To be completely sure that your approach works, you should call the element location with this selector every time before checking its visibility to avoid StaleElementReferenceException, because, clearly, those elements are not the same
But, if I was you, I would check a specific logic and not the 'what if' case. You should know exactly when and what element should be visible.
As Alexander Petrovich mentioned, I would recommand to use to different element-selectors, because in my opinion, they are indeed different elements. In this case, you can find easy selectors with ids.
But if there's a valid reason for a one-selector-but-two-elements-constuct, you need to make clear, which parts of your dom may vary and which are stable. I'm not so firm with css, but I can give you some xpath expressions, if this helps:
//span[(#id='dataAccessOrgSelection') or (#id='selection')]
//span[#class='']
//span[contains(text(),'Select') and contains(text(),'org unit')]
//div[#class='orgSelection']/span
I guess you will be able to transform this xpath-selectors into css-selectors...maybe this pdf will help:
http://code.google.com/p/timger-book/source/browse/trunk/cheatsheet/Locators_table_1_0_2.pdf

Issue on setting tr Height on CSS

I am trying to set height for <tr> element of table as below but it is not working
.tsx tr { line-height: 20px; }
<table class="tsx">
<tr></tr>
Can you please let me know what I am doing wrong?
Tried your code and seems to be working fine. Try changing the line-height value. The value you are using (20px) may be equal to the default line-height value. Hence you may not be able to see the difference.
<html>
<head>
<style>
.tsx tr { line-height: 25px; }
</style>
</head>
<body>
<table class="tsx" border="1">
<tr>
<td>abc</td>
</tr>
</table>
</body>
</html>

How to change internal table properties

If I want to treat the properties of a table imbedded in a cell differently than the outer table, what is required. I am new to CSS and do not have a handle on the cascading effect. A boiled downed example of my attempt is as follows:
<body>
<table><link rel="stylesheet" type="text/css" href="OuterTable.css">
<tr><th>Col1</th><th>Col2</th></tr>
<tr>
<td>
<table><link rel="stylesheet" type="text/css" href="InnerTable.css"><tr><th>InsideColA1</th><th>InsideColA2</th></tr></table>
</td>
<td>
<table><tr><th>InsideColB1</th><th>InsideColB2</th></tr></table>
</td>
</tr>
</table>
</b
Where the OuterTable.css specifies a pink background for the cells and InnerTable.css specifies yellow for the cells. Obviosuly, I am missing something basic as all header styles have a yellow background. What is the best method for styling an internal table.
a) Add class(inner and outer as shown below) to your table
b) remove your CSS file from table and add to head
c) just add the below style statements to your css.
<style type="text/css">
table.outer {
background-color:yellow
}
table.outer th {
// add style properties here
}
table.inner {
background-color:pink
}
table.inner th {
// add style properties here
}
</style>
<table class="outer">
<tr><th>Col1</th><th>Col2</th></tr>
<tr>
<td>
<table class="inner"><tr><th>InsideColA1</th><th>InsideColA2</th></tr></table>
</td>
<td>
<table><tr><th>InsideColB1</th><th>InsideColB2</th></tr></table>
</td>
</tr>
</table>
First, don't import CSS at the middle of your HTML code, put it on the <head> tag please.
You can style your HTML elements by "id" or "class", I'll make and example using class, check it:
<head>
<link rel="stylesheet" type="text/css" href="OuterTable.css">
<link rel="stylesheet" type="text/css" href="InnerTable.css">
<style>
.outerTable{
background-color:#FF0000;
}
.innerTable{
background-color:#FF00FF;
}
</style>
</head>
<body>
<table class="outerTable">
<tr><th>Col1</th><th>Col2</th></tr>
<tr>
<td>
<table class="innerTable"><tr><th>InsideColA1</th><th>InsideColA2</th></tr></table>
</td>
<td>
<table><tr><th>InsideColB1</th><th>InsideColB2</th></tr></table>
</td>
</tr>
</table>
</body>
Instead the class at <style> tag, you put your code at your .css files
see it working at: http://jsfiddle.net/U5cUK/
First off, all CSS files should be included in the <head> of your HTML document.
Now, if you want to target a nested table, all you have to do is use a descendant selector like this:
/*Define default color for cells*/
table th{
background-color: pink;
}
/*Override for headers inside a nested table*/
table table th{
background-color: yellow;
}
No need for a separate CSS file or custom classes or ids
See Demo fiddle

Arranging elements within generated table

The selectOneRadio element in JSF is translated to a table, where the radio button and its label are put within the same <td> in a table.
<!-- JSF Element -->
<h:selectOneRadio id="types" label="Type"
value="#{bean.selectedType}"
layout="pageDirection">
<f:selectItems value="#{bean.types}"/>
</h:selectOneRadio>
<!-- Generated HTML -->
<table id="j_id_i:types">
<tbody>
<tr>
<td>
<input id="j_id_i:types:0" type="radio" value="VALUE1"
name="j_id_i:types"/>
<label for="j_id_i:types:0"> Value #1</label>
</td>
</tr>
<tr>...</tr>
...
</tbody>
</table>
Before I was using Bootstrap, the elements within the <td> would appear side by side, but now look under each other.
The processed CSS for the element is the following, as given by Firebug.
table {
border-collapse: collapse;
border-spacing: 0;
}
body {
color: #333333;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
line-height: 20px;
}
html {
font-size: 100%;
}
I have no clue what may be producing such behaviour. It's not a concern of width, as this is the single element within the <div>, and without bootstrap it is rendering side by side.
That's because the <label> has due to the Bootstrap CSS become a HTML block element which starts naturally at a new line.
You need to make it a HTML inline element again. So, you need to override the Bootstrap CSS accordingly. Perhaps you want to apply this for labels in table cells only. E.g.
td label {
display: inline;
}

Container div width problem

Can anybody tell me why the outer div is not expanding to the page width? Is there any solution for this without removing the doctype declaration(If I remove doctype, it is expanding) ? Also my page is in js disabled mode.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1 /DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Untitled Document</title>
</head>
<body>
<div style="border:1px solid #ff0000;">
<div>
<table class="storeList">
<thead>
<tr>
<th>
Country Code
</th>
<th>
Store ID
</th>
<th>
Store Name
</th>
<th>
TownName
</th>
<th class="actions">
Store Operation
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
TEST
</td>
<td>
TEST
</td>
<td>
hghjgdkjvhkjhvhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhjjjjjjjjjjjjjjjjjjjjhghjgdkjvhkjhvhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhjjjjjjjjjjjjjjjjjjjjdhgfdhf
</td>
<td>
TEST
</td>
<td class="actions">
TEST ACTIONS
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
This answer works, promise!
To your outermost div (<div style="border:1px solid #ff0000;">), add either:
float: left, or;
display: inline-block.
If you would like to see demos of these two fixes, check these older answers I provided:
How to fix table going outside of div tag in IE6 & 7?
Expand a div width to the width of the sibling table which has a lot of rows and causes vertical scroll
It would probably be because browsers apply their own default style, which include margins and padding on various elements. The body tag probably has default padding so you'd need to add a "reset CSS" file to your page to reset these defaults or just try:
<style type="text/css">
* {
margin: 0;
padding: 0;
}
</style>
In the head of your page. Also, just to note, it looks like you're using tables for layout. This is a big no no in todays modern world of CSS:
http://www.hotdesign.com/seybold/
http://www.mardiros.net/css-layout.html
Why not use tables for layout in HTML?
You can also set your table to 100% width to cover the area provided by the div
table { width: 100%; }

Resources