88 votes

Modification de la propriété width d'un sélecteur css :before à l'aide de JQuery

J'ai une page qui contient une image et je l'ai stylisée à l'aide de sélecteurs CSS :before.
L'image étant dynamique, sa largeur n'est pas fixe. Je dois donc définir la largeur de la règle :before de manière dynamique.
Je veux le faire du côté client en utilisant JQuery.
Supposez ceci :

.column:before{
    width: 300px;
    float: left;
    content: "";
    height: 430px;
}

.column{
    width: 500px;
    float: right;
    padding: 5px;
    overflow: hidden;
    text-align: justify;
}

Comment puis-je modifier uniquement la propriété width de la classe avec :before (et pas un autre sans) en utilisant JQuery ?

116voto

m90 Points 5315

Je ne pense pas qu'il existe un moyen jQuery d'accéder directement aux règles de la pseudoclasse, mais vous pouvez toujours ajouter un nouveau fichier style à l'en-tête du document comme :

$('head').append('<style>.column:before{width:800px !important;}</style>');

Voir un Démonstration en direct ici

Je me souviens également avoir vu un plugin qui s'attaque à ce problème une fois, mais je ne l'ai pas trouvé lors de ma première recherche sur Google, malheureusement.

64voto

alex Points 186293

Les pseudo-éléments font partie du DOM fantôme et ne peuvent pas être modifiés (mais puede dont les valeurs sont interrogées).

Cependant, vous pouvez parfois contourner ce problème en utilisant des classes, par exemple.

jQuery

$('#element').addClass('some-class');

CSS

.some-class:before {
    /* change your properties here */
}

Cela ne convient peut-être pas à votre requête, mais cela montre qu'il est parfois possible d'obtenir ce schéma.

Pour obtenir la valeur d'un pseudo-élément, essayez un code comme...

var pseudoElementContent = window.getComputedStyle($('#element')[0], ':before')
  .getPropertyValue('content')

28voto

Starx Points 38727

Les pseudo-éléments ne font pas partie du DOM, ils ne peuvent donc pas être manipulés à l'aide de jQuery ou de Javascript.

Mais comme indiqué dans la réponse acceptée, vous pouvez utiliser le JS pour ajouter un bloc de style qui finit par styliser les pseudo-éléments.

22voto

yckart Points 7517

La réponse devrait être Jain . Vous ne pouvez pas sélectionner un élément via le pseudo-sélecteur, mais vous pouvez ajouter une nouvelle règle à votre feuille de style avec insertRule .

J'ai fait quelque chose qui devrait marcher pour toi :

var addRule = function(sheet, selector, styles) {
    if (sheet.insertRule) return sheet.insertRule(selector + " {" + styles + "}", sheet.cssRules.length);
    if (sheet.addRule) return sheet.addRule(selector, styles);
};

addRule(document.styleSheets[0], "body:before", "content: 'foo'");

http://fiddle.jshell.net/MDyxg/1/

Pour être super-cool (et pour répondre à la question vraiment ) J'ai relancé le projet et l'ai intégré dans un plugin jQuery (cependant, jquery n'est toujours pas nécessaire !) :

/*!
 * jquery.addrule.js 0.0.1 - https://gist.github.com/yckart/5563717/
 * Add css-rules to an existing stylesheet.
 *
 * @see http://stackoverflow.com/a/16507264/1250044
 *
 * Copyright (c) 2013 Yannick Albert (http://yckart.com)
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php).
 * 2013/05/12
 **/

(function ($) {

    window.addRule = function (selector, styles, sheet) {

        styles = (function (styles) {
            if (typeof styles === "string") return styles;
            var clone = "";
            for (var p in styles) {
                if (styles.hasOwnProperty(p)) {
                    var val = styles[p];
                    p = p.replace(/([A-Z])/g, "-$1").toLowerCase(); // convert to dash-case
                    clone += p + ":" + (p === "content" ? '"' + val + '"' : val) + "; ";
                }
            }
            return clone;
        }(styles));
        sheet = sheet || document.styleSheets[document.styleSheets.length - 1];

        if (sheet.insertRule) sheet.insertRule(selector + " {" + styles + "}", sheet.cssRules.length);
        else if (sheet.addRule) sheet.addRule(selector, styles);

        return this;

    };

    if ($) $.fn.addRule = function (styles, sheet) {
        addRule(this.selector, styles, sheet);
        return this;
    };

}(window.jQuery));

L'utilisation est assez simple :

$("body:after").addRule({
    content: "foo",
    color: "red",
    fontSize: "32px"
});

// or without jquery
addRule("body:after", {
    content: "foo",
    color: "red",
    fontSize: "32px"
});

https://gist.github.com/yckart/5563717

5voto

Nitai J. Perez Points 1

Une option consiste à utiliser un attribut sur l'image, et à le modifier à l'aide de jQuery. Prenez ensuite cette valeur dans le CSS :

HTML (remarque : je suppose que .cloumn es un div mais cela peut être n'importe quoi) :

<div class="column" bf-width=100 >
    <img src="..." />
</div>

jQuery :

// General use:
$('.column').attr('bf-width', 100);
// With your image, along the lines of:
$('.column').attr('bf-width', $('img').width());

Et ensuite, afin d'utiliser cette valeur dans le CSS :

.column:before {
    content: attr(data-content) 'px';
    /* ... */
}

Cela permettra de récupérer la valeur de l'attribut dans .column et l'appliquer sur l'avant.

Sources : Attr CSS (notez le exemples avec avant), jQuery attr .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X