Is it possible to target "no target" in CSS? - html

Is there a css selector for "no fragment identifier present"? The opposite of :target.
The thing is, I'm making a document where different parts of it are visible depending on which fragment identifier you give it. Think of it as a sprite file, only for HTML.
So it looks like this
<style>
section {display:none}
section:target {display:block}
</style>
<body>
<section id="one">The first block (showing with #one)</section>
<section id="two">The second block (showing with #two)</section>
<section id="three">The third block (showing with #three)</section>
</body>
And the user sees the first section if it's displayed with document.html#one on the location bar, etc.
The idea is that the browser will cache the html page (since it is just static html) and no other content needs to be loaded when displaying another block of text, thus minimising server load.
But the file looks stupidly empty when you call it up without a fragment identifier, so I wonder if there's a way to make all of it visible in that case, without any hidden sections. CSS only, no JS or server side processing; otherwise it wouldn't be static HTML!
Edit:
Unlike the proposed duplicates, I would like to "simply" show the whole document when there's no fragment identifier, not just one element in particular.
In other words, the default (in the absence of any #) should be to show everything; only if there is an # should everything but the target be hidden.
The duplicates don't address this situation at all.

With some extra markup and more verbose and specific CSS to write, to avoid javaScript. Needs to be updated each time HTML structure is updated .
:target ~section {
display:none;
}
#one:target ~.one,
#two:target ~.two,
#three:target ~.three {
display:block;
}
<nav>
One
Two
Three
None of below targets
</nav>
<!-- html anchor to allow use of :target ~ selectors -->
<a id="one"></a>
<a id="two"></a>
<a id="three"></a>
<!-- end anchor -->
<section class="one">The first block (showing with #one)</section>
<section class="two">The second block (showing with #two)</section>
<section class="three">The third block (showing with #three)</section>

Related

How to Isolate some part of HTML code style & formatting? [duplicate]

I am trying to figure out a way to display an archive of email newsletters on my client's site. The issue is that the newsletters are full of a zillion inline styles, which is great for seeing them in Outlook or wherever, but they're not looking too hot in an otherwise-nicely styled site.
My goal is for my client to be able to copy the entire source code of a generated newsletter (which her list management company* gives her access to) and paste it into the CMS (drupal, if it makes a difference).
*Constant Contact? Mail Chimp? I forget. One of those.
Then I'd like to display it on her site, inside the basic structure (header, nav, etc) of the rest of the site. If this was 1997, I'd say "iframes!" and be done with it, but A) that seems like a lame solution, and B) the code doesn't actually exist on a page by itself, which I think is required for iframes.
Is there some kind of tag I can put around this block of HTML to isolate it from the rest of the site's styles? Or is there another way to go about this entirely?
Thanks!
IFrames are the only way to go that I've ever been able to find. The only alternative to this would be to override every style in the parent page's CSS for the newsletter display area.
As you noted, using an iframe will probably require you to host the newsletters in an independent file. The only alternative to this that I'm aware of is that you can use JavaScript to dynamically create and/or populate the iframe.
If you go with this method, you could have the newsletter present in a div with a specific class, and then use JavaScript to move the div into an iframe. The big downside being that this wouldn't happen for users without JavaScript enabled.
9 years later and there still isn't a better solution.
If you don't have an external source (you can't add html into a frame manually) you need to use js to insert the messy html/css (in my case I use it to view emails)
<iframe class="my-frame" width="100%" height="100%" src="about:blank"></iframe>
and js:
const frame = document.querySelector('.my-frame');
frame.contentWindow.document.open('text/html', 'replace');
frame.contentWindow.document.write(hereGoesYourMessyHtmlCss);
frame.contentWindow.document.close();
Is there a reason why you can't use a modal? That would allow you to force a new request and make the page render how you'd want it to by not applying your general stylesheet while at the same time keeping your user on the desired page. Of course, it doesn't display the element inline so-to-speak, but it's nearly functionally equivelent.
Cutting and pasting raw HTML presents too many security problems, in my opinion. Never trust user's input. Even when the content is entirely benign, next week the designer of newsletter might decide to change their formatting or incorporate some javascript and you'll be responsible for anything that might go wrong.
Therefore I would implement a parser that would drop anything but the content part and leave only b, a, h*, blockquote and similar simple elements, like the ones allowed in forum posts, as well as their styles. After that, you can display it as a normal post in a CMS. I don't see any reason why that should look differently.
As for how to isolate that from your other CSS, you don't really need to if you are careful that all of CSS rules of your CMS apply to elements with specific classes. Alternatively, do a CSS reset for your posts:
.post p {
margin: 0;
...
.post /* all the standard CSS reset rules preceded with .post */
and then
<div class="post"> content parsed from your CMS </div>
Another option that I haven't used myself but am looking to possibly leverage in a similar situation is to use the Shadow DOM which is part of the Web Components spec. My main concern is that we still have some user's using IE 11 and while there seems to be support for polyfills it doesn't look like covering all browser's is real straight forward based on what I've read elsewhere.
Some details on how to use Shadow DOM to this effect can be found here and here. I've also created a small gist that I've created to demonstrate basic idea that I've been formulating as I learn about how the Shadow DOM works which I'll be updating as I learn more. Below you can see a snapshot of the content of that gist.
<!doctype html>
<html>
<head>
<style>
.row {
display: flex;
}
.column {
flex: 50%;
padding: 10px;
height: 300px;
}
* {
color: Red;
}
</style>
</head>
<body>
<div class="row">
<div class="column" style="background-color:#aaa;">
<h2>Column 1</h2>
<div id="content1">
SOME CONTENT FROM CMS
</div>
</div>
<div class="column" style="background-color:#bbb;">
<h2>Column 2</h2>
<div id="content2">
SOME MORE CONTENT FROM CMS
</div>
</div>
</div>
<script>
document
.getElementById("content1")
.attachShadow({ mode: 'open' })
.innerHTML = `
<style>
*{all:initial}
style{display: none}
div{display: block}
</style>
<h3>This text is not red</h3>
<div>slot content: <slot></slot></div>`;
document
.getElementById("content2")
.attachShadow({ mode: 'open' })
.innerHTML = `
<style>
*{all:initial}
style{display: none}
div{display: block}
</style>
<h3>This text is not red</h3>
<div>slot content: <slot></slot></div>`;
</script>
</body>
</html>

<a href="#..."> link not working

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.

CSS hover over one paragraph, change background of the previous one

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>

CSS: Highlight current menu item

I have a menu with links in the following form, in which I am trying to highlight the current menu item. I can't seem to get it working. Please advice as to what I am doing wrong
HTML
<body id="home">
<div id="topMenu">
<div class="nav-home" id="topMenuBlock"><p>Home</p></div>
<div id="nav-about"><p>About</p></div>
<div id="nav-rates"><p>Rates</p></div>
<div id="nav-faq"><p>FAQ</p></div>
<div id="nav-contact"><p>Contact</p></div>
<div id="nav-careers"><p>Careers</p></div>
</div>
<div id="rightTopMenu"></div>
</div>...other stuff</body>
Then for the CSS I have the following:
#home a.nav-home{ border-bottom:2px solid white; }
Do the links HAVE to be in a List, or can I leave them in div's, and if so, how can I make this work?
Thanks.
You've a little bit of a mess here.
Do the links HAVE to be in a List, or can I leave them in div's?
They don't have to be, but they probably should be. There's not good reason to use the strange markup you have chosen, you should definitely consider switching to a list and <li> tags.
Problem with duplicate ids
You have <body id="home"> and <a href="" id="home">
You also have several instances of id="topMenuBlock" (I see you fixed this in your edit.)
You cannot have more than one element with the same id. id attributes must be unique, always. Use class names instead, if anything.
You are using this selector: #home a.nav-home {} but it doesn't match anything. There is no <a class="nav-home">. You can use something like:
#home {} because that's the id of the <a> element you want
.nav-home a {} - Selects the <a> inside an element with class="nav-home"
Perhaps you have the concept of ids and classes mixed up. Ids are supposed to uniquely identify HTML elements, whereas classes can be used as many times as you like. Right now you have 6 elements with the id #topMenuBlock. You should make a .topMenuBlock class instead. I would also make a #nav-home id instead of a class since there should only be one such element on each page.
Secondly, there is no need for the <p> tags you have within your <a> tags. In fact, it's against HTML standards to do so since anchors are inline elements and paragraphs are block-level elements.
Lastly, your CSS selector that sets the border is incorrect because the .nav-home div is not contained within an <a> element. Use this CSS instead (assuming you change nav-home to be an id rather than a class):
#nav-home{ border-bottom:2px solid white; }
Fix these issues and then see what happens. If you're new to HTML and CSS, I would recommend going through some tutorials, such as the ones found at http://www.w3schools.com/.
Your class identifier should be in the <a /> tag
You have
<div class="nav-home" id="topMenuBlock"><p>Home</p></div>
but you want
<div class="something" id="topMenuBlock"><a class = "nav-home" href="" id="home"><p>Home</p></a></div>
Modify your CSS class accordingly.

How do I highlight a link based on the current page?

Sorry if this sounds like a really stupid question, but I need to make a link change colour when you are on the page it links to.
For example, when you are on the "Questions" page of StackOverflow, the link at the top changes colour. How do you do this?
It's a server-side thing -- when rendering the page, add a class like "current-page" to the link. Then you can style it separately from the other links.
For example, StackOverflow renders the links with class="youarehere" when it points to the page you're already on.
It really depends on how your page is constructed. Typically, I would do this using CSS, and assign give the link an id called "active"...
<a id="active" href="thisPage.html">this page</a>
...and in the CSS...
a#active { color: yellow; }
Obviously this is a fairly simplistic example, but it illustrates the general idea.
You can do this without having to actually modify the links themselves for each page.
In the Stack Overflow clone I'm building with Django, I'm doing this:
<!-- base.html -->
...
<body class="{% block bodyclass %}{% endblock %}">
...
<div id="nav">
<ul>
<li id="nav-questions">Questions</li>
<li id="nav-tags">Tags</li>
<li id="nav-users">Users</li>
<li id="nav-badges">Badges</li>
<li id="nav-ask-question">Ask Question</li>
</ul>
</div>
Then filling in the bodyclass like so in page templates:
<!-- questions.html -->
{% extends "base.html" %}
{% block bodyclass %}questions{% endblock %}
...
Then, with the following CSS, the appropriate link is highlighted for each page:
body.questions #nav-questions a,
body.tags #nav-tags a,
body.users #nav-users a,
body.badges #nav-badges a,
body.ask-question #nav-ask-question a { background-color: #f90; }
Set a class on the body tag for each page (manually or server-side). Then in your CSS use that class to identify which page you're on and update the style on the item accordingly.
body.questions #questionsTab
{
color: #f00;
}
Here's a good longer explanation
If for some reason you don't want to handle this on the server-side, you can try this:
// assuming this JS function is called when page loads
onload()
{
if (location.href.indexOf('/questions') > 0)
{
document.getElementById('questionsLink').className = 'questionsStyleOn';
}
}
Server side code is the easiest, by just setting a class on the link on the current page, but this is also possible on the client-side with JavaScript, setting a second class on all elements in a particular class which have an href which matches the current page.
You could use either document.getElementsByTagName() or document.links[] and look only for those in a class denoting your navigation links and then set a second class denoting current if it matches the current URL.
The URLs will be relative, while document.URL will not. But you can sometimes have this same problem with relative vs. absolute on the server-side if you are generating content from a table-driven design and the users can put either absolute or relative URLs anyway.
You need code on the server for this. A simplistic approach is to compare the URL of the current page to the URL in the link; however consider that there are many different URLs in stackoverflow which all result in the 'Questions' tab being highlighted.
A more sophisticated version can either put something in the session when you change pages (not too robust); store a list of pages/URL patterns which are relevant to each menu item; or within the code of the page itself, set a variable to determine which item to highlight.
Then, as John Millikin suggests, put a class on the link or on one of its parent elements such as "current-page" which will control the colour of it.