How to modify content with CSS? - html

WARNING:
I do not recommend anyone to do this. It's an ugly hack.
I've got the code (minimized for the example)
<div id="somecontent">
<a name="content"></a>
Content to be changed
</div>
JSFiddle: https://jsfiddle.net/zalun/o733uyvs/
I'd like to change the "Content to be changed" with CSS.
Is this even possible (all ugly hacks included)?
It's easy when HTML is modified (<span> added) as in second block in mentioned fiddle.

Note: What you are trying to do is not recommended. I am providing you
a solution because I think you do not have access to source HTML or
your content is generated dynamically. I would still suggest you too
either change the source file or modify the DOM node using JavaScript.
I would say No and Yes.
Why No?
That's a text node. You cannot manipulate DOM nodes using CSS. You need to use JavaScript for that.
Why Yes? (Using ugly hacks), How?
Using content property as you are already using, but you cannot change the DOM, so you can make it super ugly like
Demo
#somecontent {
color: transparent;
position: relative;
}
#somecontent a:before {
content: "My new content";
color: #000;
position: absolute;
}
JavaScript Solution :
Demo
// You'll see text flicker
var t = document.getElementById('somecontent');
t.textContent = 'New Text';

Related

On page CSS to override server added value

We have had a site re-designed by a company who also maintains and hosts it, as well as providing us with our CRM system. The issue I am facing is they add a bit of a backlink to the footer, which I am unable to edit as its not part of the page until the server generates it.
I would like to use On Page CSS to style this to white, or completley remove it. Either is fine
<span style="width: 100%; text-align: center; display: block; color: #999999; font-family: verdana; font-size: 7pt;margin-bottom:4px;">Powered by <a style="color: #999999;" href="http://www.prospectsoft.com/ecommerce" target="_blank">ProspectSoft eCommerce</a> and <a style="color: #999999;" href="http://www.prospectsoft.com/crm" target="_blank">CRM</a></span>
The above is the code I can see when I look at the source of the page in Firefox. I cannot see this code in the editor they provide, however I can edit the css files.
Is it possible to use on page CSS to style this out?
Well in my mind with pure CSS, no since there doesn't seem to be something unique to reference it by.
Alternate Solution:
If you can use Jquery it should be relatively easy though.
Do following in head:
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$().ready(function () {
$('footer').child().hide();
});
</script>
Depending on the build of the page you should be able to isolate that HTML element. For instance, if that span is the only element in the
<footer>
tag, you could simply use:
$('footer').hide();
Note: They may already be referencing jquery, which means you could just do the code.
One More:
$().ready(function () {
$("a:contains('ProspectSoft eCommerce')").parent().hide();
});
Will delete all parents of anchor tags that contain that text though, so be careful.
EDIT:
$("span:contains('Powered by')").hide();
In line CSS will typical override stylesheets declared in the document head.
If you find certain properties remain stubbornly unaffected, try using the "!important" modifier.
Example:
color: #ff0000 !important;
Beyond this, I can't give you any further advice given that you haven't specified exactly what your problem is.
Not good looking but works:
div span, span a { color: #FFF !important; }
Bad thing is you would have to set the color to all other similar nests "div span" and "span a"

Hide all, show a class with css

Context: making printable invoices to generate in a browser.
It's common in making printable webpages to use an #media print rule to change the way the content looks for a printed page. Ideally, because I'm printing only a small part of the page, I'd like to hide everything and then display the contents of a particular element.
Structure is something like this:
<body>
<div id="topMenu">...lots of elements...</div>
<div id="sideMenu">...lots more...</div>
<div class="tools">...some tools...</div>
<div class="printing">...some elements I want to print...</div>
<div class="tools">...more stuff I don't want to print...</div>
</body>
Stuff I've tried:
Ideally, I'd like to do something like
body * {
display: none;
}
.printing, .printing * { /* Both parts are needed to make it display */
display: block !important;
}
But this won't work because some elements need to be inline and some need to be block. I've played with some different values for display from MDN and can't find one that easily resets the value to its original. display: initial seems to be treated like inline.
The suggestion in CSS: "display: auto;"? seems to only work for JS.
Of course, it is possible to explicity "hide" the stuff I don't want printed rather than display the stuff I do want, but it seems to me that it should be possible to go the other way.
In this question How to only show certain parts with CSS for Print? suggests body *:not(.printable *) {display:none;} but notes (as backed up on the w3 negation page ) that this is not yet supported.
I note that the w3 draft and the display-outside page seem to recommend using an unknown (to webkit) box-suppress property to preserve the display value while not displaying the element.
My questions:
What is the best way to hide everything and target certain elements for display when they don't all share a common display property?
What exactly does box-suppress do?
Since you specifically tagged this CSS3, try using CSS3!
body>:not(.printing) {
display: none;
}
This should work for the example you gave. I hope it works for your real-world application!
To answer your auxiliary question, as of October 2014, box-suppress is a possible future replacement for display:none that will hopefully make it easier to both hide and remove elements from the flow without worrying about changing its display type (as opposed to visibility still keeps it in the flow, and position:absolute which still keeps it visible). I don't think it's currently supported so I'd stay away from it for now. If you want to know more, see http://w3.org/TR/css-display
You cannot use display for this purpose. See Display HTML child element when parent element is display:none
However, you can use visibility, as long as you use absolute positioning for the hidden content:
body, body * {
visibility: hidden;
position: absolute;
}
.printing, .printing * {
visibility: visible;
position: relative;
}
If you don't use any absolute or fixed elements, you can use an alternative way of hiding elements.
Instead of using display: none to hide your elements, try using:
body * {
position:absolute;
top: -999999px;
left: -999999px;
}
To set it back use:
.printing, .printing * {
position: initial;
/* OR */
position: static;
}

Create LESS variable from HTML content

I wasn't able to find a thread on this, but if there is one, please let me know!
I want to create and use LESS variables based on the HTML content in a certain tag.
For example, the HTML would be something like:
<div class="bar">
<span>80%</span>
Blah blah
</div>
And the CSS/LESS would be something like:
#width: '$(".bar > span").text()';
.bar { background: red; width: #width; }
Do I need to convert the variable from a string to an int or float in order for it to be used as such? And if so, how?
Thanks!
I'm not sure if your comment above was mistyped,
"At first, I was trying to to just use a LESS variable for the sizing,
and then set it as the HTML content using the CSS content tag, but it
was working."
You state "but" after which I expected "it was [not] working" (otherwise, I would have expected you to say "and"). That was actually a solution I thought of, but if I am correct, and it was not working for you, then my guess is you were using content incorrectly (directly on the span itself?). The content property is only valid on the ::before and ::after pseudo elements.
So this works like you originally intended (and no need for the span element at all):
LESS
#width: 80%;
.bar {
background: red;
width: #width;
}
.bar:before {
content: '#{width}';
}
CSS Output
.bar {
background: red;
width: 80%;
}
.bar:before {
content: '80%';
}
See Example Fiddle
This will work fine for IE8 (you note supporting that in another comment). Assuming the 80% is not a necessary "content" value (that you want search engines picking up because it is critical data on the page), then using a pseudo element is perfectly fine for such visual user feedback. If you desire, it can be aligned just as regular text and some padding added to space it from the surrounding text, just like it were a span element.
As said in the comment i doubt less can do this.
Although you might want to use the meter HTML5 tag like so
<meter value="2" min="0" max="10">2 out of 10</meter><br>
<meter value="0.6">60%</meter>
Here is an example
http://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_meter
I think this is what you wanted to achieve from your script.

Injecting HTML via CSS

I need to basically set the content of something with HTML from CSS. I'm currently doing the following:
.myclass {
content "<img src=\"hello.png\"/>";
}
However, instead of the image, I see the literal text:
<img src="hello.png"/>
How can I inject arbitrary HTML using CSS?
HTML stores the data, and is the Model
CSS stores the styles, and is the View
JS stores the interactions, and is the Controller
If you're trying to add data to the page, it should be done via HTML. If you're simply trying to add an image as a style, use the background-image property. You don't need to inject an <img> element in the page to do that.
Don't ever do this, ever
As far as being able to inject HTML into the page via CSS, it's not directly possible, however it's possible to add JavaScript into the page using CSS, which can then add HTML to the page.
I can't emphasize enough how wrong that approach would be.
Unless there is some strange hack that I am not aware of, this cannot be done with pure CSS.
The content property is only able to insert text; if you try to put in HTML, it will be escaped.
That said, you can do something like this with pure CSS:
This is the CSS that can perform that effect:
.myClass:before {
display: inline-block;
width: 32px;
height: 32px;
content: "";
background-image: url("img.gif");
}
You can see this in action on this jsFiddle page.
In this particular case, you can use a pseudo-class (eg ::before), background-image, display:block and a fixed width and height to show the image.
Also, make sure that the colon : is added between content and its value.
A relatively new concept at the horizon is the element() value for backgrounds. This will display HTML as if it were an image: See also -moz-element.
This can be done. For example with Firefox
css
#hlinks
{
-moz-binding: url(stackexchange.xml#hlinks);
}
stackexchange.xml
<bindings xmlns="http://www.mozilla.org/xbl"
xmlns:html="http://www.w3.org/1999/xhtml">
<binding id="hlinks">
<content>
<children/>
<html:a href="/privileges">privileges</html:a>
<html:span class="lsep"> | </html:span>
<html:a href="/users/logout">log out</html:a>
</content>
</binding>
</bindings>
ref 1
ref 2
You can't. It's not what it's for. The CSS is for the presentation layer while the HTML is the data layer.
Actually, you can, but just for characters, not HTML. You can use the content property. With some CSS selectors like :before, you can do nice stuff like adding your own character as a bullet for your list. But not much more.

Possible to make a:after/before pseudo elements clickable as part of the link?

pseudo elements a:after a:before allow you to add text that appears to be part of the link. However, I can't seem to figure out a way to make that portion clickable as part of the link.
For example the following css shows the url afterward:
a:after {
content: " (" attr(href) ")";
}
...but it will not be clickable.
Anyone get around this without changing underlying HTML?
Edit: I am using chrome 13.0.782.107. It turns out it's a bug. (Thanks Sean)
It looks like you have discovered a bug in the browser you are using.
Based on the spec, the generated content should be treated as a child of the element it is being generated for. I created a JSFiddle to test this out, and the generated text is linked for me in most browsers (Chrome 13 being the solitary exception.) My guess is that you are testing in Chrome. This is a reproducible bug.
The workaround is to simply specify a background color on your links ... if you want to be able to use this for all links, declaring a background image (but not specifying an image, or using a transparent .gif - or as just pointed out, setting opacity to anything other than 1) works.
I've had the same problem and apparently if I set
a { vertical-align: middle; }
(thus on the link itself, not the pseudo element), it works.
I'm hoping someone has a better solution than this, but just in case not, I did come up with this horrible/crappy/hacky solution:
a {
margin-right: 40px;
}
a:after {
content: " (" attr(href) ")";
margin-left: -40px;
}
Just add this to your css:
a {padding-right:Ypx} /* Y = size of your url in pixels */
If the size of the URL varies you will have to use javascript to get it.
If you have a link on Wrapper then you can make pseudo-elements clickable by setting pointer-events to none.
a:after {
pointer-events: none;
}
To avoid modifying the document tree, you could use a JavaScript click handler for a:after.
Edit: This doesn't work, because pseudo elements aren't added to the DOM.
The :before and :after add content before and after the selector. In CSS, there's no selector that let's you get and edit the content inside a tag. The only way to make that happen would be with jQuery or javascript to actually edit the HTML.
I wrapped the link and the text separately -- the :before goes on the container and the link goes inside. This way I can use the :before as a jQuery tigger and the text as a link.
HTML:
<li class="before-here">My Link Text</li>
CSS:
li.before-here:before{ //some css like an image }
Jquery:
$("li.before-here").click(function(){ //do something});
I'm using this to create a hide/show toggle in a tree -- this gives me the button I need on the left and allows me to link to the parent.