Related
I'm trying to get a second sibling element displaying in front of the first - with some severe restrictions:
I cannot alter the HTML or use javascript or jQuery.
I can only use CSS.
I can't change how classes are assigned (again, I don't have access to change any code apart from the one bespoke CSS file).
The left-hand menu features a number of the above HTML structures, building a clickable menu for the sections on the page. When a page section is completed, the 'completed-section' class is added to the first span (as shown above). This is what is causing me problems:
The CSS styling of the nav-link 'button' should change when it's completed, but since I can't access the parent of a CSS-selected element I need to make these changes directly to the 'menu-number' span element, including a 'nav-link' sized background colour. So I've made the menu-number the same size as the containing 'nav-link' . But when I add a background colour to the 'menu-number' , the text in the second is obscured.
How can I 'move' the second span in front of the first so I can see its text?
I have also tried making both spans position absolute or position relative and used z-index but this pulls the spans out of the flow of the document and means the width of the menu collapses. I can't set the width to a hard-coded value because the menu toggles open and closed, width-wise, (without a class being set) and the toggled width is set by javascript which, again, I can't access.
I have also tried using display: flex on the 'a' element and reversing the 'order' of span elements. No luck.
In semi-desperation I have tried setting the direction property on 'nav-link' to rtl. No luck.
I think I've tried a couple other things too, but at this point I'll wrap this question up.
Any pointers, much appreciated...
.menu-number {
border: none;
border-left: 10px solid transparent;
border-radius: 0px;
padding-top: 13px;
padding-left: 20px;
height: 45px;
position: absolute;
width: 100%;
text-align: left;
z-index: 100;
float: left;
}
.menu-number + span {
/*position: absolute;*/
padding-left: 40px;
z-index: 200;
}
.completed-section {
color: #42bb76 !important;
border-left: 10px solid #42bb76;
background-color: #274d56;
text-decoration: underline;
}
.nav-link > div > a {
display: flex;
*/flex-direction: row-reverse;*/
}
.nav-link > div > a > span:nth-of-type(1) {
order: 2;
}
.nav-link > div > a > span:nth-of-type(2) {
order: 1;
}
.nav-link > div > a > .section-name {
color: white;
padding: 13px 20px 0px 60px;
height: 45px;
float: left;
}
<div class="nav-link">
<div>
<a href="scroll/to/section">
<span class="menu-number completed-section">1.</span>
<span class="section-name">Section name</span>
</a>
</div>
</div>
I've also tried 'flex-direction' but I've now commented that out.
You can achieve this using CSS order property:
Here is the fiddle:
.menu-number {
order: 2;
}
.section-name {
order: 1;
}
.nav-link a{
display: flex;
}
<div class="nav-link">
<div>
<a href="scroll/to/section">
<span class="menu-number completed-section">1.</span>
<span class="section-name">Section name</span>
</a>
</div>
</div>
How can I replace text with CSS using a method like this:
.pvw-title img[src*="IKON.img"] { visibility:hidden; }
Instead of ( img[src*="IKON.img"] ), I need to use something that can replace text instead.
I have to use [ ] to get it to work.
<div class="pvw-title">Facts</div>
I need to replace "Facts".
Or maybe you could wrap 'Facts' round a <span> as follows:
.pvw-title span {
display: none;
}
.pvw-title:after {
content: 'whatever it is you want to add';
}
<div class="pvw-title"><span>Facts</span></div>
Obligatory: This is a hack: CSS isn't the right place to do this, but in some situations - eg, you have a third party library in an iframe that can only be customized by CSS - this kind of hack is the only option.
You can replace text through CSS. Let's replace a green button that has the word 'hello' with a red button that has the word 'goodbye', using CSS.
Before:
After:
See http://jsfiddle.net/ZBj2m/274/ for a live demo:
Here's our green button:
<button>Hello</button>
button {
background-color: green;
color: black;
padding: 5px;
}
Now let's hide the original element, but add another block element afterwards:
button {
visibility: hidden;
}
button:after {
content:'goodbye';
visibility: visible;
display: block;
position: absolute;
background-color: red;
padding: 5px;
top: 2px;
}
Note:
We explicitly need to mark this as a block element, 'after' elements are inline by default
We need to compensate for the original element by adjusting the pseudo-element's position.
We must hide the original element and display the pseudo element using visibility. Note display: none on the original element doesn't work.
If you're willing to use pseudo elements and let them insert content, you can do the following. It doesn't assume knowledge of the original element and doesn't require additional markup.
.element {
text-indent: -9999px;
line-height: 0; /* Collapse the original line */
}
.element::after {
content: "New text";
text-indent: 0;
display: block;
line-height: initial; /* New content takes up original line height */
}
JSFiddle Example
Based on
mikemaccana’s answer,
this worked for me
button {
position: absolute;
visibility: hidden;
}
button:before {
content: "goodbye";
visibility: visible;
}
<button>original</button>
§ Absolute positioning
an element that is positioned absolutely is taken out of the flow and thus
takes up no space when placing other elements.
This is simple, short, and effective. No additional HTML is necessary.
.pvw-title { color: transparent; }
.pvw-title:after {
content: "New Text To Replace Old";
color: black; /* set color to original text color */
margin-left: -30px;
/* margin-left equals length of text we're replacing */
}
I had to do this for replacing link text, other than home, for WooCommerce breadcrumbs
Sass/Less
body.woocommerce .woocommerce-breadcrumb > a[href$="/shop/"] {
color: transparent;
&:after {
content: "Store";
color: grey;
margin-left: -30px;
}
}
CSS
body.woocommerce .woocommerce-breadcrumb > a[href$="/shop/"] {
color: transparent;
}
body.woocommerce .woocommerce-breadcrumb > a[href$="/shop/"]&:after {
content: "Store";
color: #child-color-grey;
margin-left: -30px;
}
You can't, well, you can.
.pvw-title:after {
content: "Test";
}
This will insert content after the current content of the element. It doesn't actually replace it, but you can choose for an empty div, and use CSS to add all the content.
But while you more or less can, you shouldn't. Actual content should be put in the document. The content property is mainly intended for small markup, like quotation marks around text that should appear quoted.
In order to use after and hide the original content, you can use this hack:
.pvw-title {
font-size: 0;
}
.pvw-title:after {
font-size: 1rem;
content: 'I am a totally different piece of text!';
}
<div class="pvw-title">Facts</div>
Setting font-size to 0 makes the text disappear without removing the actual element from the viewport. Therefore, the :after selector works and should show on all browsers.
Try using :before and :after. One inserts text after HTML is rendered, and the other inserts before HTML is rendered. If you want to replace text, leave button content empty.
This example sets the button text according to the size of the screen width.
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
button:before {
content: 'small screen';
}
#media screen and (min-width: 480px) {
button:before {
content: 'big screen';
}
}
</style>
<body>
<button type="button">xxx</button>
<button type="button"></button>
</body>
Button text:
With :before
big screenxxx
big screen
With :after
xxxbig screen
big screen
I had better luck setting the font-size: 0 of the outer element, and the font-size of the :after selector to whatever I needed.
If you just want to show different texts or images, keep the tag empty and write your content in multiple data attributes like that <span data-text1="Hello" data-text2="Bye"></span>.
Display them with one of the pseudo classes :before {content: attr(data-text1)}
Now you have a bunch of different ways to switch between them. I used them in combination with media queries for a responsive design approach to change the names of my navigation to icons.
jsfiddle demonstration and examples
It may not perfectly answer the question, but it satisfied my needs and maybe others too.
Text replacement with pseudo-elements and CSS visibility
HTML
<p class="replaced">Original Text</p>
CSS
.replaced {
visibility: hidden;
position: relative;
}
.replaced:after {
visibility: visible;
position: absolute;
top: 0;
left: 0;
content: "This text replaces the original.";
}
The simplest way I found is by making the element font-size: 0px, then overwrite it with any font size when creating :after pseudo. Example below:
.pvw-title {
font-size:0px;
}
.pvw-title:after {
content: "Hello";
font-size:15px !important;
}
This worked for me with inline text. It was tested in Firefox, Safari, Chrome, and Opera.
<p>Lorem ipsum dolor sit amet, consectetur <span>Some Text</span> adipiscing elit.</p>
span {
visibility: hidden;
word-spacing: -999px;
letter-spacing: -999px;
}
span:after {
content: "goodbye";
visibility: visible;
word-spacing: normal;
letter-spacing: normal;
}
I use this trick:
.pvw-title {
text-indent: -999px;
}
.pvw-title:after {
text-indent: 0px;
float: left;
content: 'My New Content';
}
I've even used this to handle internationalization of pages by just changing a base class...
.translate-es .welcome {
text-indent: -999px;
}
.translate-es .welcome:after {
text-indent: 0px;
float: left;
content: '¡Bienvenidos!';
}
Try this way:
IDENTIFIER {
visibility: hidden;
position: relative;
}
IDENTIFIER::after {
visibility: visible;
position: absolute;
top: 0;
left: 0;
content: "NEW_CONTENT";
}
This implements a checkbox as a button which shows either Yes or No depending on its 'checked' state. So it demonstrates one way of replacing text using CSS without having to write any code.
It will still behave like a checkbox as far as returning (or not returning) a POST value, but from a display point of view it looks like a toggle button.
The colours may not be to your liking, they're only there to illustrate a point.
The HTML is:
<input type="checkbox" class="yesno" id="testcb" /><label for="testcb"><span></span></label>
...and the CSS is:
/* --------------------------------- */
/* Make the checkbox non-displayable */
/* --------------------------------- */
input[type="checkbox"].yesno {
display:none;
}
/* --------------------------------- */
/* Set the associated label <span> */
/* the way you want it to look. */
/* --------------------------------- */
input[type="checkbox"].yesno+label span {
display:inline-block;
width:80px;
height:30px;
text-align:center;
vertical-align:middle;
color:#800000;
background-color:white;
border-style:solid;
border-width:1px;
border-color:black;
cursor:pointer;
}
/* --------------------------------- */
/* By default the content after the */
/* the label <span> is "No" */
/* --------------------------------- */
input[type="checkbox"].yesno+label span:after {
content:"No";
}
/* --------------------------------- */
/* When the box is checked the */
/* content after the label <span> */
/* is "Yes" (which replaces any */
/* existing content). */
/* When the box becomes unchecked the*/
/* content reverts to the way it was.*/
/* --------------------------------- */
input[type="checkbox"].yesno:checked+label span:after {
content:"Yes";
}
/* --------------------------------- */
/* When the box is checked the */
/* label <span> looks like this */
/* (which replaces any existing) */
/* When the box becomes unchecked the*/
/* layout reverts to the way it was. */
/* --------------------------------- */
input[type="checkbox"].yesno:checked+label span {
color:green;
background-color:#C8C8C8;
}
I've only tried it on Firefox, but it's standard CSS so it ought to work elsewhere.
Using a pseudo element, this method doesn't require knowledge of the original element and doesn't require any additional markup.
#someElement{
color: transparent; /* You may need to change this color */
position: relative;
}
#someElement:after { /* Or use :before if that tickles your fancy */
content: "New text";
color: initial;
position: absolute;
top: 0;
left: 0;
}
I had an issue where I had to replace the text of link, but I couldn't use JavaScript nor could I directly change the text of a hyperlink as it was compiled down from XML. Also, I couldn't use pseudo elements, or they didn't seem to work when I had tried them.
Basically, I put the text I wanted into a span and put the anchor tag underneath it and wrapped both in a div. I basically moved the anchor tag up via CSS and then made the font transparent. Now when you hover over the span, it "acts" like a link. A really hacky way of doing this, but this is how you can have a link with different text...
This is a fiddle of how I got around this issue
My HTML
<div class="field">
<span>This is your link text</span><br/>
This is your actual link
</div>
My CSS
div.field a {
color: transparent;
position: absolute;
top:1%;
}
div.field span {
display: inline-block;
}
The CSS will need to change based off your requirements, but this is a general way of doing what you are asking.
I found a solution like this where a word, "Dark", would be shortened to just "D" on a smaller screen width. Basically you just make the font size of the original content 0 and have the shortened form as a pseudo element.
In this example the change happens on hover instead:
span {
font-size: 12px;
}
span:after {
display: none;
font-size: 12px;
content: 'D';
color: red;
}
span:hover {
font-size: 0px;
}
span:hover:after {
display: inline;
}
<span>Dark</span>
After eight years, I faced the same challenge when trying to use the Stylish browser extension to change something on a website (not mine). And this time I made it work by looking at the source code using "inspect element" and created the CSS code based on that.
This it what it looked like before:
<table>
<tbody>
<tr>
<td role="gridcell">
<span title="In progress" style="background-color: #e2047a;color:White;margin:2px;border-radius:2px;padding-left: 2px; padding-right: 2px;text-align: center;width: 45px; display: block;overflow: hidden;text-overflow: ellipsis;">In progress</span>
</td>
</tr>
</tbody>
</table>
This is the same piece of the HTML and the CSS I used to modify the style:
td span[style="background-color: #e2047a;color:White;margin:2px;border-radius:2px;padding-left: 2px; padding-right: 2px;text-align: center;width: 45px; display: block;overflow: hidden;text-overflow: ellipsis;"] {
width: 100px!important;
}
<table>
<tbody>
<tr>
<td role="gridcell">
<span title="In progress" style="background-color: #e2047a;color:White;margin:2px;border-radius:2px;padding-left: 2px; padding-right: 2px;text-align: center;width: 45px; display: block;overflow: hidden;text-overflow: ellipsis;">In progress</span>
</td>
</tr>
</tbody>
</table>
You can run the code above and you will see that it works (tested in Chrome).
This is simply what I wanted back in the days when I asked this question.
I was using some sort of community blog/Myspace similar stuff and the only thing you had when styling your profile was their CSS editor, and that's why I wanted to select it based on the style.
I found the answer here:
Advanced CSS Selector - Select based on styling
CSS selector by inline style attribute
Unlike what I see in every single other answer, you don't need to use pseudo elements in order to replace the content of a tag with an image
<div class="pvw-title">Facts</div>
div.pvw-title { /* No :after or :before required */
content: url("your URL here");
}
Well, as many said this is a hack. However, I'd like to add more up-to-date hack, which takes an advantage of flexbox and rem, i.e.
You don't want to manually position this text to be changed, that's why you'd like to take an advantage of flexbox
You don't want to use padding and/or margin to the text explicitly using px, which for different screen sizes on different devices and browsers might give different output
Here's the solution, in short flexbox makes sure that it's automatically positioned perfectly and rem is more standardized (and automated) alternative for pixels.
CodeSandbox with code below and output in a form of a screenshot, do please read a note below the code!
h1 {
background-color: green;
color: black;
text-align: center;
visibility: hidden;
}
h1:after {
background-color: silver;
color: yellow;
content: "This is my great text AFTER";
display: flex;
justify-content: center;
margin-top: -2.3rem;
visibility: visible;
}
h1:before {
color: blue;
content: "However, this is a longer text to show this example BEFORE";
display: flex;
justify-content: center;
margin-bottom: -2.3rem;
visibility: visible;
}
Note: for different tags you might need different values of rem, this one has been justified for h1 and only on large screens. However with #media you could easily extend this to mobile devices.
Example
<!DOCTYPE html>
<html>
<head>
<title>Devnote</title>
<style>
.replacedValue {
visibility: hidden;
position: relative;
}
.replacedValue:after {
visibility: visible;
position: absolute;
top: 0;
left: 0;
content: "Devnote is developer answer solve. devnote.in";
}
</style>
</head>
<body>
<p class="replacedValue">Old Text Here</p>
</body>
</html>
Output
Devnote is developer answer solve. devnote.in
This isn't really possible without tricks. Here is a way that works by replacing the text with an image of text.
.pvw-title{
text-indent: -9999px;
background-image: url(text_image.png)
}
This type of thing is typically done with JavaScript. Here is how it can be done with jQuery:
$('.pvw-title').text('new text');
The way to make this work is to add line-height to the CSS content. This will make the block to be seen above the hidden, thus this will not hide the changed text.
Example with use before:
.pvw-title span {
display: none;
}
.pvw-title:before {
content: 'Whatever it is you want to add';
line-height: 1.5em
}
How can I replace text with CSS using a method like this:
.pvw-title img[src*="IKON.img"] { visibility:hidden; }
Instead of ( img[src*="IKON.img"] ), I need to use something that can replace text instead.
I have to use [ ] to get it to work.
<div class="pvw-title">Facts</div>
I need to replace "Facts".
Or maybe you could wrap 'Facts' round a <span> as follows:
.pvw-title span {
display: none;
}
.pvw-title:after {
content: 'whatever it is you want to add';
}
<div class="pvw-title"><span>Facts</span></div>
Obligatory: This is a hack: CSS isn't the right place to do this, but in some situations - eg, you have a third party library in an iframe that can only be customized by CSS - this kind of hack is the only option.
You can replace text through CSS. Let's replace a green button that has the word 'hello' with a red button that has the word 'goodbye', using CSS.
Before:
After:
See http://jsfiddle.net/ZBj2m/274/ for a live demo:
Here's our green button:
<button>Hello</button>
button {
background-color: green;
color: black;
padding: 5px;
}
Now let's hide the original element, but add another block element afterwards:
button {
visibility: hidden;
}
button:after {
content:'goodbye';
visibility: visible;
display: block;
position: absolute;
background-color: red;
padding: 5px;
top: 2px;
}
Note:
We explicitly need to mark this as a block element, 'after' elements are inline by default
We need to compensate for the original element by adjusting the pseudo-element's position.
We must hide the original element and display the pseudo element using visibility. Note display: none on the original element doesn't work.
If you're willing to use pseudo elements and let them insert content, you can do the following. It doesn't assume knowledge of the original element and doesn't require additional markup.
.element {
text-indent: -9999px;
line-height: 0; /* Collapse the original line */
}
.element::after {
content: "New text";
text-indent: 0;
display: block;
line-height: initial; /* New content takes up original line height */
}
JSFiddle Example
Based on
mikemaccana’s answer,
this worked for me
button {
position: absolute;
visibility: hidden;
}
button:before {
content: "goodbye";
visibility: visible;
}
<button>original</button>
§ Absolute positioning
an element that is positioned absolutely is taken out of the flow and thus
takes up no space when placing other elements.
This is simple, short, and effective. No additional HTML is necessary.
.pvw-title { color: transparent; }
.pvw-title:after {
content: "New Text To Replace Old";
color: black; /* set color to original text color */
margin-left: -30px;
/* margin-left equals length of text we're replacing */
}
I had to do this for replacing link text, other than home, for WooCommerce breadcrumbs
Sass/Less
body.woocommerce .woocommerce-breadcrumb > a[href$="/shop/"] {
color: transparent;
&:after {
content: "Store";
color: grey;
margin-left: -30px;
}
}
CSS
body.woocommerce .woocommerce-breadcrumb > a[href$="/shop/"] {
color: transparent;
}
body.woocommerce .woocommerce-breadcrumb > a[href$="/shop/"]&:after {
content: "Store";
color: #child-color-grey;
margin-left: -30px;
}
You can't, well, you can.
.pvw-title:after {
content: "Test";
}
This will insert content after the current content of the element. It doesn't actually replace it, but you can choose for an empty div, and use CSS to add all the content.
But while you more or less can, you shouldn't. Actual content should be put in the document. The content property is mainly intended for small markup, like quotation marks around text that should appear quoted.
In order to use after and hide the original content, you can use this hack:
.pvw-title {
font-size: 0;
}
.pvw-title:after {
font-size: 1rem;
content: 'I am a totally different piece of text!';
}
<div class="pvw-title">Facts</div>
Setting font-size to 0 makes the text disappear without removing the actual element from the viewport. Therefore, the :after selector works and should show on all browsers.
Try using :before and :after. One inserts text after HTML is rendered, and the other inserts before HTML is rendered. If you want to replace text, leave button content empty.
This example sets the button text according to the size of the screen width.
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
button:before {
content: 'small screen';
}
#media screen and (min-width: 480px) {
button:before {
content: 'big screen';
}
}
</style>
<body>
<button type="button">xxx</button>
<button type="button"></button>
</body>
Button text:
With :before
big screenxxx
big screen
With :after
xxxbig screen
big screen
I had better luck setting the font-size: 0 of the outer element, and the font-size of the :after selector to whatever I needed.
If you just want to show different texts or images, keep the tag empty and write your content in multiple data attributes like that <span data-text1="Hello" data-text2="Bye"></span>.
Display them with one of the pseudo classes :before {content: attr(data-text1)}
Now you have a bunch of different ways to switch between them. I used them in combination with media queries for a responsive design approach to change the names of my navigation to icons.
jsfiddle demonstration and examples
It may not perfectly answer the question, but it satisfied my needs and maybe others too.
Text replacement with pseudo-elements and CSS visibility
HTML
<p class="replaced">Original Text</p>
CSS
.replaced {
visibility: hidden;
position: relative;
}
.replaced:after {
visibility: visible;
position: absolute;
top: 0;
left: 0;
content: "This text replaces the original.";
}
The simplest way I found is by making the element font-size: 0px, then overwrite it with any font size when creating :after pseudo. Example below:
.pvw-title {
font-size:0px;
}
.pvw-title:after {
content: "Hello";
font-size:15px !important;
}
This worked for me with inline text. It was tested in Firefox, Safari, Chrome, and Opera.
<p>Lorem ipsum dolor sit amet, consectetur <span>Some Text</span> adipiscing elit.</p>
span {
visibility: hidden;
word-spacing: -999px;
letter-spacing: -999px;
}
span:after {
content: "goodbye";
visibility: visible;
word-spacing: normal;
letter-spacing: normal;
}
I use this trick:
.pvw-title {
text-indent: -999px;
}
.pvw-title:after {
text-indent: 0px;
float: left;
content: 'My New Content';
}
I've even used this to handle internationalization of pages by just changing a base class...
.translate-es .welcome {
text-indent: -999px;
}
.translate-es .welcome:after {
text-indent: 0px;
float: left;
content: '¡Bienvenidos!';
}
Try this way:
IDENTIFIER {
visibility: hidden;
position: relative;
}
IDENTIFIER::after {
visibility: visible;
position: absolute;
top: 0;
left: 0;
content: "NEW_CONTENT";
}
This implements a checkbox as a button which shows either Yes or No depending on its 'checked' state. So it demonstrates one way of replacing text using CSS without having to write any code.
It will still behave like a checkbox as far as returning (or not returning) a POST value, but from a display point of view it looks like a toggle button.
The colours may not be to your liking, they're only there to illustrate a point.
The HTML is:
<input type="checkbox" class="yesno" id="testcb" /><label for="testcb"><span></span></label>
...and the CSS is:
/* --------------------------------- */
/* Make the checkbox non-displayable */
/* --------------------------------- */
input[type="checkbox"].yesno {
display:none;
}
/* --------------------------------- */
/* Set the associated label <span> */
/* the way you want it to look. */
/* --------------------------------- */
input[type="checkbox"].yesno+label span {
display:inline-block;
width:80px;
height:30px;
text-align:center;
vertical-align:middle;
color:#800000;
background-color:white;
border-style:solid;
border-width:1px;
border-color:black;
cursor:pointer;
}
/* --------------------------------- */
/* By default the content after the */
/* the label <span> is "No" */
/* --------------------------------- */
input[type="checkbox"].yesno+label span:after {
content:"No";
}
/* --------------------------------- */
/* When the box is checked the */
/* content after the label <span> */
/* is "Yes" (which replaces any */
/* existing content). */
/* When the box becomes unchecked the*/
/* content reverts to the way it was.*/
/* --------------------------------- */
input[type="checkbox"].yesno:checked+label span:after {
content:"Yes";
}
/* --------------------------------- */
/* When the box is checked the */
/* label <span> looks like this */
/* (which replaces any existing) */
/* When the box becomes unchecked the*/
/* layout reverts to the way it was. */
/* --------------------------------- */
input[type="checkbox"].yesno:checked+label span {
color:green;
background-color:#C8C8C8;
}
I've only tried it on Firefox, but it's standard CSS so it ought to work elsewhere.
Using a pseudo element, this method doesn't require knowledge of the original element and doesn't require any additional markup.
#someElement{
color: transparent; /* You may need to change this color */
position: relative;
}
#someElement:after { /* Or use :before if that tickles your fancy */
content: "New text";
color: initial;
position: absolute;
top: 0;
left: 0;
}
I had an issue where I had to replace the text of link, but I couldn't use JavaScript nor could I directly change the text of a hyperlink as it was compiled down from XML. Also, I couldn't use pseudo elements, or they didn't seem to work when I had tried them.
Basically, I put the text I wanted into a span and put the anchor tag underneath it and wrapped both in a div. I basically moved the anchor tag up via CSS and then made the font transparent. Now when you hover over the span, it "acts" like a link. A really hacky way of doing this, but this is how you can have a link with different text...
This is a fiddle of how I got around this issue
My HTML
<div class="field">
<span>This is your link text</span><br/>
This is your actual link
</div>
My CSS
div.field a {
color: transparent;
position: absolute;
top:1%;
}
div.field span {
display: inline-block;
}
The CSS will need to change based off your requirements, but this is a general way of doing what you are asking.
I found a solution like this where a word, "Dark", would be shortened to just "D" on a smaller screen width. Basically you just make the font size of the original content 0 and have the shortened form as a pseudo element.
In this example the change happens on hover instead:
span {
font-size: 12px;
}
span:after {
display: none;
font-size: 12px;
content: 'D';
color: red;
}
span:hover {
font-size: 0px;
}
span:hover:after {
display: inline;
}
<span>Dark</span>
After eight years, I faced the same challenge when trying to use the Stylish browser extension to change something on a website (not mine). And this time I made it work by looking at the source code using "inspect element" and created the CSS code based on that.
This it what it looked like before:
<table>
<tbody>
<tr>
<td role="gridcell">
<span title="In progress" style="background-color: #e2047a;color:White;margin:2px;border-radius:2px;padding-left: 2px; padding-right: 2px;text-align: center;width: 45px; display: block;overflow: hidden;text-overflow: ellipsis;">In progress</span>
</td>
</tr>
</tbody>
</table>
This is the same piece of the HTML and the CSS I used to modify the style:
td span[style="background-color: #e2047a;color:White;margin:2px;border-radius:2px;padding-left: 2px; padding-right: 2px;text-align: center;width: 45px; display: block;overflow: hidden;text-overflow: ellipsis;"] {
width: 100px!important;
}
<table>
<tbody>
<tr>
<td role="gridcell">
<span title="In progress" style="background-color: #e2047a;color:White;margin:2px;border-radius:2px;padding-left: 2px; padding-right: 2px;text-align: center;width: 45px; display: block;overflow: hidden;text-overflow: ellipsis;">In progress</span>
</td>
</tr>
</tbody>
</table>
You can run the code above and you will see that it works (tested in Chrome).
This is simply what I wanted back in the days when I asked this question.
I was using some sort of community blog/Myspace similar stuff and the only thing you had when styling your profile was their CSS editor, and that's why I wanted to select it based on the style.
I found the answer here:
Advanced CSS Selector - Select based on styling
CSS selector by inline style attribute
Unlike what I see in every single other answer, you don't need to use pseudo elements in order to replace the content of a tag with an image
<div class="pvw-title">Facts</div>
div.pvw-title { /* No :after or :before required */
content: url("your URL here");
}
Well, as many said this is a hack. However, I'd like to add more up-to-date hack, which takes an advantage of flexbox and rem, i.e.
You don't want to manually position this text to be changed, that's why you'd like to take an advantage of flexbox
You don't want to use padding and/or margin to the text explicitly using px, which for different screen sizes on different devices and browsers might give different output
Here's the solution, in short flexbox makes sure that it's automatically positioned perfectly and rem is more standardized (and automated) alternative for pixels.
CodeSandbox with code below and output in a form of a screenshot, do please read a note below the code!
h1 {
background-color: green;
color: black;
text-align: center;
visibility: hidden;
}
h1:after {
background-color: silver;
color: yellow;
content: "This is my great text AFTER";
display: flex;
justify-content: center;
margin-top: -2.3rem;
visibility: visible;
}
h1:before {
color: blue;
content: "However, this is a longer text to show this example BEFORE";
display: flex;
justify-content: center;
margin-bottom: -2.3rem;
visibility: visible;
}
Note: for different tags you might need different values of rem, this one has been justified for h1 and only on large screens. However with #media you could easily extend this to mobile devices.
Example
<!DOCTYPE html>
<html>
<head>
<title>Devnote</title>
<style>
.replacedValue {
visibility: hidden;
position: relative;
}
.replacedValue:after {
visibility: visible;
position: absolute;
top: 0;
left: 0;
content: "Devnote is developer answer solve. devnote.in";
}
</style>
</head>
<body>
<p class="replacedValue">Old Text Here</p>
</body>
</html>
Output
Devnote is developer answer solve. devnote.in
This isn't really possible without tricks. Here is a way that works by replacing the text with an image of text.
.pvw-title{
text-indent: -9999px;
background-image: url(text_image.png)
}
This type of thing is typically done with JavaScript. Here is how it can be done with jQuery:
$('.pvw-title').text('new text');
The way to make this work is to add line-height to the CSS content. This will make the block to be seen above the hidden, thus this will not hide the changed text.
Example with use before:
.pvw-title span {
display: none;
}
.pvw-title:before {
content: 'Whatever it is you want to add';
line-height: 1.5em
}
I'm currently working on a website design and need to make some changes to an advertisement. The CSS I apply to the main div (.ad_728x90_home) I'm targeting doesn't work. I have applied a margin-top to the div but that doesn't work, tried other CSS but it's not getting picked up.
Any help would be greatly appreciated! The advert is located below the second post.
.ad_728x90_home {
height: 130px;
}
.ad_728x90_home_text {
margin-top: 40px;
}
span.ad_728x90_home_h3text {
color: #FFFFFF;
float: left;
font-family: LeagueGothicRegular;
font-size: 23px;
line-height: 34px;
margin: 13px 0 22px 10px;
text-transform: uppercase;
width: 185px;
}
.ad_728x90_image {
float: right;
margin-right: 10px;
}
<div class="ad_728x90_home">
<div class="ad_728x90_home_text">
<span class="ad_728x90_home_h3text">Need more quality fonts? Head over to myfonts.com</span>
</div>
<div class="ad_728x90_image">
<img class="scale-with-grid" src="images/ad_728x90.jpg" alt="Blog Post" />
</div>
</div>
Be sure you have the right class names between .ad_728x90_home and .ad_728x90_home_text and double check your HTML nesting.
I checked your items with Chrome's inspect element and the <div class="ad_728x90_home_text"> seems to start above your ad, at the top of the page.
Try going to make it a position:relative as it seems like a main div element
.ad_728x90_home {
Postion:relative;
top:10px;}
I cannot say the exact pixel amount of it as the margin-top doesnt work try using it as relative.
What is the best (as in cross-browser) technique to do image replacement in CSS? I am using sprites to do my navigation, but I want the markup to remain SEO friendly. Given the following HTML structure...
<div id="menu">
<ul>
<li>Test</li>
<li>Tester</li>
<li>Testing Testing</li>
</ul>
</div>
What is the best way to replace the text with a background image using CSS only?
I am currently using this...
text-indent: -9999px;
But, it fails with CSS on, and images off.
If this is the html:
<div id="menu">
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
And this is the css:
#menu ul li a{
display: block;
overflow: hidden;
text-indent: -9999px;
background: transparent url(yourpicture.png) no-repeat 0 0;
width: 100px;
}
#home{
background-position: 0px 0px
}
#about{
background-position: -100px 0px
}
#contact{
background-position: -200px 0px
}
The image would then be 300px wide, and each tab would be 100px wide.
In 2008, Google's presentation at An Event Apart made it clear that valid image replacement will not be penalized by Google. See Mezzoblue's post about it
Basically, as long as the image you replace the text with has the same text in it, it will be considered valid and not trying to cheat search engines. How do they determine whether the image is valid or not? I have no idea... OCR? Manual review?
As far as CSS on/images off, there is no perfect solution, all of them require extra non-semantic markup. See the css-tricks link that beggs posted on the different techniques. I personally do not bother with the very small percentage of users who browse with CSS but no images.
Your choice is simple. Extra markup, or don't care about css on/images off.
The background image is usally applied to the <a> link, giving the entire clickable area an image. To hide the text you can use a very big negative value for text-indent.
I just came up with this, it seems to work in all modern browsers, I just tested it then on (IE8/compatibility, Chrome, Safari, Moz)
HTML
<img id="my_image" alt="my text" src="images/small_transparent.gif" />
CSS
#my_image{
background-image:url('images/my_image.png');
width:100px;
height:100px;}
Pro's:
image alt text is best-practice for accessibility/seo
no extra HTML markup, and the css is pretty minimal too
gets around the css on/images off issue where "text-indent" techniques still hide text for low bandwidth users
The biggest disadvantage that I can think of is the css off/images on situation, because you'll only send a transparent gif.
It might be possible to write a little javascript to help out with this, replacing all the image sources with their background-image css properties. But this would only work if the browsers still attaches css properties to elements and then ignores them. I don't know if this is the case or not, I'll have to test it out. You'd also want to develop a javascript-based test to see if css is being applied to the page (maybe check the position of some test element).
btw, I'd like to know, who uses images without stylesheets? some kind of mobile phone or something?
edit:
Based on comment below... inline styles hrm... maybe I should just make a php helper function like <?php echo css_image('image_id','my text','image_url');?> to generate some code like this:
HTML
<div id="image_id" style="background-image:url('image_url')" class="image">
<img src="image_url" class="alt_text" alt="my text" />
<p>my text</p>
</div><!--/#my_image-->
then just attach some CSS in the stylesheet
#image_id{width:*image width*;height:*image height*}
.alt_text{position:absolute;top:0px;left:0px}
.image{display:block;background-position:left top}
.image p{position:absolute;left:-9999em}
it's an older technique that I'm using, not sure where I found it though. It works with CSS on/images off, CSS off/images on, CSS on/images on.
If a user with CSS off/images off visits, they'll see doubled up text. If a search engine spider visits, they'll see alt text and regular text, an intelligent spider could easily identify this for what it is, an innocent image replacement technique.
So, this technique is worst for screen readers, since alt text is read, but these users should be able to skip to the next paragraph, which is why I stuck <p></p> around "my text".
Everyone else with both CSS and images turned off is some kind of bot, right?
#menu ul li a {
display: block;
background-image: url(images/someimage.png);
text-indent: -9000px;
width: 454px;
height: 64px;
}
The display:block is important or else your width and height may not look right.
This is the code I use for replacing logo text with an image while keeping the text in the code but not shown to the user (this is Google approved). View the completed example here:
http://discretiondesigns.com/overflow/imagereplacement/
Here's the full code (images can be found at the above link - images can be varying sizes - the entire image is clickable and changes upon hover):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Image Replacement</title>
<style type="text/css">
<!--
#menu li { list-style: none; }
#menu #a { font: .9em Verdana, Arial, Helvetica, sans-serif; color: #E9E7E0; height: 20px; width: 100px; padding-top: 8px; padding-left: 8px; float: left; }
#menu #a a { background: url(http://discretiondesigns.com/overflow/imagereplacement/a_off.gif) no-repeat left top; height: 20px; width: 100px; display: block; }
#menu #a a:hover { background: url(http://discretiondesigns.com/overflow/imagereplacement/a_on.gif); }
#menu #a span { display: none; }
#menu #b { font: .9em Verdana, Arial, Helvetica, sans-serif; color: #E9E7E0; height: 20px; width: 100px; padding-top: 8px; padding-left: 8px; float: left; }
#menu #b a { background: url(http://discretiondesigns.com/overflow/imagereplacement/b_off.gif) no-repeat left top; height: 20px; width: 100px; display: block; }
#menu #b a:hover { background: url(http://discretiondesigns.com/overflow/imagereplacement/b_on.gif); }
#menu #b span { display: none; }
#menu #c { font: .9em Verdana, Arial, Helvetica, sans-serif; color: #E9E7E0; height: 20px; width: 100px; padding-top: 8px; padding-left: 8px; float: left; }
#menu #c a { background: url(http://discretiondesigns.com/overflow/imagereplacement/c_off.gif) no-repeat left top; height: 20px; width: 100px; display: block; }
#menu #c a:hover { background: url(http://discretiondesigns.com/overflow/imagereplacement/c_on.gif); }
#menu #c span { display: none; }
-->
</style>
</head>
<body>
<div id="menu">
<ul>
<li id="a"><span>Nav A</span></li>
<li id="b"><span>Nav B</span></li>
<li id="c"><span>Nav C</span></li>
</ul>
</div>
</body>
</html>
This is touted to work no matter the settings of css/images:
http://www.tjkdesign.com/articles/tip.asp
CSS Tricks has one of the most detailed posts on the subject here
They show various techniques. The one that solves your problem of css on and images off is:
HTML:
CSS Tricks has one of the most detailed pages on the subject here
They show various techniques. The one that solves your problem of css on and images off is the technique #8:
HTML:
<div id="menu">
<ul>
<li><span></span>Test</li>
<li><span></span>Tester</li>
</ul>
</div>
CSS:
#menu a {
width: 350px; height: 75px; /*your values here*/
position: relative;
}
#menu a span {
background: url("images/li.jpg"); /*your image here*/
position: absolute;
width: 100%;
height: 100%;
}
EDIT: Updated the code to the sample provided.
PS: I didn't test the code above.
CSS:
#menu ul li a{
display: block;
background-image: url(http://example.com/sprite.png);
width: 100px;
height: 50px;
}
#a {
background-position: <offset for sprite>;
}
#b {
background-position: <offset for sprite>;
}
#c {
background-position: <offset for sprite>;
}
HTML:
<div id="menu">
<ul>
<li id="a">Test</li>
<li id="b">Tester</li>
<li id="c">Testing Testing</li>
</ul>
</div>
Edit: added the link text back in... 'cause it was missed. :-)