I use an arrow pointing in the direction that the content and sidebar will toggle to/from via a CSS pseudo-element. The code below is effectively a write mode however it is entirely possible to read CSS pseudo-element content
as well.
Since there is a bit involved I’ll also post the prerequisites (source: JAB Creations web platform JavaScript documentation, if anything missing look it up there) so those who wish to try it out can fairly quickly do so.
CSS
#menu a[href*='sidebar']::after {content: '2192' !important;}
JavaScript Use
css_rule_set('#menu a[href*="sidebar"]::after','content','"u2192"','important');
JavaScript Prerequisites
var sidebar = 20;
function id_(id)
{
return (document.getElementById(id)) ? document.getElementById(id) : false;
}
function css_rule_set(selector,property,value,important)
{
try
{
for (var i = 0; i<document.styleSheets.length; i++)
{
var ss = document.styleSheets[i];
var r = ss.cssRules ? ss.cssRules : ss.rules;
for (var j = 0; j<r.length; j++)
{
if (r[j].selectorText && r[j].selectorText==selector)
{
if (typeof important=='undefined') {r[j].style.setProperty(property,value);}
else {r[j].style.setProperty(property,value,'important');}
break;
}
}
}
}
catch(e) {if (e.name !== 'SecurityError') {console.log('Developer: '+e);}}
}
function sidebar_toggle()
{
if (id_('menu_mobile')) {id_('menu_mobile').checked = false;}
if (getComputedStyle(id_('side')).getPropertyValue('display') == 'none')
{
css_rule_set('#menu a[href*="sidebar"]::after','content','"u2192"','important');
if (is_mobile())
{
css_rule_set('main','display','none','important');
css_rule_set('#side','width','100%','important');
css_rule_set('#side','display','block','important');
}
else
{
css_rule_set('main','width',(100 - sidebar)+'%');
css_rule_set('#side','display','block');
}
}
else
{
css_rule_set('#menu a[href*="sidebar"]::after','content','"u2190"','important');
if (is_mobile())
{
css_rule_set('main','display','block','important');
css_rule_set('main','width','100%','important');
css_rule_set('#side','display','none','important');
}
else
{
css_rule_set('main','width','100%','important');
css_rule_set('#side','display','none');
}
}
Кароч к самому псевдоэлементу нельза,но можно в элементе,где :after создать с помощью css свойства content: в котором создать селектор с помощью метода attr(data-название селектора ).то есть получиться например content:attr(data-el); а затем обратиться к нему из js var a = this.dataset.el,т таким макаром сможешь переопределить или добавить новые свойства элементу:after.только так.
К сожалению, обратиться к псевдоэлементу из js нельзя. Это Shadow DOM, он из js не виден.
мой способ это при нажатии на кнопку в элементе добавлять ему еще один класс и в css указать условие при котором твой псевдоэлемент будет изменяться как только присвоится второй класс и выполнится условие, на бумаге выглядит так:
*HTML*
div class=»first»
*STYLE*
.first {
background: red
}
.first.second::after {
*тут стили*
}
*JS*
let div = document.querySelector(«.first»);
div.addEventListener(‘click’, function () {
div.classlist.toggle(«second»);
}
способ с классами универсальный и решает множество проблем занимая меньше времени хоть и не выглядит современным чтоли
So this title you are looking at — Yes its an actual stackoverflow question.The question has 980 upvotes and it’s top answer has 723 upvotes. Then the question arises, why write an article about it then. Well, for starters I really wanted to answer this question, but since I didnt have enough «reputations»,this article is my way of letting people know of this new easy method.
First things first
Scenerio 1:
Imagine you want to grab an element using JavaScript and change its color using JavaScript. Its pretty easy, here we go:
//HTML
<div id="text">Hey there !</div>
//CSS
#text{
color: red;
}
//JS
const text = document.getElementById('text');
text.style.color = 'blue';
Enter fullscreen mode
Exit fullscreen mode
Scenerio 2:
This time we create a :before
pseudo element on the #text
element and then try to change the pseudo element’s background color. So lets see what happens here:
- Create a basic pseudo element with the styling(if you are new to creating a pseudo element, I suggest you learn that first and come back here):
//CSS
#text{
color: red;
position: relative;
}
#text:before{
position: absolute;
height: 25px;
width: 100px;
background: black;
top: -30px;
left: 0;
content: "";
}
Enter fullscreen mode
Exit fullscreen mode
- Now just a little twist to this, instead of using black as the background color, we are gonna create a
:root
element in our CSS file inside which we will create a variable ‘—pseudo-backgroundcolor’ with a value of ‘red’ and use this varible as the value for ‘background’ as shown below.
//CSS
:root{
--pseudo-backgroundcolor: red;
}
#test:before{
background: var(--pseudo-backgroundcolor);
}
Enter fullscreen mode
Exit fullscreen mode
- So by now I hope you are getting some hint of where I am heading. No ? Okay, let me explain. Our goal is simple, we should create a global background color variable and with the help of JavaScript we will grab the root value of the variable and update it using JavaScript so that the effect will be applied to the pseudo elements background color style automatically.
Lets get to work:
//JS
const root = document.querySelector(":root"); //grabbing the root element
**important part below**
root.style.setProperty("--pseudo-backgroundcolor", 'green');
Enter fullscreen mode
Exit fullscreen mode
So as you can see, we grabbed the --pseudo-backgroundcolor
varible and used setProperty
function to first select the variable and then set its color value from red to green. This is pretty much the code we need.So now if we ever need to change the color, you can just do this dynamically.An example would be to create a button and on click of that button, you can loop through an array of different colors and apply it to this varible.
In the stackoverflow answer, you can see other right ways too, but they just seemed a bit long, while this one just needs you to set the root variable and just write some JS code.
BONUS PART:
Suppose you want to add a text to a pseudo element — we usually add text using the content = ""
property.So instead of «» , just create a root variable like we did above and manipulate it using one line of JavaScript.Here’s the code:
//CSS
:root{
--pseudo-text: "just some text";
}
#text:before {
content: var(--pseudo-text);
}
//JS
root.style.setProperty("--pseudo-text", `"YAY new text"`);
//**!! Dont forget to add the 'double quotes' around this new text above or else you can't see any changes
Enter fullscreen mode
Exit fullscreen mode
So thats it, Hope you learned something new today or even saved time finding this solution. I got to find this solution while I was making my app — PrettyCover — which you can use to create Beautiful Cover Images for your blogs.In fact, I have made this cover image using PrettyCover. I would appreciate if you could go and try it out, and if you like it, don’t forget to ⭐ the repo.
Also, here is the codePen containing the full example codes: https://codepen.io/ridzman/pen/poEgPGq?editors=0011
And as always ending the article with a Gif. Please do let me know if there are any corrections or clarifications to be made. Ciao !
Since they’re not part of the DOM, CSS pseudo-elements can’t be selected and edited with JavaScript the same way as traditional elements on a page. I ended up going a different route by selecting the regular elements, creating CSS rules for their pseudo elements, and injecting those them into the page.
The Design
One of my recent projects involved creating 10 sections that follow a similar layout. Each section was distinguished by a numbered tab that was incrementally offset to the right of the previous section’s tab.
To create each section’s tabs, I absolutely positioned a ::before
pseudo-element at the top of the section. One way to accomplish the design would have been to hardcode the text and numbers in each tab individually and do the same with positioning in the stylesheet. However, I wanted to generate these numbered tabs and their positions programmatically since they followed a reproducible pattern.
The Problem
In the stylesheets, I added the base styles of each section and their pseudo-element tabs.
What I wanted to do with JavaScript was to run through a loop of all 10 tabs so I could add tab numbers to the content
attribute and change their horizontal positions.
JavaScript allowed me to select my pseudo elements with the getComputedStyle
method and retrieve specific values.
window.getComputedStyle(
document.querySelector('section'), ':before'
).getPropertyValue('left')
However, I quickly came to find that it wasn’t possible to target and manipulate pseudo-elements as they’re not part of the DOM.
The Solution
With a little help from some Stack Overflow threads, I learned that the best solution for my situation was to loop through each of my section
elements, create CSS rules for each pseudo-element, and then insert the rules inside a style
tag in the head of the site.
I started with an empty string called cssRules
, and a number value of 7.5
which was used as the initial left
position of the tabs. This number was also what each subsequent tab would be incremented by in the for loop. An empty variable, newLeftPosition
was used to store the new, calculated left
position of each tab in the index.
Within the for loop, the index of each element was used to multiply by 7.5
to give the element a left
position. The index was also used to print the number of the tab by way of the pseudo-element’s content
property. Both of these properties were assigned to numbered classes that corresponded to each section (e.g. .section-1
, .section-2
, .section-3
) and then added to the cssRules
string.
;(function() {
var cssRules = '',
origLeftPosition = 7.5,
newLeftPosition
$('section').each(function(i) {
newLeftPosition = origLeftPosition * (i + 1)
cssRules += '.section-' + (i + 1) + "::before{content:'Tab " + (i + 1) + "';left:" + newLeftPosition + 'vw;}'
})
$('head').append('<style>' + cssRules + '</style>')
})()
The cssRules
string contained the rules for all section::before
pseudo-elements. These were then appended inside of a style
tag to the head of the page, which rendered like this:
<style>.section-1::before{content:'Tab 1';left:7.5vw;}.section-2::before{content:'Tab 2';left:15vw;}.section-3::before{content:'Tab 3';left:22.5vw;}.section-4::before{content:'Tab 4';left:30vw;}.section-5::before{content:'Tab 5';left:37.5vw;}.section-6::before{content:'Tab 6';left:45vw;}.section-7::before{content:'Tab 7';left:52.5vw;}.section-8::before{content:'Tab 8';left:60vw;}.section-9::before{content:'Tab 9';left:67.5vw;}.section-10::before{content:'Tab 10';left:75vw;}</style>
It might have taken me a little longer to figure out how to generate this design element programmatically instead of just individually typing each pseudo-elements’s different properties, but I’m pleased with the outcome, the challenge this small hurdle posed, and the knowledge gained along the way.
So I’ve been work on a CSS selector engine, and I want to support pseudo-elements (::before, ::after, ::selection, ::first-line, etc). I noticed Slick, Sizzle, and some other popular engines seem to support them, but when looking through their code I found no code for it (now granted, I didn’t look that hard). Does anyone know how they do it or some way I could do it?
BoltClock
695k159 gold badges1384 silver badges1352 bronze badges
asked Apr 8, 2011 at 17:30
4
Here’s a simple way to find them in Webkit using jQuery, can fairly easily be converted to standard JS:
$('*').filter(function(){return getComputedStyle(this, ':before').length != 0});
For Gecko based browsers you need something a little different (haven’t tested in IE). Hope this helps
answered Aug 11, 2011 at 7:17
AlexAlex
3441 silver badge10 bronze badges
4