Is it possible to change a CSS pseudo-element style via JavaScript?
For example, I want to dynamically set the color of the scrollbar like so:
document.querySelector("#editor::-webkit-scrollbar-thumb:vertical").style.background = localStorage.getItem("Color");
and I also want to be able to tell the scrollbar to hide like so:
document.querySelector("#editor::-webkit-scrollbar").style.visibility = "hidden";
Both of these scripts, however, return:
Uncaught TypeError: Cannot read property ‘style’ of null
Is there some other way of going about this?
Cross-browser interoperability is not important, I just need it to work in webkit browsers.
Nakilon
34.6k14 gold badges106 silver badges140 bronze badges
asked Dec 19, 2010 at 3:41
1
If you’re comfortable with some graceful degradation in older browsers you can use CSS Vars. Definitely the easiest of the methods I’ve seen here and elsewhere.
So in your CSS you can write:
#editor {
--scrollbar-background: #ccc;
}
#editor::-webkit-scrollbar-thumb:vertical {
/* Fallback */
background-color: #ccc;
/* Dynamic value */
background-color: var(--scrollbar-background);
}
Then in your JS you can manipulate that value on the #editor element:
document.getElementById("#editor").style.setProperty('--scrollbar-background', localStorage.getItem("Color"));
Lots of other examples of manipulating CSS vars with JS here: https://eager.io/blog/communicating-between-javascript-and-css-with-css-variables/
answered Apr 18, 2018 at 20:29
Wes RuvalcabaWes Ruvalcaba
7661 gold badge5 silver badges3 bronze badges
6
To edit an existing one which you don’t have a direct reference to requires iterating all style sheets on the page and then iterating all rules in each and then string matching the selector.
Here’s a reference to a method I posted for adding new CSS for pseudo-elements, the easy version where you’re setting from js
Javascript set CSS :after styles
var addRule = (function (style) {
var sheet = document.head.appendChild(style).sheet;
return function (selector, css) {
var propText = typeof css === "string" ? css : Object.keys(css).map(function (p) {
return p + ":" + (p === "content" ? "'" + css[p] + "'" : css[p]);
}).join(";");
sheet.insertRule(selector + "{" + propText + "}", sheet.cssRules.length);
};
})(document.createElement("style"));
addRule("p:before", {
display: "block",
width: "100px",
height: "100px",
background: "red",
"border-radius": "50%",
content: "''"
});
sheet.insertRule
returns the index of the new rule which you can use to get a reference to it for it which can be used later to edit it.
answered Nov 8, 2011 at 13:55
5
EDIT: There is technically a way of directly changing CSS pseudo-element styles via JavaScript, as this answer describes, but the method provided here is preferable.
The closest to changing the style of a pseudo-element in JavaScript is adding and removing classes, then using the pseudo-element with those classes. An example to hide the scrollbar:
CSS
.hidden-scrollbar::-webkit-scrollbar {
visibility: hidden;
}
JavaScript
document.getElementById("editor").classList.add('hidden-scrollbar');
To later remove the same class, you could use:
document.getElementById("editor").classList.remove('hidden-scrollbar');
vhs
8,8013 gold badges64 silver badges70 bronze badges
answered Aug 31, 2012 at 0:47
Chris FritzChris Fritz
1,9041 gold badge19 silver badges23 bronze badges
5
I changed the background of the ::selection pseudo-element by using CSS custom properties doing the following:
/*CSS Part*/
:root {
--selection-background: #000000;
}
#editor::selection {
background: var(--selection-background);
}
//JavaScript Part
document.documentElement.style.setProperty("--selection-background", "#A4CDFF");
answered Feb 5, 2020 at 22:12
TazExprezTazExprez
2417 silver badges7 bronze badges
1
You can’t apply styles to psuedo-elements in JavaScript.
You can, however, append a <style>
tag to the head of your document (or have a placeholding <style id='mystyles'>
and change its content), which adjusts the styles. (This would work better than loading in another stylesheet, because embedded <style>
tags have higher precedence than <link>
‘d ones, making sure you don’t get cascading problems.
Alternatively, you could use different class names and have them defined with different psuedo-element styles in the original stylesheet.
answered Nov 8, 2011 at 5:44
I posted a question similar to, but not completely like, this question.
I found a way to retrieve and change styles for pseudo elements and asked what people thought of the method.
My question is at Retrieving or changing css rules for pseudo elements
Basically, you can get a style via a statement such as:
document.styleSheets[0].cssRules[0].style.backgroundColor
And change one with:
document.styleSheets[0].cssRules[0].style.backgroundColor = newColor;
You, of course, have to change the stylesheet and cssRules index. Read my question and the comments it drew.
I’ve found this works for pseudo elements as well as «regular» element/styles.
Christian
27.2k16 gold badges108 silver badges153 bronze badges
answered Oct 7, 2015 at 23:57
SimonTSimonT
4463 silver badges16 bronze badges
An old question, but one I came across when try to dynamically change the colour of the content of an element’s :before
selector.
The simplest solution I can think of is to use CSS variables, a solution not applicable when the question was asked:
"#editor::-webkit-scrollbar-thumb:vertical {
background: --editorScrollbarClr
}
Change the value in JavaScript:
document.body.style.setProperty(
'--editorScrollbarClr',
localStorage.getItem("Color")
);
The same can be done for other properties.
answered Jul 21, 2019 at 13:38
Lee GoddardLee Goddard
10.1k3 gold badges46 silver badges60 bronze badges
Looks like querySelector won’t work with pseudo-classes/pseudo-elements, at least not those. The only thing I can think of is to dynamically add a stylesheet (or change an existing one) to do what you need.
Lots of good examples here:
How do I load css rules dynamically in Webkit (Safari/Chrome)?
answered Dec 19, 2010 at 4:07
HemlockHemlock
6,0801 gold badge27 silver badges36 bronze badges
1
Is it possible to change a CSS pseudo-element style via JavaScript?
For example, I want to dynamically set the color of the scrollbar like so:
document.querySelector("#editor::-webkit-scrollbar-thumb:vertical").style.background = localStorage.getItem("Color");
and I also want to be able to tell the scrollbar to hide like so:
document.querySelector("#editor::-webkit-scrollbar").style.visibility = "hidden";
Both of these scripts, however, return:
Uncaught TypeError: Cannot read property ‘style’ of null
Is there some other way of going about this?
Cross-browser interoperability is not important, I just need it to work in webkit browsers.
Nakilon
34.6k14 gold badges106 silver badges140 bronze badges
asked Dec 19, 2010 at 3:41
1
If you’re comfortable with some graceful degradation in older browsers you can use CSS Vars. Definitely the easiest of the methods I’ve seen here and elsewhere.
So in your CSS you can write:
#editor {
--scrollbar-background: #ccc;
}
#editor::-webkit-scrollbar-thumb:vertical {
/* Fallback */
background-color: #ccc;
/* Dynamic value */
background-color: var(--scrollbar-background);
}
Then in your JS you can manipulate that value on the #editor element:
document.getElementById("#editor").style.setProperty('--scrollbar-background', localStorage.getItem("Color"));
Lots of other examples of manipulating CSS vars with JS here: https://eager.io/blog/communicating-between-javascript-and-css-with-css-variables/
answered Apr 18, 2018 at 20:29
Wes RuvalcabaWes Ruvalcaba
7661 gold badge5 silver badges3 bronze badges
6
To edit an existing one which you don’t have a direct reference to requires iterating all style sheets on the page and then iterating all rules in each and then string matching the selector.
Here’s a reference to a method I posted for adding new CSS for pseudo-elements, the easy version where you’re setting from js
Javascript set CSS :after styles
var addRule = (function (style) {
var sheet = document.head.appendChild(style).sheet;
return function (selector, css) {
var propText = typeof css === "string" ? css : Object.keys(css).map(function (p) {
return p + ":" + (p === "content" ? "'" + css[p] + "'" : css[p]);
}).join(";");
sheet.insertRule(selector + "{" + propText + "}", sheet.cssRules.length);
};
})(document.createElement("style"));
addRule("p:before", {
display: "block",
width: "100px",
height: "100px",
background: "red",
"border-radius": "50%",
content: "''"
});
sheet.insertRule
returns the index of the new rule which you can use to get a reference to it for it which can be used later to edit it.
answered Nov 8, 2011 at 13:55
5
EDIT: There is technically a way of directly changing CSS pseudo-element styles via JavaScript, as this answer describes, but the method provided here is preferable.
The closest to changing the style of a pseudo-element in JavaScript is adding and removing classes, then using the pseudo-element with those classes. An example to hide the scrollbar:
CSS
.hidden-scrollbar::-webkit-scrollbar {
visibility: hidden;
}
JavaScript
document.getElementById("editor").classList.add('hidden-scrollbar');
To later remove the same class, you could use:
document.getElementById("editor").classList.remove('hidden-scrollbar');
vhs
8,8013 gold badges64 silver badges70 bronze badges
answered Aug 31, 2012 at 0:47
Chris FritzChris Fritz
1,9041 gold badge19 silver badges23 bronze badges
5
I changed the background of the ::selection pseudo-element by using CSS custom properties doing the following:
/*CSS Part*/
:root {
--selection-background: #000000;
}
#editor::selection {
background: var(--selection-background);
}
//JavaScript Part
document.documentElement.style.setProperty("--selection-background", "#A4CDFF");
answered Feb 5, 2020 at 22:12
TazExprezTazExprez
2417 silver badges7 bronze badges
1
You can’t apply styles to psuedo-elements in JavaScript.
You can, however, append a <style>
tag to the head of your document (or have a placeholding <style id='mystyles'>
and change its content), which adjusts the styles. (This would work better than loading in another stylesheet, because embedded <style>
tags have higher precedence than <link>
‘d ones, making sure you don’t get cascading problems.
Alternatively, you could use different class names and have them defined with different psuedo-element styles in the original stylesheet.
answered Nov 8, 2011 at 5:44
I posted a question similar to, but not completely like, this question.
I found a way to retrieve and change styles for pseudo elements and asked what people thought of the method.
My question is at Retrieving or changing css rules for pseudo elements
Basically, you can get a style via a statement such as:
document.styleSheets[0].cssRules[0].style.backgroundColor
And change one with:
document.styleSheets[0].cssRules[0].style.backgroundColor = newColor;
You, of course, have to change the stylesheet and cssRules index. Read my question and the comments it drew.
I’ve found this works for pseudo elements as well as «regular» element/styles.
Christian
27.2k16 gold badges108 silver badges153 bronze badges
answered Oct 7, 2015 at 23:57
SimonTSimonT
4463 silver badges16 bronze badges
An old question, but one I came across when try to dynamically change the colour of the content of an element’s :before
selector.
The simplest solution I can think of is to use CSS variables, a solution not applicable when the question was asked:
"#editor::-webkit-scrollbar-thumb:vertical {
background: --editorScrollbarClr
}
Change the value in JavaScript:
document.body.style.setProperty(
'--editorScrollbarClr',
localStorage.getItem("Color")
);
The same can be done for other properties.
answered Jul 21, 2019 at 13:38
Lee GoddardLee Goddard
10.1k3 gold badges46 silver badges60 bronze badges
Looks like querySelector won’t work with pseudo-classes/pseudo-elements, at least not those. The only thing I can think of is to dynamically add a stylesheet (or change an existing one) to do what you need.
Lots of good examples here:
How do I load css rules dynamically in Webkit (Safari/Chrome)?
answered Dec 19, 2010 at 4:07
HemlockHemlock
6,0801 gold badge27 silver badges36 bronze badges
1
Is it possible to change a CSS pseudo-element style via JavaScript?
For example, I want to dynamically set the color of the scrollbar like so:
document.querySelector("#editor::-webkit-scrollbar-thumb:vertical").style.background = localStorage.getItem("Color");
and I also want to be able to tell the scrollbar to hide like so:
document.querySelector("#editor::-webkit-scrollbar").style.visibility = "hidden";
Both of these scripts, however, return:
Uncaught TypeError: Cannot read property ‘style’ of null
Is there some other way of going about this?
Cross-browser interoperability is not important, I just need it to work in webkit browsers.
Nakilon
34.6k14 gold badges106 silver badges140 bronze badges
asked Dec 19, 2010 at 3:41
1
If you’re comfortable with some graceful degradation in older browsers you can use CSS Vars. Definitely the easiest of the methods I’ve seen here and elsewhere.
So in your CSS you can write:
#editor {
--scrollbar-background: #ccc;
}
#editor::-webkit-scrollbar-thumb:vertical {
/* Fallback */
background-color: #ccc;
/* Dynamic value */
background-color: var(--scrollbar-background);
}
Then in your JS you can manipulate that value on the #editor element:
document.getElementById("#editor").style.setProperty('--scrollbar-background', localStorage.getItem("Color"));
Lots of other examples of manipulating CSS vars with JS here: https://eager.io/blog/communicating-between-javascript-and-css-with-css-variables/
answered Apr 18, 2018 at 20:29
Wes RuvalcabaWes Ruvalcaba
7661 gold badge5 silver badges3 bronze badges
6
To edit an existing one which you don’t have a direct reference to requires iterating all style sheets on the page and then iterating all rules in each and then string matching the selector.
Here’s a reference to a method I posted for adding new CSS for pseudo-elements, the easy version where you’re setting from js
Javascript set CSS :after styles
var addRule = (function (style) {
var sheet = document.head.appendChild(style).sheet;
return function (selector, css) {
var propText = typeof css === "string" ? css : Object.keys(css).map(function (p) {
return p + ":" + (p === "content" ? "'" + css[p] + "'" : css[p]);
}).join(";");
sheet.insertRule(selector + "{" + propText + "}", sheet.cssRules.length);
};
})(document.createElement("style"));
addRule("p:before", {
display: "block",
width: "100px",
height: "100px",
background: "red",
"border-radius": "50%",
content: "''"
});
sheet.insertRule
returns the index of the new rule which you can use to get a reference to it for it which can be used later to edit it.
answered Nov 8, 2011 at 13:55
5
EDIT: There is technically a way of directly changing CSS pseudo-element styles via JavaScript, as this answer describes, but the method provided here is preferable.
The closest to changing the style of a pseudo-element in JavaScript is adding and removing classes, then using the pseudo-element with those classes. An example to hide the scrollbar:
CSS
.hidden-scrollbar::-webkit-scrollbar {
visibility: hidden;
}
JavaScript
document.getElementById("editor").classList.add('hidden-scrollbar');
To later remove the same class, you could use:
document.getElementById("editor").classList.remove('hidden-scrollbar');
vhs
8,8013 gold badges64 silver badges70 bronze badges
answered Aug 31, 2012 at 0:47
Chris FritzChris Fritz
1,9041 gold badge19 silver badges23 bronze badges
5
I changed the background of the ::selection pseudo-element by using CSS custom properties doing the following:
/*CSS Part*/
:root {
--selection-background: #000000;
}
#editor::selection {
background: var(--selection-background);
}
//JavaScript Part
document.documentElement.style.setProperty("--selection-background", "#A4CDFF");
answered Feb 5, 2020 at 22:12
TazExprezTazExprez
2417 silver badges7 bronze badges
1
You can’t apply styles to psuedo-elements in JavaScript.
You can, however, append a <style>
tag to the head of your document (or have a placeholding <style id='mystyles'>
and change its content), which adjusts the styles. (This would work better than loading in another stylesheet, because embedded <style>
tags have higher precedence than <link>
‘d ones, making sure you don’t get cascading problems.
Alternatively, you could use different class names and have them defined with different psuedo-element styles in the original stylesheet.
answered Nov 8, 2011 at 5:44
I posted a question similar to, but not completely like, this question.
I found a way to retrieve and change styles for pseudo elements and asked what people thought of the method.
My question is at Retrieving or changing css rules for pseudo elements
Basically, you can get a style via a statement such as:
document.styleSheets[0].cssRules[0].style.backgroundColor
And change one with:
document.styleSheets[0].cssRules[0].style.backgroundColor = newColor;
You, of course, have to change the stylesheet and cssRules index. Read my question and the comments it drew.
I’ve found this works for pseudo elements as well as «regular» element/styles.
Christian
27.2k16 gold badges108 silver badges153 bronze badges
answered Oct 7, 2015 at 23:57
SimonTSimonT
4463 silver badges16 bronze badges
An old question, but one I came across when try to dynamically change the colour of the content of an element’s :before
selector.
The simplest solution I can think of is to use CSS variables, a solution not applicable when the question was asked:
"#editor::-webkit-scrollbar-thumb:vertical {
background: --editorScrollbarClr
}
Change the value in JavaScript:
document.body.style.setProperty(
'--editorScrollbarClr',
localStorage.getItem("Color")
);
The same can be done for other properties.
answered Jul 21, 2019 at 13:38
Lee GoddardLee Goddard
10.1k3 gold badges46 silver badges60 bronze badges
Looks like querySelector won’t work with pseudo-classes/pseudo-elements, at least not those. The only thing I can think of is to dynamically add a stylesheet (or change an existing one) to do what you need.
Lots of good examples here:
How do I load css rules dynamically in Webkit (Safari/Chrome)?
answered Dec 19, 2010 at 4:07
HemlockHemlock
6,0801 gold badge27 silver badges36 bronze badges
1
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 !
- Поменять или задать content для before или after
- Удалить :before или :after
- Скрипт, чтобы изменить псевдоэлементы у NodeList
- textarea и innerHTML в Internet Explorer
Недавно задалась вопросом: как динамически изменить стиль CSS в :before или :after у элемента с помощью JavaScript?
Поменять или задать content для before или after на JavaScript
Самое простое решение в одну строку:
<style> #raz:after { content: attr(data-after); background: yellow; } </style> <button onclick="this.dataset.after = ' мой after'" id="raz">нажать</button>
То есть для элемента создаём новый атрибут data-after, в котором пишем содержимое для content у after
Можно задать другой стиль CSS с дополнительным class, где content имеет значение none. Щелчок по кнопке будет присваивать этот class элементу.
<style> #element {background: #fff5d7; border: 5px solid #fff5d7;} #element:before {content: ":before"; border-bottom: solid brown;} #element.new:before {content: none;} </style> <button onclick="delBefore();">удалить</button> <div id="element"></div> <script> function delBefore() { var div = document.getElementById('element'); div.className = 'new'; } </script>
Скрипт, чтобы изменить псевдоэлементы у NodeList
А как быть, если вместо getElementById используется getElementsByName или querySelectorAll и т.п? Там работать нужно с массивом NodeList. Например, я хочу чтобы высота у :after каждого элемента составила четверть ширины элемента. Один класс на всех тут не подходит, поскольку ширина у элементов разная.
<style> #element {background: #fff5d7; border: 5px solid #fff5d7;} #element li {background: green;} #element li:nth-child(2) {background: blue; width: 30%; text-align: right;} #element li:after {content: ":after"; background: DarkSalmon; display: inline-block;} </style> <button onclick="borderWidth();">height = 1/4 ширины li</button> <ol id="element"> <li> <li> </ol> <script> function borderWidth() { [].forEach.call(document.querySelectorAll('#element li'), function(eLi) { eLi.dataset.width = eLi.offsetWidth/4; var style = document.createElement('style'); style.innerHTML = '#element li[data-width="' + eLi.dataset.width + '"]:after {height: ' + eLi.dataset.width + 'px;}'; document.querySelector('head').appendChild(style); }); } </script>
1. Причина:
Эта статья возникла в сообществе OSC, кто-то спросил, как использовать jq для получения псевдоэлементов. Моя первая мысль заключается в том, что мощный CSS-запрос должен иметь возможность получать псевдоэлементы.
Однако на самом деле CSS Query не может. То есть мы не можем получить псевдоэлемент: before через $ («: before»), $ (dom) .find («: before») или document.querySelector («: before»).
По этой причине мне нужно заново понять псевдоэлементы (псевдоэлементы). Почему вы не можете использовать JS для прямого получения псевдоэлементов?
Например, псевдоэлементы :: before и :: after используются для вставки содержимого в начало или конец элемента при визуализации CSS.Они не ограничены документом и не влияют на сам документ, а только на окончательный стиль. Этот добавленный контент не будет отображаться в DOM, а только добавлен в слой рендеринга CSS.
По факту,Псевдоэлементы могут отображаться браузером, но сами они не являются элементами DOM. Его нет в документе, поэтому JS не может напрямую управлять им.А селекторы jQuery основаны на элементах DOM, поэтому псевдоэлементы нельзя манипулировать напрямую.
Как управлять стилем псевдоэлемента?
По этой причине я решил резюмировать методы управления псевдоэлементами JS, чтобы облегчить их использование в будущем.
2. Что такое псевдоэлементы:
Для начала кратко поговорим о том, что такое псевдоэлементы. Всего шесть псевдоэлементов, а именно::after、::before、::first-line、::first-letter、::selection、::backdrop。
Наиболее часто используемые псевдоэлементы на основных веб-страницах — это :: after и :: before.
Чтобы узнать о семантике этих псевдоэлементов, обратитесь к другой моей статье «Сводка селектора псевдоэлементов CSS》。
В CSS3 рекомендуется, чтобы псевдоэлементы использовали синтаксис с двумя двоеточиями (: вместо одного двоеточия (:), чтобы различать псевдоклассы и псевдоэлементы. Большинство браузеров поддерживают эти два синтаксиса представления. Only :: selection всегда может начинаться с двух двоеточий (: :). Поскольку IE8 поддерживает только синтаксис с одним двоеточием, если вы хотите быть совместимым с IE8, безопасным способом является использование одного двоеточия.
3. Получите значение атрибута псевдоэлемента:
Получить значение атрибута псевдоэлемента можноwindow.getComputedStyle()Метод получения объекта объявления стиля CSS псевдоэлемента. Затем используйте метод getPropertyValue или напрямую используйте доступ «ключ-значение» для получения соответствующего значения свойства.
Синтаксис: window.getComputedStyle (element [, pseudoElement])
- Параметры следующие:
- element (Object): элемент DOM, в котором расположен псевдоэлемент;
- pseudoElement (String): тип псевдоэлемента. Необязательные значения: «: after», «: before», «: first-line», «: first-letter», «: selection», «: backdrop»;
Дайте каштан:
// код CSS
#myId:before {
content: "hello world!";
display: block;
width: 100px;
height: 100px;
background: red;
}
// HTML-код
<div id="myId"></div>
// JS код
var myIdElement = document.getElementById("myId");
var beforeStyle = window.getComputedStyle(myIdElement, ":before");
console.log(beforeStyle); // [CSSStyleDeclaration Object]
console.log(beforeStyle.width); // 100px
console.log(beforeStyle.getPropertyValue("width")); // 100px
console.log(beforeStyle.content); // "hello world!"
Примечания:
1.
И getPropertyValue (), и прямой доступ к объекту «ключ-значение» могут обращаться к объекту CSSStyleDeclaration. Различия между ними:
- Для атрибута float, если вы используете доступ «ключ-значение», вы не можете напрямую использовать getComputedStyle (element, null) .float, но должны быть cssFloat и styleFloat;
- Используйте доступ напрямую по ключу, ключ атрибута должен использовать верблюжий регистр, например: style.backgroundColor;
- Использование метода getPropertyValue () не обязательно должно выполняться в регистре верблюда (запись в регистре верблюда не поддерживается), например: style.getPropertyValue («border-top-color»);
- Метод getPropertyValue () поддерживается в IE9 + и других современных браузерах; в IE6 ~ 8 вместо него можно использовать метод getAttribute ();
2.
Псевдоэлемент по умолчанию — «display: inline». Если атрибут отображения не определен, даже если значение атрибута ширины явно установлено в CSS на фиксированный размер, например «100 пикселей», значение ширины, полученное в конце, все равно будет «автоматическим». Это связано с тем, что ширину и высоту встроенных элементов нельзя настроить. Решение состоит в том, чтобы изменить атрибут display псевдоэлемента на «block», «inline-block» или другое.
4. Измените стиль псевдоэлемента:
Метод 1. Измените класс, чтобы изменить значение атрибута псевдоэлемента:
Дайте каштан:
// код CSS
.red::before {
content: "red";
color: red;
}
.green::before {
content: "green";
color: green;
}
// HTML-код
<div class = "red"> контент контент контент контент </div>
// код jQuery
$(".red").removeClass('red').addClass('green');
Метод 2. Используйте insertRule CSSStyleSheet для изменения стиля псевдоэлементов:
Дайте каштан:
document.styleSheets [0] .addRule ('. red :: before', 'color: green'); // Поддержка IE document.styleSheets [0] .insertRule ('. red :: before {color: green}', 0); // Поддержка современных браузеров, отличных от IE
Способ 3. В<head>
Вставить в этикетку<style>
Внутренний стиль:
var style = document.createElement("style");
document.head.appendChild(style);
sheet = style.sheet;
sheet.addRule ('. red :: before', 'color: green'); // совместим с браузером IE
sheet.insertRule ('. red :: before {color: green}', 0); // Поддержка современных браузеров, отличных от IE
Или используйте jQuery:
$('<style>.red::before{color:green}</style>').appendTo('head');
5. Измените значение атрибута содержимого псевдоэлемента:
Метод 1. Используйте insertRule CSSStyleSheet для изменения стиля псевдоэлемента:
var latestContent = "Измененный контент";
var formerContent = window.getComputedStyle($('.red'), '::before').getPropertyValue('content'); document.styleSheets[0].addRule('.red::before','content: "' + latestContent + '"'); document.styleSheets[0].insertRule('.red::before { content: "' + latestContent + '" }', 0);
Метод 2. Используйте атрибут data- * элемента DOM, чтобы изменить значение содержимого:
// код CSS
.red::before {
content: attr(data-attr);
color: red;
}
// HTML-код
<div class = "red" data-attr = "red"> контент контент контент контент </div>
// Код JacaScript
$('.red').attr('data-attr', 'green');
6. Небольшое предложение:
1.
Атрибут содержимого псевдоэлемента очень мощный, и он может записывать различные строки и некоторые мультимедийные файлы. Но содержимое псевдоэлементов существует только в дереве рендеринга CSS, а не в реальной DOM. Поэтому для SEO-оптимизации лучше не включать контент, связанный с документами, в псевдоэлементы.
2.
Для изменения стиля псевдоэлементов рекомендуется использовать метод изменения стиля путем замены класса. Потому что два других способа вставить CSSStyleSheet в строку — это вставить коды символов в JavaScript, что не способствует разделению стиля и управления; а сращивание строк подвержено ошибкам.
3.
Измените значение атрибута содержимого псевдоэлемента, для его изменения рекомендуется использовать атрибут data- * модели DOM.
http://www.dengzhr.com/frontend/css/797
Хочешь проверить свои знания по JS?
Подпишись на наш канал с тестами по JS в Telegram!
Решать задачи
×
Как изменить CSS-стили? Ответ очевиден — отредактировать CSS-файл. Возможно, после этого понадобится компиляция. Затем нужно обновить стили во время выполнения, изменив атрибуты элемента, такие как class
и aria-*
.
Хотя этот ответ неполный, подумайте над следующими вопросами:
- Как обновить стили во время выполнения, основываясь на взаимодействии с пользователем, а не на предустановленных значениях? Сгенерировать уникальные имена классов для каждой возможной комбинации цветов нереально.
- Что, если у вас нет доступа к таблицам стилей или HTML? Например, если сайт сгенерирован конструктором сайтов со сторонними CSS-файлами, изобилующими свойствами !important.
В этой статье мы рассмотрим четыре способа обновить CSS-стили при помощи JavaScript. Также мы кратко разберем, в каких случаях эти способы стоит применять. Наконец, мы оценим их с точки зрения CSS-сложности, т. е. того, насколько просто понять и изменить код в каждом случае.
Используйте встроенные стили
До изобретения CSS для стилизации веб-страниц использовались теперь уже устаревшие HTML-атрибуты, такие как color
, background
и border
. Встроенный CSS — духовный преемник этих атрибутов. При таком подходе свойства CSS задаются через атрибут style
элемента.
Два следующих способа изменить размер шрифта для элемента hero
равнозначны:
document.getElementById('hero').style = 'font-size: 12rem;'; document.getElementById('hero').style.fontSize = '12rem';
Использование JavaScript для обновления встроенного CSS в целом считается плохой практикой. Причин для этого несколько:
- Нарушается разделение между стилями и контентом, из-за чего становится сложнее читать и изменять документ.
- При таком подходе CSS-селекторы не могут формировать семантические абстракции.
- Без селекторов обновление нескольких элементов на странице потребует прохода по всем элементам, а это отнимает время. К тому же, таким образом можно допустить ошибки.
- Повторяющиеся стили раздувают ваш HTML.
- У вас не будет доступа к псевдоэлементам и псевдоклассам, они доступны только через CSS-селекторы.
В настоящее время мы наблюдаем возрождение встроенного CSS-lite через атомарные CSS-фреймворки, такие как Tailwind CSS. Атомарные фреймворки используют имена классов CSS, которые переводятся в одно CSS-свойство и основываются на генерации компонентов для повторного использования стилей при помощи JS. Это позволяет избавиться от проблем 3, 4 и 5 из приведенного выше списка. Но проблему раздувания HTML это все равно не решает.
Хотя встроенные CSS-стили в целом вредны, их применение имеет одно преимущество. Чтобы внести изменение, вам не нужно иметь доступ к таблицам стилей. Поэтому с их помощью вполне можно вносить некоторые правки по ходу работы.
Когда стоит применять встроенный CSS
- Для обновления стилей отдельного элемента во время выполнения.
- Для быстрой проверки чего-либо.
- Когда таблицы стилей недоступны.
Используйте HTML-атрибуты
Можно изменять и другие атрибуты элементов, не только style
. Это самый популярный способ, он позволяет создавать переиспользуемые и семантически значимые стили. Вот несколько примеров:
// toggles HTML semantic state document.getElementById('cta').disabled = true; // a aria based semantic button state document.getElementById('cta').ariaExpanded = "true"; // a class based semantic primary variation document.getElementById('cta').classList.toggle('primary');
Тут особо нечего добавить. Вероятно, вы и так пользуетесь этим методом. Такой код и понять просто, и изменить легко. К тому же, в нашем распоряжении множество CSS-методологий для контроля над его сложностью.
Но я хочу отметить, что примеры в приведенном выше коде расположены в порядке их значимости. Прежде чем прибегнуть к состояниям на основе классов, стоит обратиться к состояниям на основе атрибутов HTML. Теперь, когда селектор :has()
уже на горизонте, это стало проще.
Когда стоит модифицировать атрибуты помимо style
Всегда, когда у вас есть доступ к таблицам стилей и предопределенные стили.
Используйте CSSOM
Следующий метод изменения CSS посредством JavaScript можно сравнить со скальпелем в наборе инструментов фронтендера. Мы можем напрямую изменять объекты CSS.
Два предыдущих метода для изменения стилей модифицируют HTML DOM. Но в некоторых случаях проще изменить напрямую CSS Object Model (CSSOM).
Обратившись к объекту styleSheets
документа, мы можем избирательно менять стили сайта, используя всю мощь CSS. Например:
const thirdPartyStylesheet = document.styleSheets[0]; //index 15 rule color: red !important; thirdPartyStylesheet.deleteRule(15);
Можно даже добавить новые динамически генерируемые стили при помощи конструктора CSSStyleSheet. По своему опыту могу сказать, что это наилучший вариант, когда вы имеете дело со сторонними таблицами стилей или конструктором сайтов, т. е., когда ваши возможности работы с CSS ограничены.
Когда вы засоряете свои встроенные стили многочисленными !important
для перезаписи сторонних стилей, происходит жуткое разрастание CSS-селекторов. Изменение CSSOM позволяет этого избежать. Этот подход также может быть эффективнее перебора в цикле нескольких элементов для динамического обновления их стилей.
Основной недостаток CSSOM-подхода — такой код труден для понимания и отладки. Для измененного CSSOM нет поддержки в инструментах разработчика. И, если только вы не задокументировали свои шаги крупным шрифтом, ваш код может довести будущего мейнтейнера до ручки. Так же, как и скальпель, этот метод нужно использовать редко и осторожно.
Когда стоит модифицировать CSSOM
Больше всего этот способ подходит не для внесения новых стилей, а для удаления сторонних. Также с его помощью можно изменить стили, которые вы не контролируете.
Используйте пользовательские свойства CSS
Последний способ динамического обновления CSS-стилей предполагает применение пользовательских свойств CSS. Хотя технически тут не используются никакие новые APIs, применение пользовательских свойств существенно отличается от предыдущих подходов.
Пользовательские свойства можно использовать с любым из предыдущих методов:
const themeColor = document.getElementById('color-picker').value; // use with inline style document.body.style=`--theme-color: ${themeColor};`; // use in CSSOM const stylesheet = document.styleSheets[0]; stylesheet.insertRule(`:root { --theme-color: ${themeColor}; }`);
Пользовательские свойства элемента наследуются его потомками. Мы можем использовать их со встроенными стилями и не беспокоиться о выборке и переборе в цикле всех элементов в DOM. Все, что нам нужно, это найти их общего предка. В силу этой особенности пользовательские свойства также могут применяться для изменения псевдоэлементов при помощи встроенных стилей.
Самые значительные минусы применения пользовательских свойств — необходимость доступа к таблицам стилей и необходимость планирования своих действий. При благоразумном использовании с их помощью можно изменить несколько стилей за одно обновление. Пример — генерация целой цветовой палитры путем обновления одного цвета.
Применение пользовательских свойств требует такой же продуманности (если не большей), что и подход с изменением атрибутов элемента, но с его помощью можно менять стили во время работы кода.
Поддержка кода с пользовательскими свойствами проще, чем кода с измененной CSSOM: тут нужно отслеживать меньше изменений. Но при этом вам нужен доступ к таблицам стилей.
Когда стоит применять пользовательские свойства
- Вам нужно внести комплексные изменения стилей во время выполнения программы.
- Вы хотите создать новые отношения между стилевыми свойствами.
- Вам нужно пробить Shadow DOM, чтобы стилизовать множество веб-компонентов.
Итоги
Когда вам в очередной раз понадобится изменить CSS-стили при помощи JavaScript, спросите себя:
- Это предопределенное изменение или значение стиля определяется динамически во время работы программы?
- Я перекрываю существующие сторонние стили?
- Мне нужно изменить один элемент или несколько, включая псевдоэлементы и классы?
- Хочу ли я, чтобы это изменение повлияло на несколько производных свойств или затронуло несколько элементов на странице?
Исходя из ответов на эти вопросы, можно подобрать наиболее подходящий способ внесения изменений в CSS-стили.
Перевод статьи «How to Change CSS Styles with JavaScript – From Basic to Advanced Methods».