Hiding pseudo css element when data attribute is empty - css

I have the following badge that I can add to any element:
.notification-badge {
position: relative;
}
.notification-badge:after {
content:attr(data-badge);
position:absolute;
top:-10px;
right:-10px;
min-width: 10px;
padding: 3px 7px;
font-size: 12px;
font-weight: 700;
line-height: 1;
background-color: $brand-danger;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: middle;
border-radius: 10px;
border: 2px solid #fff;
}
It's fairly straightforward, the element that I attach the badge class onto provides a data-badge attribute with some number, which gets shoved into the :after element's content.
I would like the badge to not appear at all if content is empty. I've tried using the :empty selector, but it doesn't work because the actual tag may still contain other elements, for instance:
<a href="/cart" class="notification-badge" data-badge="">
<i class="fa fa-shopping-cart"></i>
</a>
In this case, I'd want the shopping cart icon and link to still exist, but have the notification-badge class not render the badge.
So, I suppose I could give up on the idea of it being a pure pseudo element and just make it a span with the number inside of it instead of a data- attribute, but it seems like there is probably an easy way to do this that I'm just not aware of.

This works for me:
.notification-badge:after {
visibility: hidden;
}
.notification-badge[data-badge]:after {
visibility: visible;
}

The :empty selector selector matches every element that has no children (including text nodes) W3Schools
So what you could do is here do something like this:
.notification-bade .fa-shopping-cart {visibility:visible}
.notification-badge:after {
content:attr(data-badge); visibility: hidden
}

Related

change the text "at" to "v" using css [duplicate]

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
}

Display second <span> element in front of first

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>

Is there a way to rename the nth item in a list with CSS? [duplicate]

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
}

Decoration elements and Accessibility

I'm not sure how to deal with anything(except images) that is used for design/decoration only in terms of accessibility. For example, if in case like this I'll use an image, I'd simply use alt="" or use CSS background image, so the AT for example will ignore it. But what if I'm using some <div> or anything else? It can be a div with some CSS styling that is presented in a code-way, instead of image, or it can be some text with CSS styling so it will be just for decoration(instead of images), or really, anything else. How should I mark it so it will be ignored in a proper way by AT?
Simple example(for request):
<div><span>For Decoration</span></div>
div{
width:0; height:0;
border-bottom:116px solid #009;
border-left:500px solid #900;
margin:0 auto;
}
div span{
display:block;
position:absolute;
margin:0 auto;
left:0;
right:0;
width:150px;
color:#fff;
}
There are two solutions to this:
1) if you are using an empty tag such as a div with no text in it, the screen reader will ignore it automatically. You don't need to do anything in particular.
2) if you are using a tag with text inside you should: a) give it an aria-hidden="true" if you don't want the screen-reader to read the text or b) give it a role="presentation" if you do want the screen-reader to read the text but not announce it as a particular type of element.
-------------------
Based on the comments on this post I have added code below showing an example. It shows when you wouldn't need to do anything (the first and last div) and when you would want to use aria-hidden and role="presentation".
The top line is purely for decoration. Part of it is empty divs and part of it is text. The different words for "Hello" in the p tag should be seen but don't need to be read since they're purely ornamental which is why I am using role and aria-hidden on it.
.end {
display: inline-block;
width: 5%;
height: 20px;
border: 5px solid transparent;
}
.end-left {
border-left-color: #999;
border-top-color: #999;
}
.end-right {
border-right-color: #999;
border-top-color: #999;
}
.languages {
display: inline-block;
width: 80%;
text-align: center;
font-family: 'copperplate', 'century gothic';
color: #999;
}
.languages span {
display: inline-block;
width: 15%;
}
<div class="end end-left"></div>
<p class="languages" aria-hidden="true" role="presentation">
<span class="english">Hello</span>
<span class="french">Bonjour</span>
<span class="italian">Ciao</span>
<span class="spanish">Hola</span>
<span class="hinid">Namaste</span>
<span class="persian">Salaam</span>
</p>
<div class="end end-right"></div>
<h1>Languages</h1>
<p>Welcome to your first language lesson. You will learn how to speak fluently.</p>

Put the value of an input Button next to the button via css

I was wondering if this is possible:
if I have an input field:
<input type="button" value="some value" class="icon-button" />
and it is styled with gradient background, border, box-shadow, etc.
I want to have the button like an Icon with all its style and the value-text right next to it.
I thought of something like this, but it didn't work:
.icon-button{
display:block;
width: 25px;
height: 25px;
/* gradients, borders, shadows, etc. */
text-indent: 30px;
overflow: visible;
}
Any Idea? I know I could solve it with javascript, but I would like to know if there is a css way to do this.
I don't think you're going to achieve this (at least not very neatly) using an input. If you can amend your markup to use an actual button to submit though, it's pretty trivial:
<button type="submit">Some value</button>
CSS:
button {
line-height: 25px;
border: none;
background: transparent;
cursor: pointer;
}
button::before {
content: '';
display:inline-block;
vertical-align: middle;
width: 25px;
height: 25px;
margin-right: 3px;
/* gradients, borders, shadows, etc. */
background: red;
}
You could use a span rather than generated content if IE7 support is needed. This approach is not possible with an input, as that can't contain any elements, nor can it have generated content.
If you need to use an input, you could achieve the same thing by wrapping it in a span and styling that.

Categories

Resources