How can I replace text with CSS?

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.

Facts
I need to replace "Facts".

16.9k 5 5 gold badges 84 84 silver badges 106 106 bronze badges asked Oct 25, 2011 at 21:58 5,030 3 3 gold badges 16 16 silver badges 16 16 bronze badges

The question is how to do it with CSS. I am using a CMS that only allows me to change the CSS, which is why I arrived at this page while googling for the answer, and not a different one. That is why we answer the question that was asked instead of asking why the asker's situation isn't different.

Commented Apr 19, 2017 at 3:37 If anybody else is as clueless as I am: FOUC Commented May 30, 2022 at 12:58

26 Answers 26

Or maybe you could wrap 'Facts' round a as follows:

.pvw-title span < display: none; >.pvw-title:after
Facts
14.4k 24 24 gold badges 114 114 silver badges 167 167 bronze badges answered Dec 18, 2012 at 21:03 Matthew Cachia Matthew Cachia 4,644 1 1 gold badge 14 14 silver badges 17 17 bronze badges Nice, but that's a change to HTML rather than just CSS. Commented Jan 10, 2013 at 15:58 Sometimes its your only option Commented Feb 6, 2014 at 20:49 span < display: none; >should also hide the pseudo element. You should use visibility: hidden instead Commented Aug 18, 2014 at 6:16 display: none; and visibility: hidden; both hide the pseudo element Commented Feb 23, 2015 at 14:20

@Mathew is hiding the span but adding the pseudo element to the div, so the pseudo element should not be hidden (either by using visibility or display property)

Commented Jun 5, 2015 at 17:19

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

Here's our green button:

button

After

Now let's hide the original element, but add another block element afterwards:

button < background-color: green; color: black; padding: 5px; >/* Bonus CSS to do cool things */ button < visibility: hidden; >button:after
answered Jan 10, 2013 at 15:55 mikemaccana mikemaccana 121k 108 108 gold badges 420 420 silver badges 521 521 bronze badges This doesn't work in ie 10, any idea how to modify it to do so? Commented Jul 21, 2013 at 3:02

display: none; doesn’t work because ::after really means “inside this element, but at the end”, in case anyone was curious.

Commented Jun 30, 2014 at 22:17

Unfortunately, the "modified" button does not work like a button anymore. It's a good example, just that it does not apply to a button.

Commented Aug 18, 2014 at 6:18 display: none; and visibility: hidden; both hide the pseudo element Commented Feb 23, 2015 at 14:20

Indeed this hack is not universal. You have to take into account that the resulting element will retain the dimensions of the original element. So your replacement text should be the same width/height.

Commented Feb 13, 2020 at 11:23

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 */ >
answered Feb 26, 2014 at 22:14 James van Dyke James van Dyke 4,980 3 3 gold badges 29 29 silver badges 25 25 bronze badges

This answer works in places that a number of the other answers don't such as text nodes inside a element.

Commented Apr 8, 2014 at 13:23

This works well. In my case, line-height: 0 and color: transparent on the main element and resetting those values on the pseudo do the job (no fiddling with text-indent )

Commented Jun 9, 2014 at 21:38 Shouldn't it be line-height: normal instead of initial ? Commented Nov 27, 2014 at 15:10

the reason to use text-indent is that if the original text is longer, the element remains the size of the old text, not shrinking to the size of the new text (assuming that is what you want)

Commented Jul 9, 2015 at 20:34 The text-indent: -9999px; works on IE. Whereas the visibility: hidden; method doesn't work on IE. Commented Oct 29, 2015 at 16:10

Based on mikemaccana’s answer, this worked for me

button < position: absolute; visibility: hidden; >button:before

an element that is positioned absolutely is taken out of the flow and thus takes up no space when placing other elements.

147k 48 48 gold badges 268 268 silver badges 282 282 bronze badges answered Jun 18, 2013 at 3:51

For me this answer was superior to others because it works with a text replacement within the same line, that is, it does not force a line break in text (for my particular combination of HTML and CSS).

Commented May 23, 2015 at 21:40

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
31.6k 22 22 gold badges 109 109 silver badges 132 132 bronze badges answered Apr 16, 2015 at 18:16 3,752 1 1 gold badge 35 35 silver badges 33 33 bronze badges

In order to use after and hide the original content, you can use this hack:

