I have two sets of text that need to be inline with each other but at the moment one is placed higher than the other. The two sets of text share the same CSS code so when I edit it, both are affected. However, I would like to target only one of the text; Is there a way of doing this?
Here is the HTML and CSS:
<div id="mi-slider" class="mi-slider">
<?
$result = $mysqli->query("SELECT * FROM stock");
while($obj = $result->fetch_object())
{
if($obj->id&1)
echo "<ul>";
?>
<li class="<?=$obj->orientation=='landscape'?'landscape':'portrait'?>" id="list">
<img src="./img/<?=$obj->description=='unframed'?$obj->poster_no:$obj->poster_no.'_frame'?>.jpg" alt="">
<h4><?= $obj->description=="unframed"?"Unframed Poster - 750mm x 500mm":"Framed Poster - 790mm x 540mm"?><br />£<?=$obj->price?> each</h4>
</li>
The CSS code:
.mi-slider ul li h4 {
display: inline-block;
font-family: HelveticaNeueRegular;
font-weight: 100;
font-size: 12px;
color: #a34235;
padding: 0 0 0;
text-align: left;
margin-top: 20px;
margin-left: 10px;
float: left;
}
you can use unique ID for each special element, then specify your CSS via '#' selector.
if the special CSS need to be applied to the first element,
consider using the ':first-child' selector. its cleaner.
but, if you want to target the second element (or later) consider that the 'nth-child' selector is not suported in older browser (like IE8)
If you want to target the second list items H4, you can use the nth-child selector, as below:
.mi-slider ul li:nth-child(2) h4
{ your css }
Use this:
li:first-child h4
{
your custum css
}
With this, the CSS rules only apply to the h4 tag of first li instead of all li.
Related
TL;DR - See Adam's answer (accepted) or Update #5 in my
question for the current solution. My question shows my journey
getting to that solution in a rather long but explanatory way,
describing pitfalls and limitations.
I am creating a module that adds glossary term descriptions to the respective words used in a text. Everything works fine with plain text descriptions. For example, if there is a description for onomasticon (Another word for thesaurus), the following HTML
<p>An onomasticon is not a dinosaur.</p>
gets converted to
<p>An <dfn title="Another word for thesaurus">onomasticon</dfn> is not a dinosaur.</p>
Since the content (both article text and glossary term descriptions) come out of a CMS which allows the user to use HTML, the term's description may contain HTML, e.g. Another word for <strong>thesaurus</strong>. Using the above technique, this starts to get messy:
<p>An <dfn title="Another word for <strong>thesaurus</strong>">onomasticon</dfn> is not a dinosaur.</p>
This is by default since tag attributes may not contain tags themselves. This limitation can be bypassed by adding an additional element inside the dfn tag and adding some CSS to hide the element initially:
dfn span {
display: none;
}
dfn:hover span {
display: block;
position: absolute;
top: 2.2em;
background: #ccc;
}
<p>An <dfn><span>Another word for <strong>thesaurus</strong></span>onomasticon</dfn> is not a dinosaur.</p>
But now comes the part, I am failing to overcome. HTML tags like <strong> are inline elements which do not pose a problem. However, if the term's description contains a block element, this fails, e.g. if the description itself is contained in a <p> tag:
dfn span {
display: none;
}
dfn:hover span {
display: block;
position: absolute;
top: 2.2em;
background: #ccc;
}
<p>An <dfn><span><p>Another word for <strong>thesaurus</strong></p></span>onomasticon</dfn> is not a dinosaur.</p>
What happens here? Well, since block elements are not allowed inside most inline elements, the outer inline element is getting terminated and the inner block element is placed right after. Thus, the CSS selectors are not working anymore, plus you'll end up with extra line breaks. Of course, one might think of adding something like dfn span p { display: inline-block; } but this doesn't work either (neither does inline), it's invalid HTML5.
Although semantically incorrect, I tried to turn <dfn> into <div class="dfn"> and the inside <span> to a <div> as well since dfn, abbr and cite elements may only contain phrasing context as well (just as span). This fails again due to <div> not being allowed inside <p>, again an unwanted line-break is added:
.dfn > div {
display: none;
}
.dfn:hover div {
display: inline-block;
position: absolute;
top: 2.2em;
background: #ccc;
}
<p>An <div class="dfn"><div><p>Another word for <strong>thesaurus</strong></p></div>onomasticon</div> is not a dinosaur.</p>
That has been the summary of my journey so far, trying to reach the holy grail of adding a tooltip - containing HTML - to an inline element - such as <dfn>, <abbr> or <cite> - using CSS only.
Before I now look into javascript-based solutions, my question is whether or not I missed an option which fulfils my requirements as listed below?
CSS only
tooltip must be added to <dfn>, <abbr> or <cite> inside a paragraph
tooltip content may contain the following HTML tags: div, p, h2, img, figure, ul, ol, li
Update 1: Since I wrote the module (PHP), I am of course able to manipulate the term's description. However, I don't just want to strip all <p> tags but try to keep the intended markup.
Update 2: I found a rather crude solution. Let's say the description for onomasticon is some HTML snippet like:
<p>Another word for <strong>thesaurus</strong></p>
<p><img src="thesaurus.png" /></p>
My module will now convert all block elements to spans with appropriate class names, so the description becomes
<span class="p">Another word for <strong>thesaurus</strong></span>
<span class="p"><img src="thesaurus.png" /></span>
This way, I have inline elements which shouldn't break the phrasing context. Adding some more CSS to style the tooltip and make span.p behave somewhat like a p again, it all ends up to this.
dfn {
display: inline-block;
position: relative;
}
dfn > span {
display: none;
}
dfn:hover > span {
display: block;
position: absolute;
top: calc(1em + 5px);
max-width: 20em;
background: #ccc;
padding: .5em;
}
dfn img {
max-width: 12em;
}
dfn > span span.p {
display: block;
margin-bottom: .5em;
}
<p>An <dfn><span><span class="p">Another word for <strong>thesaurus</strong></span>
<span class="p"><img src="http://i.imgur.com/G0bl4k7.png" /></span></span></span>onomasticon</dfn> is not a dinosaur.</p>
This is my best looking option so far supporting limited HTML for inline element's tooltips. However, it's probably not the best option since it requires the hacky rewrite of HTML block elements.
Update 3: ChristianF's answer had a very important clue how to preserve HTML in glossary term definitions. If the description is not an element inside the dfn tag but a following sibling, we could still hide and show it, e.g. with the CSS selector dfn + div.dfn-tooltip. However, since most glossary terms will be found in a phrasing context, this will again break the layout, since divs are not permitted inside a paragraph.
So we would need an element, that can be both used in a phrasing context and contain block elements. According to this beautiful HTML structure diagram, the <button> tag would be the only suitable one.
p {
display: relative;
}
dfn + .dfn-tooltip {
display: none;
}
dfn:hover + .dfn-tooltip {
display: block;
position: absolute;
top: 3em;
max-width: 20em;
background: #ccc;
padding: .5em;
border: none;
}
.dfn-tooltip img {
max-width: 12em;
}
<p>An <dfn>onomasticon</dfn><button class="dfn-tooltip"><p>Another word for <strong>thesaurus</strong></p><p><img src="http://i.imgur.com/G0bl4k7.png" /></p></button> is not a dinosaur.</p>
This looks pretty promising. Of course, there are two major drawbacks: (1) a button element at this place is semantically incorrect and (2) the tooltip doesn't stay open when hovering itself since it's not a child of the dfn tag anymore.
Update 4: Taking one little step further to avoid the second drawback is to simply move the button element back into the dfn tag, since the context is the same.
dfn {
position: relative;
display: inline-block;
}
dfn > .dfn-tooltip {
display: none;
}
dfn:hover > .dfn-tooltip {
display: block;
position: absolute;
top: calc(1em + 5px);
max-width: 20em;
background: #ccc;
padding: .5em;
border: none;
}
.dfn-tooltip img {
max-width: 12em;
}
<p>An <dfn>onomasticon<button class="dfn-tooltip"><p>Another word for <strong>thesaurus</strong></p><p><img src="http://i.imgur.com/G0bl4k7.png" /></p></button></dfn> is not a dinosaur.</p>
Update 5 (final): Adam's answer brought up some nice technique to incorporate the title attribute's original intention, putting everything together, this is what I ended up with.
dfn {
position: relative;
display: inline-block;
cursor: help;
}
dfn:before {
content: attr(title);
}
dfn > .dfn-tooltip {
display: none;
}
dfn:hover > .dfn-tooltip {
display: block;
position: absolute;
top: calc(1em + 5px);
max-width: 20em;
background: #ccc;
padding: .5em;
border: none;
cursor: help;
}
.dfn-tooltip img {
max-width: 12em;
}
<p>An <dfn title="onomasticon"><button disabled class="dfn-tooltip"><p>Another word for <strong>thesaurus</strong></p><p><img src="http://i.imgur.com/G0bl4k7.png" /></p></button></dfn> is not a dinosaur.</p>
By the way, if anyone is interested, I am using this in a module called Onomasticon, which provides a basic glossary functionality for Drupal 8.
Note that W3C says :
Defining term: If the dfn element has a title attribute, then the exact value of that attribute is the term being defined.
Accordingly, you can have a simple solution where you put the term being defined inside the title attribute, and the definition inside
dfn::before {content: attr(title);padding: 0 0 1em;}
dfn button {display: none; position: absolute}
dfn:hover button, dfn:focus button {display: block;}
<p>An
<dfn title="onomasticon" tabindex="0"><button disabled>
<p>Another word for <strong>thesaurus</strong></p>
<p><img src="http://i.imgur.com/G0bl4k7.png" /></p>
</button></dfn> is not a dinosaur.
</p>
I do not find any tag that can replace here the button element which seems to be the only one working here.
So we have to add the disabled attribute to the button element to disable its button behavior (focus) and set the tabindex on the dfn element to enable arrow navigation.
As already established in the comments, the easiest way to do this is by simply replacing the p tags with something else. This requires the least amount of workaround, and thus the approach least likely to break.
The quickest is simply replacing the opening p tag with two br tags, and the closing with an empty string. That way you'll get a visible empty line between the two text blocks, similar to what a paragraph break would normally give you. Most of the time this is enough to give the illusion of a paragraph break.
Another solution is, as you've found, to replace them with span-tags and style these to behave exactly like a normal P-tag. This requires a bit more code and work, but has the benefit of behaving, well... Exactly like the paragraphs on your site, creating a perfect illusion of there actually being a paragraph break there.
This is the method I'd use if the paragraphs have been styled in an unusual manner, so a simple empty line would not be sufficient to create the illusion. For example when the first line is indented, special styling for the first character or so forth.
In your case, I think a simple double br would suffice. Seeing as you only have a .5em bottom margin on paragraphs.
Edit, added:
In light of your comment to my answer, I have one more idea. That is to create a hidden div, and store the comment in this one. Giving it an ID that corresponds to a rel attribute of the dfn tag. Then, using CSS and JS, style the DIV as a tooltip upon hover. Will require a bit more work, but it will allow you to preserve all formatting and tags without issues.
For those who don't support the necessary features, you could use a trimmed down version inside the title tag. Then use the same JS to suppress it when showing the "enhanced" tooltip.
But yeah, you're most certainly looking at using JS here. Unless you can make do with the CSS3 adjacent sibling selector
I used the object tag. It makes more sense to me because you include the info in your text.
dfn {
position: relative;
display: inline-block;
}
dfn > .dfn-tooltip {
display: none;
}
dfn:hover > .dfn-tooltip,
.dfn-tooltip:hover {
display: block;
position: absolute;
top: calc(1em + 4px);
max-width: auto;
background: #ccc;
padding: .5em;
border: none;
}
.dfn-tooltip span {
max-width: 12em;
float: left;
}
.dfn-tooltip img {
max-width: 12em;
float: left;
clear: both;
}
<p>An <dfn>onomasticon
<object class="dfn-tooltip">
<p>Another word for <strong>thesaurus</strong></p>
<p><img src="http://i.imgur.com/G0bl4k7.png" /></p>
</object>
</dfn> is not a dinosaur.
</p>
Another solution worth looking into would be to use pure css, in combination with just the element. Forget about the title, or add it plain.
If you can afford to generate and use inline css, and inject it into the head before the output gets served, then how about:
The <abbr id="abbr_1" title="Fox is an animal">fox</abbr>. Another <abbr id="abbr_2">word</abbr>
abbr
{
display: none;
position: absolute;
z-index: 1; //probably not required, but I hope the title won't show up above it.... I guess it won't.
}
abbr:hover{display: block;}
#abbr_1:before{
content: '<p>Fox is a <i class="">beautiful</i> \'animal\'</p>'
}
...etc
Just don't forget escaping the single quotes ;)
thanks for assisting.
I'm having an issue in which my DIV class named box-2 is only applying itself to the title of the section, even though I closed it around the entire code. I'm very new to PHP, so I'm wondering if there is something I'm overlooking.
<div class="box-2 shadow">
<?php if (get_field('highlights')) { //Sub speciality ?>
<div itemprop="Restuarant Highlights">
<h3 class="content-title">Highlights</h3>
<ul>
<?php $terms = get_field('highlights'); ?>
<?php foreach ($terms as $term){ ?>
<li><div class="sl-highlights"><span class="icon-ok-circled"><?php echo $term->name; ?></span></div></li>
<?php } ?>
</ul>
</div>
</div>
<div class="clearboth"></div>
<?php } ?>
I need the box-2 class to be applied to everything, as it spaces out the entire section for me.
EDIT: This pulls the data from a taxonomy, and displays it like:
Bananas Apples Pears Lemons Grapes
Peaches Strawberrys
Here is the CSS:
.box-2 {
width: 100%;
border-top: 1px solid rgba(0,0,0,.05);
margin-bottom: 7px;
padding: 12px 0 3px 0;
}
.sl-highlights {
float: left;
margin-right: 4%;
font-size: 14px;
min-width: 135px;
line-height: 25px;
}
.content-title {
font-size: 18px;
color: #444;
padding-bottom: 9px;
font-weight: bold;
font-family: 'HelveticaNeue','Helvetica Neue',Helvetica,Arial,sans-serif;
}
Thank you very much for any and all help!
Anytime you apply a float style to an element, you remove it from the normal document flow; basically, the element doesn't reserve the space it normally would. Since that's what normally defines the height of it's container, the container tends to collapse to the height of the next element that is in the normal flow.
In your case, since all of the elements that have content are floated, box-2 collapses to a zero height. If you want it to still contain the floated elements, add an overflow: auto; rule to .box-2.
You can simplify your markup a bit by eliminating the <div> elements that currently have the sl-highlights class and instead apply the class to the <li> elements. I'd probably add a display: block rule too, since technically it's invalid to have a block-level element (the <h3> tags) inside an inline element (the <li> element).
I am using a bunch of divs (created with PHP) to generate a block of clickable elements. What I need to do is apply some styles to these generic elements, rather than to specific ones, yet using the code below seems to be invalid.
#Container {
height: 80%;
width: 60%;
background-color: green;
}
#Container div:hover {
background-color: blue;
}
<div id="Container">
<div style="background-color: red; width: 100px; height: 100px;">
</div>
http://jsfiddle.net/XD2eZ/
So I am not sure if it is an issue that a generic div element cannot be styled as a sub-element AND have a :hover attribute that operates properly. I know that classes or id's can be specified to handle this, but have thousands of unique divs. I also cannot use
#Container:hover div{ background-color: blue;}
As it ALSO seems to be invalid, but I need to select the one element from a block, and not all at once.
Any ideas here? Thanks in advance.
This will work if you remove the background color from the HTML, and apply it using css:
#Container {
height: 80%;
width: 60%;
background-color: green;
}
#Container div {background-color: red;}
#Container div:hover {
background-color: blue;
}
Example: http://jsfiddle.net/XD2eZ/1/
The reasone is CSS Specificity - a style attribute rule is much more specific (stronger) than an ID + element rule.
.hi guys, i have a little problem on styling my menu bar. i have the following code:
#can_header {
width:1024px;
height:140px;
background-color:#8D96A8;
}
#can_header ul{
list-style-type:none;
margin: 0;
padding: 110px 0 0 550px;
font-family: adolph;
text-transform: uppercase;
font-size: 1em;
}
#can_header li{
display:inline-block;
line-height: 15px;
border-right: 2px solid #CCC;
}
#can_header li#item-104{
border-right: none;
}
#can_header ul a:visited{
color:#CCC;
text-decoration:none;
margin-right:15px;
margin-left:15px;
}
#can_header ul a:link{
color:#CCC;
text-decoration:none;
margin-right:15px;
margin-left:15px;
}
#can_header ul a:hover{
color:#EB1886;
}
#can_header ul a:active{
color:#FFFFFF;
}
what i want to do is that when i click one of the links on my ul the color of the selected link will permanently change while on the page of the link. with my present code the color of the link only changes while on-click.. but when the page changes the color will be back to normal. TIA! More Power!
.By the way I'm using Joomla, i'm just editing the CSS of the template that i made.
I'm afraid what you want to do isn't possible with CSS only. What you can do is create a css class that indicate that an item in your menu is selected and assign that class to your li element either using javascript or server side when you render the template
You can't do that with CSS alone, you need to add some class to the selected link (ie class="selected") using Javascript or PHP.
Then you can add a style rule for links with class .selected.
Their right you can't do that with CSS alone. You can use :active and change the text-color, or whatever, while it is being clicked down (aka onmousedown) but you can't have it change like blue + click = red.
JQuery should be able to help you with this though.
This will be handled by the menu module you are using to display the menu. Most modules have the option to turn on active highlighting which basically does what everyone is talking about, adds a CSS class to the active menu item. Chances are all you need to do is turn on the active highlighting on and add the appropriate CSS.
Also, I noticed you are turning off a right border in one of the menu items by using the itemID. You would be better off using the :lastchild psuedo selector in case you ever change the order of your menu items or remove the one you have chosen to be last.
Instead of #can_header li#item-104 use #can_header li:last-child
You should add css class programmatically to child object based on requested page.
An Example with php:
function GetFileName()
{
$currentFile = basename($_SERVER["PHP_SELF"]);
$parts = Explode('.', $currentFile);
return $parts[0];
}
$basename = GetFileName();
<li>
<a href="index.php" <?php if($basename =="index") echo "class='current'"; ?>>Home</a>
</li>
<li>
<a href="about.php" <?php if($basename =="about") echo "class='current'"; ?>>About</a>
</li>
My Website
On the link above you can see that I have a CSS drop down menu in my site. It works fine, however, I want the top level items to stay highlighted when I'm on the page they represent.
I have this so far but it won't work (I'm only showing one menu item which doesn't have any sub menus as it saves space)
Here's the HTML:
<ul>
<li><h2><a name="donate" id="donate" href="index2.php?op=Donate">Donate</a></h2></li>
</ul>
Here's the CSS that colours the background:
#menu a {
color: #000;
background: #efefef;
text-decoration: none;
}
The content of each page is determined by the value of $head: $head = $_GET['op'];
I tried to implement the change by placing this straight after the menu:
if($head == "Donate") {
echo '<style>
#menu a donate {
color: #000;
background: #fff;
text-decoration: none;
</style>';
}
When I leave 'donate' out of the above code: '#menu a {' the background color of all the menu items changes to white, but I need to change the 'donate' button specifically. I tried doing this by adding id="donate" / name="donate" to the menu item (as seen above), and then calling it in css with '#menu a donate {'. but that is obviously wrong as it doesn't work! What should I do?
I think you need to use
if($head == "Donate") {
echo '<style>
#menu a#donate {
color: #000;
background: #fff;
text-decoration: none;
}
</style>';
}
as a selector instead, because donate is an id for the a tag, therefore it comes immediately after the a tag (no spaces) with a "#" in front.
You were also missing a "}" closing bracket for the css declaration.
OK, quick and dirty answer : your CSS selector wont work, because right now it search for a tag "donate" inside a "a" tag inside a tag with the id "menu". I assume all your link have a specific Id, so the easy way to do it is to use this selector
#donate
{
color: #000;
background: #fff;
text-decoration: none;
}
As an added bonus, this selector will be faster to parse by the browser.
By the way, you seem not to close the style tag. Is that an error?
Now, for a longer answer, it is not exactly the best way to do it. I suggest you create a CSS class with a name like "currentpage" and to use it like this in your menu
<li><h2><a <?php if($head == "Donate") echo 'class="currentpage"'; ?> id="donate" href="index2.php?op=Donate">Donate</a></h2></li>
That way you can keep your style in the stylesheet where it will be easier to maintain. Now of course, if all your menu tags are handcoded, you may find it pretty tedious to add the condition in everytag. If it's indeed the case, I suggest you create your menu using a loop.
By the way, you should remove the name attribute in the a tag, its a deprecated feature. id does the job just fine.
In this kind of situations, you will generally use a CSS class for the currently highlighted item :
<a href="..." class="highlight" ...>Current item </a>
<a href="..." ...>not current item</a>
This way, you won't change the id nor name nor anything else -- but just :
When an item is highlighted, add the css class
And when an item is un-highlighted, remove the css class.
That class can be added from Javascript, if necessary -- but it can also be generated from PHP, using something like this :
<a href="..." <?php if ($current=='item1') {echo 'class="highlight"';} ?> ...>Current item </a>
<a href="..." <?php if ($current=='item2') {echo 'class="highlight"';} ?>...>not current item</a>
usgin css you can try like this:
#menu a:active {
color: #000;
background: red:
text-decoration: none;
}
using jquery this can be done as following:
First create a css like below:
.active {
color: #000;
background: red:
text-decoration: none;
}
then write jquery code:
$('#menu a').click(function(){
$('#menu ul li h2').find('a.active').removeClass('active');
$(this).addClass('active');
});
You should set a class for the current page item using php, and use css to set rules for that class.