Modify pseudo-element :after's width using javascript [duplicate]

匿名 (未验证) 提交于 2019-12-03 01:10:02

问题:

Markup:

Hello World

CSS:

.title {   border-bottom: 3px solid #aaa;   position: relative; } .title:after {   content: "";   width: 100px;   border-bottom: 3px solid red;   display: block;   position: absolute; } 

Demo: http://codepen.io/anon/pen/HDBqe

I wanted to change the .title:after's width based on the text's width, how do I change :after's width using javascript?

$.fn.textWidth = function(){   var html_org = $(this).html();   var html_calc = '' + html_org + '';   $(this).html(html_calc);   var width = $(this).find('span:first').width();   $(this).html(html_org);   return width; };  $('.title').each(function(){   // Change :after's width based on the text's width   // .css('width', $(this).textWidth()); }); 

回答1:

A pseudo-element is not part of the DOM. Therefore, you cannot change its CSS properties directly through JS.

In order to get your desired effect the way you want it, my best guess would be YUI.StyleSheet and manipulate the stylesheet itself, although I have to admit I haven't tested it myself in recent years.

Including such a utility and doing all of this calculation seems like a lot of work for width matching.

If you are willing to compromise a little bit on the semantic HTML, there is a working technique:

Your element takes the entire width of the screen. Wrapping the text with a span and adding the pseudo-element to that, as an inline-block should allow you to get the border under the text only

HTML:

Hello World

CSS:

.title {     border-bottom: 3px solid #aaa;     position: relative; }  .title span{     display:inline-block;     position:relative; }  .title span:after {     content: "";     width: 100%;     border-bottom: 3px solid red;     display: block;     position: absolute; } 

Here is my version of the codePen.

For future reference:

There is a W3C Candidate Recommendation that suggests the capability of using attributes for CSS properties other than content.

This way, if and when the recommendation is approved and implemented, it might be possible to have the pseudo-element reflect the parent's attributes, as such:

this.setAttribute("length", $(this).textWidth()); 

And the relevant CSS:

.title:after {     ...     width: attr(length px);     ... } 


回答2:

I've found a trick which works in this case. I've updated your demo:

http://codepen.io/anon/pen/bHLtk

.title {   border-bottom: 3px solid #aaa;   position: relative;   min-width: 100%; }  .title:after {   content: "";   width: inherit;   border-bottom: 3px solid red;   display: block;   position: absolute; } 

Notice, that .title:after has width set to inherit but his parent (.title) has overridden width with min-width. Now I can freely to set width by JavaScript to title and it take effect only on his nested pseudoelement:

$('.title').each(function(){   $(this).css('width', $(this).textWidth()); }); 


回答3:

How's this for a different approach.... http://jsfiddle.net/mayYt/

Added CSS

.title span {     border-bottom: 3px solid red; } 

JQuery

$('.title').wrapInner(''); 


回答4:

With just a simple trick any pseudo-element can be changed (or at least replaced with something else):

$('.something').click(function(){   $(this).toggleClass('to_show'); });
.something {   background: red;   height: 40px;   width: 120px;   position: relative; } .something.to_show:after {   content: "X";   color: white;   background: green;   width: 20px;   height: 20px;   position: absolute;   right: 0px;   top: 0px;   display: block;   text-align: center; } .something:after {   content: "O";   color: white;   background: blue;   width: 30px;   height: 25px;   position: absolute;   right: 0px;   top: 0px;   display: block;   text-align: center; }
click here!


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!