.pvw-title < font-size: 0; >.pvw-title:after
Facts

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.

answered Jun 29, 2021 at 22:42 Thatkookooguy Thatkookooguy 6,964 1 1 gold badge 32 32 silver badges 59 59 bronze badges

You can't, well, you can.

.pvw-title:after

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.

answered Oct 25, 2011 at 22:02 116k 19 19 gold badges 183 183 silver badges 211 211 bronze badges

I'm very sure about that I used a code to replace text with kind of that method.. ' Commented Oct 25, 2011 at 22:11

How widely compatible is that for browsers? And i suspect javascript is going to be a better choice long term for this kind of flexibility.

Commented Aug 2, 2013 at 23:29

Modern browsers support it. I'm not sure about older IE versions, but I guess that can be looked up on quirksmode.com. -edit- It can: quirksmode.org/css/user-interface/content.html

Commented Aug 3, 2013 at 16:34

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.

button:before < content: 'small screen'; >@media screen and (min-width: 480px) < button:before < content: 'big screen'; >>
  1. With :before big screenxxx big screen
  2. With :after xxxbig screen big screen
6,964 1 1 gold badge 32 32 silver badges 59 59 bronze badges answered Sep 12, 2016 at 17:14 51.6k 25 25 gold badges 248 248 silver badges 214 214 bronze badges

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
answered Feb 26, 2021 at 19:44 979 9 9 silver badges 12 12 bronze badges

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.

answered Mar 3, 2017 at 16:34 4,959 13 13 gold badges 54 54 silver badges 75 75 bronze badges This works well. Here is a demo. Commented Dec 28, 2018 at 14:38 Smart use of font-size:0 - first time for me. Kudos! Commented Sep 8, 2021 at 20:42

If you just want to show different texts or images, keep the tag empty and write your content in multiple data attributes like that . Display them with one of the pseudo classes :before

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.

It may not perfectly answer the question, but it satisfied my needs and maybe others too.

31.6k 22 22 gold badges 109 109 silver badges 132 132 bronze badges answered Aug 7, 2016 at 10:26 Robbendebiene Robbendebiene 4,752 4 4 gold badges 32 32 silver badges 39 39 bronze badges

Text replacement with pseudo-elements and CSS visibility

.replaced < visibility: hidden; position: relative; >.replaced:after
1 1 1 silver badge answered Aug 16, 2018 at 0:25 Ahsan Aftab Ahsan Aftab 181 2 2 silver badges 6 6 bronze badges
IDENTIFIER < visibility: hidden; position: relative; >IDENTIFIER::after
answered Aug 31, 2021 at 1:45 Murtaza JAFARI Murtaza JAFARI 714 7 7 silver badges 12 12 bronze badges This doesn't work if the element is center aligned or not at the start of its bounding box Commented Oct 24, 2022 at 11:55

This worked for me with inline text. It was tested in Firefox, Safari, Chrome, and Opera.

Lorem ipsum dolor sit amet, consectetur Some Text adipiscing elit.

span < visibility: hidden; word-spacing: -999px; letter-spacing: -999px; >span:after
31.6k 22 22 gold badges 109 109 silver badges 132 132 bronze badges answered Aug 2, 2013 at 22:39 Noel Williams Noel Williams 109 1 1 silver badge 2 2 bronze badges

Doesn't work for me in at least IE 9 through 11 due to it ignoring the "visibility:visible" on the :after element: stackoverflow.com/questions/17530947/…

Commented Jun 20, 2014 at 0:14

I use this trick:

.pvw-title < text-indent: -999px; >.pvw-title:after

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
answered Jul 5, 2015 at 12:16 119 1 1 silver badge 3 3 bronze badges

This is problematic for users with screen readers. If you don't change the disaply/visibility of the element and don't provide any aria hints, your "invisible" text may still be read by a screen reader.

Commented Mar 8, 2016 at 17:20

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.

/* --------------------------------- */ /* Make the checkbox non-displayable */ /* --------------------------------- */ input[type="checkbox"].yesno < display:none; >/* --------------------------------- */ /* Set the associated label */ /* 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 is "No" */ /* --------------------------------- */ input[type="checkbox"].yesno+label span:after < content:"No"; >/* --------------------------------- */ /* When the box is checked the */ /* content after the label */ /* 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 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

I've only tried it on Firefox, but it's standard CSS so it ought to work elsewhere.