I have a div that is encased in an html <a> tag, so clicking anywhere on that box will lead the user to a new location.
I would like to add one button inside that box that leads somewhere else (a more specific location than the encasing div's link.
At the moment, adding that second <a> tag inside my div closes the original <a>, which makes sense as I guess these tags cannot be nested. How can I accomplish this 'nested' link problem?
Update
I need to build a rel attribute because it toggles an expanding section in the outer div.
My current code:
<a class="toggle" rel="toggle[<%= "#{user.id}" -%>]">
<div>
<a>...</a>
</div>
</a>
<div class="expand_me" id=<%= "{user.id}" -%>>
...
</div>
I've been trying to get the javascript you have suggested to work, but it doesn't. How should I get this specific case to work? I apologize for not including this information at the outset - I didn't know there would be a real difference between getting the solution to work with an href instead of the needed rel.
you could instead add an onClick handler to the div, and could place the link safely inside the div.
<html>
<head>
<script>
function clicked(){
window.location.href="link2";
}
</script>
<style>
body{
width:50%;
margin-left:auto;
margin-right:auto;
}
</style>
</head>
<div width="100px" height="100px" style="background-color:red" onclick="javascript:clicked()">
test
</div>
</html>
Not only <A> elements cannot be nested, but (I believe) that the content must be inline, so DIV should not be used for links. I'd use, onclick in the outside DIV, for example:
<div id="myparentdiv" onclick="alert('go somewhere')">
hi bla bla blah
<br> hi <br>
<a onclick="document.getElementById('myparentdiv').onclick=undefined;return true;"
href="http://stackoverflow.com/">go to st</a>
</div>
Obviously, you should replace the alert call with your redirection.
The inside onclick is to avoid the event propagation.
This problem can be solved with jQuery like so:
<div class="linked">
Text
<div class="linked">
Text2
</div>
</div>
<script type="text/javascript">
$("a").each(function(){
var aTag = this;
$(aTag).ancestor('.linked').click(function(){
window.location.href = $(aTag).attr('href');
});
});
</script>
This gives you the best of all worlds: semantic HTML, and the auto propagation of a tag behavior up to the nearest 'linked' ancestor. It also conveniently allows for nesting.
I agree with what the other users suggested. A tag can only be inline elements and therefore cannot wrap any other elements. Solution is to use the onclick event to handle the case where the user will click on the div tag. Inside the div tag then you can put other a tags which can point somewhere else.
This method however has a flaw, that is search engines will not be able to crawl the link wherever the onclick event is pointing. One way to fix this is to have another explicit link on the page which will point to the same link as the onclick. Here is the example:
<div onclick="document.location.href = 'link1.html'">
<p>Content would go here...</p>
Click here or anywhere near me to go location 1
Click here to go to location 2
</div>
NOTE: The first a tag does not have to be inside the div tag.
This will allow users to click either inside the div or on the first a tag to go to link1.html, and the other a tag will go to link2.html. This will also allow search crawlers to index both links.
I would also recommend applying some CSS to the div tag, and wrapping the onclick javascript code into a function to make the code more manageable but that's not necessary.
Hope this helps.
If browser compatibility isn't of utmost importance, then you should have a look at this pure CSS solution. By using an AP anchor and the z-index property, you can have an anchor that's as big as the outer div that is layered on top of all the other contents.
In it's simplest form, it could look something like:
<div id="about_us">
<h3>About Us</h3>
<p>This website is the culmination of several months of intensive research
and collaboration. </p>
<p>We painstakingly gathered data and are presenting it to the world here. </p>
Read More
</div>
CSS:
#about_us {
position: relative;
}
#about_us a {
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
z-index: 100;
text-indent: -9999px;
}
This will give you anchor with the same size as the parent div, and is above all of the contents, as well as hide the link text so that it won't appear at the top left corner of the div.
For a more complex example, see: http://jsfiddle.net/545xy/2/
Related
I was wondering how do I make it so that a div container show parts of its content in a small text box, and there will be an arrow at the bottom of the text box pointing downwards, and when clicked upon, it will make the text box bigger and show all of its content?
Can this be achieved using html/css, without the need to use javascript and jQuery or is it a jQuery thing?
<div class="society3" style="overflow:auto">
<p>Description:<p>
<p><?php echo $description; ?></p>
</div>
The description variable just contains a paragraph of text, so I would like the div container to show part of the text and when someone wants to read the full description, they can click on the button and, box will extend to show all content of the div tag.
The bad news is that you will need to use jQuery or similar for something like this, but the good news is that it's relatively straight forward. After you've loaded it into your page, all you need to do is target the id you would like to show/hide (or as it is called in jQuery toggle) and make an onClick() event.
For example, something like this should work.
<script>
$(document).ready(function(){
$("button").click(function(){
$("#toggle").toggle();
});
});
</script>
<div id="button" class="society3" style="overflow:auto">
<p>Description:<p>
<p id="toggle" style="display: none">[content]</p>
</div>
The most similar of your objective is using html5, but this works in google chrome, sometimes in firefox.
<html>
<head><meta charset="UTF-8"></head>
<style type="text/css">
.expand{
padding:10px;
}
</style>
<div class="expand">
<details>
<summary>OPEN</summary>
<p>Some text</p>
</details>
</div>
</html>
Is it possible to wrap an <a> tag around <div>s like so:
<a href=etc etc>
<div class="layout">
<div class="title">
Video Type
<div class="description">Video description</div>
</div>
</div>
</a>
Eclipse is telling me the div's are in the wrong place?
If this is not allowed. How can I make the entire 'layout' class become a link?
That structure would be valid in HTML5 since in HTML5 anchors can wrap almost any element except for other anchors and form controls. Most browsers nowadays have support for this and will parse the code in the question as valid HTML. The answer below was written in 2011, and may be useful if you're supporting legacy browsers (*cough* Internet Explorer *cough*).
Older browsers without HTML5 parsers (like, say, Firefox 3.6) will still get confused over that, and possibly mess up the DOM structure.
Three options for HTML4 - use all inline elements:
<a href=etc etc>
<span class="layout">
<span class="title">
Video Type
<span class="description">Video description</span>
</span>
</span>
</a>
Then style with display: block
Use JavaScript and :hover:
<div class="layout">
<div class="title">
Video Type
<div class="description">Video description</div>
</div>
</div>
And (assuming jQuery)
$('.layout').click(function(){
// Do something
}):
And
.layout:hover {
// Hover effect
}
Or lastly use absolute positioning to place an a anchor with CSS to cover the whole of .layout
<div class="layout">
<div class="title">
Video Type
<div class="description">Video description</div>
</div>
<a class="more_link" href="somewhere">More information</a>
</div>
And CSS:
.layout {
position: relative;
}
.layout .more_link {
position: absolute;
display: block;
top: 0;
bottom: 0;
left: 0;
right: 0;
text-indent: -9999px;
z-index: 1000;
}
This won't work with older versions of IE, of course.
While the <a> tag is not allowed to contain <div> element, it is allowed to contain other inline elements such as <span>.
When I encountered the problem i swapped the div tag with a <span>. Since the span tag is an inline element, you need to apply a display:block to the css of your <span> element, in order to make it behave like the <div> block element.
This should be valid xhtml and does not require any javascript.
Here's an example:
<a href="#">
<span style="display:block">
Some content. Maybe some other span elements, or images.
</span>
</a>
Another simple solution - just add an onclick event handler to the div thusly:
<div class="layout" onclick="location.href='somewhere'">
<div class="title">
Video Type
<div class="description">Video description</div>
</div>
</div>
This works great for me but there is one small gotcha. I'm not sure how search engine friendly this is. I fear that google's web crawlers might not find this link so I also tend to include a traditional A HREF link somewhere in the block like this:
<div class="layout" onclick="location.href='destination_url'">
<div class="title">
Video Type
<div class="description">Video description</div>
</div>
This is a link
</div>
Timothy's solution is correct ... instead of wrapping an anchor around a div ... you simply give layout to the anchor element with display:block and add the size and width of the anchor ...
.div_class { width: 100px; height: 100px; }
.div_class a { width: 100px; height: 100px; display: block; }
<div class='div_class'></div>
HTML provides two general elements, where div is a natural block element, and span is a natural inline element. All other elements are similarly assigned to be a natural block or inline.
Now, while both can be made by css display to be any of inline, inline-block or block, they are still treated for enclosure purposes as their natural selves, hence the warning messages. Leopards and spots sort of thing.
However, css is only meant to be for making what an element looks like (presentation), but not actually be like (functionality), so it doesn't change an element's basic nature, though that gets very fuzzy in practice. A span made block becomes a bully that kicks everything else off the line, which is very un-inline sort of behaviour.
So, to mitigate against possible conflicts between their natural and css-induced behaviours, it is better to allow:
div or any natural block tag to only ever be block or inline-block.
span or any natural inline tag to only ever be inline or inline-block.
This will also mitigate against tending to build page structures that will likely end up churning out error and warning messages.
Basically, NEVER embed a natural block tag inside a natural inline tag, at any depth.
Why there is a really a distinction is perhaps due to a simplistic idea of what HTML was going to be used for when it was first dreamed up.
Certainly, framework makers got around a lot of these what-to-embed-where problems by just using myriads of divs everywhere, and 'divitis' was born, and still alive and well in every framework. Just have to press F12 in a browser on almost any commercial web page and drill down through a dozen divs. This very page has 15 unbroken levels of divs.
It is not hard to see why just settling on divs made sense. For example, a p tag may have a bunch of links to various sites, and that is ok because inline links are allowed in a block p. However, if not wanting to have query variables visible in those urls, then buttons are required. If only one, then the p can be put inside a form, as a p cannot contain a form.
The formaction attribute on a button can be used to target a url other than the form default, but it still does not allow independent forms, each with their own set of hidden inputs. A button can use the form attribute to use it with a form that isn't an ancestor, but it can get messy to keep track of.
For multiple links to different sites to appear as part of one paragraph though, the only way is to use a div instead of the p and then wrap each button in its own form set to inline. Most frameworks have to cope with so much more complex scenarios that nested divs are the only way to go.
It meant that they really only had to manage one tag per purpose and manage it as if it was an isolated environment. So what was meant to be an occasionally-used functional grouping tag became the web's Lego block. And none of them are going to risk breaking their frameworks by converting to HTML5 semantic tags in a hurry. In the end, semantic tags only really work for fairly static content rather than rich interactive sites.
I had tried to create custom solution using jQuery, which would imitate same behavior as a tag does, for parent DIV.
DEMO:
https://jsfiddle.net/kutec/m9vxhcke/
As per W3C standard, you cannot do this:
<div class="boxes">
<a href="http://link1.com" target="_blank">
<div class="box">
<h3>Link with _blank attr</h3>
</div>
</a>
</div>
You must follow this:
<div class="boxes">
<div class="box">
<h3>
Link with _blank attr
</h3>
</div>
</div>
But by following above code, you wouldn't get the whole DIV clickable :).
Correct structure should be something like this, which also allows you to click over the DIV to redirect on the given href value:
<div class="boxes" data-href="http://link1.com" data-target="_blank">
<div class="box">
<h3>
Link with _blank attr
</h3>
</div>
</div>
Simple Solution:
$(function() {
$('.boxes a').each(function(){
var aTag = $(this).attr('href');
$(this).parent().attr('data-href',aTag);
$("[data-href]").click(function() {
window.location.href = $(this).attr("data-href");
return false;
});
})
}(jQuery));
Dynamic Solution:
(function ( $ ) {
$.fn.dataURL = function() {
// variables
var el = $(this);
var aTag = el.find('a');
var aHref;
var aTarget;
// get & set attributes
aTag.each(function() {
var aHref = $(this).attr('href');
$(this).parent().attr('data-href',this);
aTarget = $(this).attr('target');
$(this).parent().attr('data-target',aTarget);
});
// imitation - default attributes' behavior on "data-" attributes
$(el).delegate('[data-href]','click', function() {
var loc = window.location.href;
loc = $(this).attr("data-href");
aTarget = $(this).attr('data-target');
if(aTarget == "_blank"){
window.open(loc);
} else {
window.location = loc;
}
return false;
});
//removing attributes from selector itself
el.removeAttr('data-href');
el.removeAttr('data-target');
// css
$('[data-href]').css('cursor','pointer');
};
}( jQuery ));
Final call:
<script>
$('.boxes').dataURL();
</script>
Hope this would be helpful :)
You would just want to style the "a" tag as display: block;
Eclipse is appropriately telling you that your HTML is not to spec (as a div tag is not allowed in an anchor tag).
But, since you seem to want to be visually making the anchor look like a big-ol-box, then simply style it as such :)
One easy way to make the div a link/clickable is by using html javascript onclick attribute:
<div class="clickable-div" onclick="location.href='#';"><div> ... </div></div>
I am trying to create a set of links to specific sections in the page using the <a href="#..."> notation, but it doesn't seem to work. Clicking on the link seems to do nothing and right-click -> open in a new tab changes the url but does not move to a different section of the page. I am using Firefox 28.0. My links are as follows:
<div>
<p>Contents</p>
<ul>
<li>Map</li>
<li>Timing</li>
<li>Timing Details</li>
</ul>
</div>
And they should be linking to:
<div id="map">[content]</div>
<div id="timing">[content]</div>
<div id="timingdetails">[content]</div>
Links to external webpages work fine. Placing the id="..." feature inside an <a> tag instead did not fix the problem. My webpage url is of the form http://127.0.0.1/foo/bar/baz/. This is within a Python Django project.
Any idea why this isn't working?
Every href needs a corresponding anchor, whose name or id attribute must match the href (without the # sign). E.g.,
Map
<a name="map">[content]</a>
An enclosing div is not necessary, if not used for other purposes.
Wow, thanks for pointing that out OP. Apparently Mozilla Firefox doesn't associate the id attribute with a location in the HTML Document for elements other than <a> but uses the name attribute instead, and Google Chrome does exactly the opposite. The most cross-browser proof solution would be to either:
1.Give your anchor divs both a name and an id to ensure max. browser compatibility, like:
Go to Map <!-- Link -->
----
<div id="map" name="map"></div> <!-- actual anchor -->
Demo: http://jsbin.com/feqeh/3/edit
2.Only use <a> tags with the name attribute as anchors.
This will allow the on-page links to work in all browsers.
what happened with me is that the href does not work second time and that because I should Remove hash value first,,
take look how I resolved it
go to Content 1
function resetHref() {
location.hash = '';
}
Just resurrecting this post because I had a similar problem and the reason was something else.
In my case it was because we had:
<base href="http://mywebsite.com/">
defined on the .
Obviously, don't just remove it, because you need it if you are using relative paths.
Read more here:
https://www.w3schools.com/tags/tag_base.asp
Content 1
Content 2
Content 3
....
<a name="1"></a>Text here for content 1
<a name="2"></a>Text here for content 2
<a name="3"></a>Text here for content 3
When clicking on "Content 1" it will take directly to "Text here for Content 1.
Guaranteed!
Today being March of 2022, I had a specific occurrence of this problem that illustrates how the whole web environment is an "issue" today.
Same requirement: links that go to a section of the page.
It worked on my desktop's Chrome and Firefox, but not on my client's and neither on my Android's Chrome.
After reading multiple threads several times for a few hours, I found out that, in order for this behavior to be the most consistent across browsers and browser versions, you have to implement both things:
a container with an id, and
an anchor with a name property,
The most important part is that the anchor tag with a name, must have content inside of it.
So, you have your links
Go to section
<!-- more links -->
And you have the sections you want your links to go to
<div id="page-section">
<a name="page-section" class="collapse"> placeholder-content (important) </a>
<!-- your section content -->
</div>
Since you MUST have content inside the anchor with the name, you can then hide it in several ways.
My approach was to just set it's height to 0.
In order for the height to be effective, the anchor tag's display property should be set to block or inline-block for example.
.collapse {
height: 0px;
overflow: hidden;
display: block;
}
Finally it all worked, and I have to thank the many developers who struggle with this sort of thing (which should be much easier to do, but, the web...), and all the people who answer questions like this and share their knowledge.
This might help
JS:
function goto($hashtag){
document.location = "index.html#" + $hashtag;
}
HTML :
<li><a onclick="goto('aboutus')">ABOUT</a></li>
In my case The input tag was the problem. I implemented my tabs by input (radio buttons) which was preventing the anchor tag's behaviour.
It was like this at first (not working):
<a href="#name">
<li>
<label></label>
<input></input>
</li>
</a>
Then I removed the input tag and it worked:
<a href="#name">
<li>
<label></label>
// <input></input> <!-- removed it -->
</li>
</a>
Make sure you're not using preventDefault in javascript
Here is something that I finally got to work in IE, Chrome and Firefox.
Around any text create an anchor tag like this:
<a class="anchor" id="X" name="X">text</a>
Set "X" to whatever you want.
You must enclose something in the anchor tags such as text or an image. It will NOT work without these.
For the link, use this:
text
As for getting rid of the CSS for links using our anchor tag use something like this:
a.anchor {
color:#000;
text-decoration:none;
}
This seems to work well.
For practice and training CSS im trying to do something like:
In other words, I'm trying something like this: when I hover over third paragraph, second paragraph needs to get color like on picture.
I'm trying with pseudo-classes :hover and :before (or :after) with content attribute set to "", setting background to #E7A51B and opacity to 0.3 but It doesn't work.
HTML need to be like this:
<body>
<div class="app">
<p> First paragraph </p>
<div class="active">
<p> Second paragraph </p>
</div>
<br>
<div>
<p> Third paragraph </p>
</div>
</div>
</body>
EDIT: Thanks everyone on comments. Reading your comments I get idea to ask that is it possible some more generic approach, something like:
If I hover over element with class="foo1" background of element with class="foo2" get changed?
current CSS (Selectors Level 3)
With the current CSS standard, unfortunately what you are trying is not possible. However, what is possible at the moment?
Given the following markup:
<div class="app">
<p> First paragraph </p>
<p> Second paragraph </p>
<p> Third paragraph </p>
</div>
You can target elements that are on the same level (same parent) and follow your initial element you interact with (e.g. :hover). → Demo
/* targeting the direct descending sibling of the 3rd paragraph*/
p:nth-of-type(3):hover + p{
color:red;
}
/* targets the 4th paragraph when hovering the second */
p:nth-of-type(2):hover ~ p:nth-of-type(4){
color:blue;
}
/* targets all paragraphs being siblings of the first paragraph */
p:first-of-type:hover ~ p{
color:green;
}
the future (Selectors Level 4)
Selectors Level 4 will (most likely) bring two exciting new feature which can achieve, what you actually try to do:
1) The - what I would call it - subject indicator - it let's you determine, which element of the compound selector you want to target.
!OL > LI:only-child
would target all ordered lists with only have one list element (looks simple, but is not possible with current css).
2) the reference combinator:
label:hover /for/ input
would target an input element, when the label which is referencing it via it's for attribute is hovered.
At the moment this is not supported by any browser yet, but you see, we can be excited what awaits us in the near future of css;)
The :hover method in CSS will only work if you want to hover over an element and change the color of that specific element, it will not work to change a separate one. In other words, you will need to do some simple JQuery. If you're not familiar with JQuery, don't worry, I'll walk you through the steps you'll need. If you're familiar with Jquery and already have the library, skip to step 3 and I'll provide you with the exact code that will make it work. This looks extremely long and painful but that's just because I'm trying to be as thorough as possible. It is actually very simple
Step 1: If you don't know what JQuery is, it is JavaScript that has been rewritten in an easier (in my opinion) syntax. In order for the JQuery to work however, you will need to download the library (syntax) for free at jquery.com. When you get to the website, click the download tab and then download the compressed, production version of JQuery. When you click that to download it, a page opens up with all the code. Copy it all and paste it into your text editor and save it with a .js extension. ex: jquery-library.js.
Tip: make sure it is in the same folder as all of your other html and css documents that you're using.
Step 2: Link your html with the Jquery library you downloaded like this:
<head>
<script type="text/javascript" src="the name of your jquery library file.js"></script>
</head>
Step 3: Create a new file in your text editor with a .js extension. ex: background-color.js. You will also need to link this with your html page. Go to your html page and in the < head > section right underneath the first < script > tag, type:
<script type="text/javascript" src="the name of your javascript file.js"></script>
Your < head > section in the html should now look like this:
<script src="the name of your jquery library file.js"></script>
<script src="the name of your javascript file.js"></script>
Step 4: You will need to make a few simple changes to your html first. The second and third < p > elements both need classes so that the JQuery can identify them:
<div class="app">
<p> First paragraph </p>
<div class="active">
<p class="second"> Second paragraph </p>
</div>
<br>
<div>
<p class="third"> Third paragraph </p>
</div>
Step 5: Now for the JQuery. It is okay if you don't understand the syntax, just copy and paste this into your .js document:
Tip: I added comments to explain each string as much as possible. Anything on a line after a // is a comment.
$(document).ready(function(){ // <-- this string tells the browser to perform the following action once the page has fully loaded
$(".third").mouseenter(function(){
$(".second").css("background-color", "#9CF"); // change this css color to whatever background color you want
}); // when the mouse enters the class "third", the background color of the class "second"
// changes to #9CF
$(".third").mouseleave(function(){
$(".second").css("background-color", "#FFF"); //change this css color to whatever your default background is
}); // when the mouse leaves the class "third", the background color of the class "second"
// changes back to default
});
I hope this helped. Let me know if something doesn't work, but I tested it in safari and firefox and it is extremely basic JQuery so it should work anywhere. Keep in mind that on a mobile device, you can't hover, so try not to make it an essential part of your website.
Here is my solution
My goal was to create a solution that wouldn't require any work on the HTML of the page. I was also trying to create a solution that would be applicable in various scenarios. To do this, I have to use the .prev() method.
$("div p").on("mouseenter", function () {
$(this).prev().css("background-color", "red");
});
$("div p").on("mouseleave", function () {
$(this).prev().css("background-color", "inherit");
});
here is my new code with some jquery
in your html I added class last
http://jsfiddle.net/K4RFX/1/
$('.last').mouseover(function() {
$('.active p').css('background','#f00');
});
$('.last').mouseout(function() {
$('.active p').css('background','none');
});
<body>
<div class="app">
<p> First paragraf </p>
<div class="active">
<p> Second paragraf </p>
</div>
<br>
<div class="last">
<p> Third paragraf </p>
</div>
</div>
</body>
Unfortunately, the modern CSS doesn't have a selector like 'previous element'. We can only use some combinations of hover effects on parent and children elements, like in this demo:
CSS
.wrapper:hover p:first-child {
background: red;
}
.wrapper p:first-child:hover {
background: none;
}
HTML
<div class="wrapper">
<p>The 2nd parapraph</p>
<p>The 3rd parapraph</p>
</div>
I have this type of markup:
<div class="box" href="pic-gallery/img01.jpg">
<div>----------</div>
</div>
Now as I am going to validate this it is showing error as href inside a div is not allowed. So how to validate this error? I had used:
<div class="box" onclick="href='pic-gallery/img01.jpg'"></div>
but it is not opening the image as picture is coming through the fancybox. So please help me out. Any help and suggestions will be highly appreciated.
href isn't a valid attribute for div, just a and area. Your best bet is to use an actual link (an a element). You can use styling (display: block) to make it shown as a block on modern browsers (not, sadly, on some older versions of IE), and since its content model is transparent, you could put a div inside it. All of the examples on the Fancybox howto page show using an a element, not a div.
So perhaps
<a class="box" href="pic-gallery/img01.jpg">
<div>----------</div>
</a>
...where the "box" class includes display: block. Or if you use that class places where you don't want block display, break out the display: block and apply it separately (via another class or inline style attribute).
With fancybox, you can show your images by putting their path inside links:
<a class="box" href="pic-gallery/img01.jpg"></a>
This will be identified by fancybox based on link's class eg box and will be opened by fancybox.
This is expected - the href attribute is not valid on a <div> element. As T.J. said above, it would be best to use an actual <a> element to do this - it makes more semantic sense. You could even nest the <a> inside the outer <div> and hide it with CSS, so non-JS enabled users don't see redundant markup.
Instead of this code.
<div class="box" onclick="href='pic-gallery/img01.jpg'"></div>
Try this
<script type="text/javascript">function open_win(){window.open("pic-gallery/img01.jpg");}</script><div class="box" onclick="javascript:open_win();"></div>
But how do you want to open the image?
I know this is unusual but you could still open an image (or any other type of content) in fancybox adding the onclick attribute to the <div> (or any other tag other than the <a> tag) and without using the href attribute.
You may have this (valid) html:
<div class="box" onclick="openFancybox('pic-gallery/img01.jpg');">
<div>whatever here</div>
</div>
and use this script:
<script type="text/javascript">
function openFancybox(url){
$.fancybox({
'href': url,
'type': 'image' //select the proper type of content
});
}
</script>
what you are doing is passing the url to the function instead of using href