OVH Cloud OVH Cloud

CSS clip et RegExp pour modif par JS

30 réponses
Avatar
SAM
Salutatous,

Dans le cadre de mon apprentissage des expressions régulières.
Soit la règle de style 'clip'.

Je crois que ça doit s'écrire :
clip: rect(15px, 200px, 150px, 50px);

Il parait que certain(s) IE voudraient :
clip: rect(15px 200px 150px 50px);
et que ça ne poserait pas de problème pour les autres navigateurs.


Je mets cette règle inline pour la faire traiter le + simplement
possible par JavaScript :

<img style="clip: rect(15px 200px 150px 50px)" id="ici" blabla>

Que l'on rajoute ou non les virgules dans ce rect(...),
si je fais (en JS) :
alert(document.getElementById('ici').style.clip);
j'obtiens :
- Firefox, Opera :
rect(15px, 200px, 150px, 50px)
ils rajoutent les virgules ou les espaces si absents
- Safari.3, iCab, IE(Mac) :
rect(15px 200px 150px 50px)
ils mettent un espace comme séparateur

Alors pour retrouver les 4 réglages je fais :

var clip = getElementById('ici').style.clip;
clip = clip.replace(/[A-Za-z\(\)]/g,'').split(/[^0-9]{1,2}/);
var haut = clip[0], droite = clip[1]; // etc

Ça m'a l'air un peu laborieux comme RegExp, non ?

Accessoirement, n'y aurait-il pas une méthode + simple d'extraire les 4
réglages de clip ?

--
sm

10 réponses

1 2 3
Avatar
Laurent vilday
Olivier Miakinen a écrit :
Le 16/07/2008 23:36, Laurent vilday a écrit :
Cf. ci-dessus. Chez moi ça marche avec :
------------------------------------------------
clip = 'clip: rect(15px 200px 150px 50px);';
clip = clip.match(/[0-9]+/g);
var haut = clip[0], droite = clip[1];
------------------------------------------------
-> haut vaut 15 et droite vaut 200


Allez, je vais faire mon chieur.

"Ca" ne "passe" plus dès qu'on en vient à mélanger des unités non
entière et autres que le pixel (em,pt,px,pc), même si je ne vois pas
trop pourquoi qqun voudrait faire ça mais bon.



Tu as parfaitement raison. Note que cela ne marche pas non plus avec les



Houla, j'aurais pas dis "parfaitement" :)

longueurs exprimées en pourcentage, ni avec les longueurs négatives, ni
bien sûr avec les valeurs 'auto' ou 'inherit'.



Tiens, je croyais les longueurs en pourcentages non valides. Mais j'ai
beau lire et relire je ne retrouve pas cette "info".

En passant la règle " p { clip:rect(1%, 2%, 3%, 4%) } " au validateur
CSS, il me dit bien que c'est pas bon, mais il me dit pas que c'est à
cause des %.

Pourtant ça doit bien être les % qui l'embête puisqu'il arrête de raler
si je lui dit " p { clip:rect(1px, 2px, 3px, 4px) } "

J'essaye mais j'imagine qu'il y a bien plus efficace comme regexp, mes
capacités regexp sont trop limitées :/

var clip = 'clip:rect(15em, 1.5pt, 15px, 1.5pc)';
clip = clip.match(/[0-9.]+[em|px|pc|pt]{2}/g);



Petite confusion entre [] et (), même si tu rattrappes un peu le coup



LOL, petite confusion ? Ahaha, connaissant mes compétences regexp tu
peux largement parler d'énorme confusion et d'incompréhension totale :)

avec le {2} qui suit. Je suppose que tu voulais (em|px|pc|pt) au lieu de
[em|px|pc|pt]. Pour info, [em|px|pc|pt] est équivalent à [cemppptx|||],
c'est-à-dire à [cemptx|].

Mais je suis persuadé que la regexp est foireuse, le [em|px|pc|pt]{2}
surtout, je pense que ça doit pouvoir se remplacer par [empxct]{2} mais



Ah oui, désolé d'avoir enfoncé une porte ouverte. Note quand même
qu'elle n'était qu'entrebaillée car tu as oublié le « | » dans ton
équivalence.



Pourquoi ajouter le pipe | ?

Je croyais (à tort j'en suis sur) que le pipe servait à séparer des
valeurs dans l'expression entre crochets. Visiblement, c'est pas ça.

ça continuerait à extraire des unités invalides comme ee ou tt. Je ne
sais pas comment rendre ça plus strict pour lui imposer l'extraction
seulement des unitées valides (em, pc, px, pt et pas un mélange
aléatoire de 2 de ces lettres)



Allons-y. Je pars de /[0-9]+/g.



Cool, à partir de là je comprend :D

On veut accepter les nombres non entiers : « zéro, ou plusieurs
chiffres, suivi par un point (.) et un, ou plusieurs, chiffres ».
/([0-9]*.)?[0-9]+/g



Et voila ça commence, je comprends dèjà beaucoup moins. Obligé de
décortiquer atome par atome pour esquisser un début de compréhension.
Grr, j'aime pas les regexp.

La longueur peut être négative : « Les valeurs négatives sont admises. »
http://www.yoyodesign.org/doc/w3c/css2/visufx.html#clipping



<http://www.w3.org/TR/CSS21/visufx.html#clipping>
The 'clip' property applies only to absolutely positioned elements.

<http://www.yoyodesign.org/doc/w3c/css2/visufx.html#clipping>
La propriété 'clip' s'applique aux éléments dont la valeur de la
propriété 'overflow' est autre que 'visible'

Erreur de traduction de yoyodesign.org.

La propriété 'clip' s'applique uniquement aux éléments en position absolue.

/-?([0-9]*.)?[0-9]+/g

Il y a des unités relatives (em, ex, px), absolues (in, cm, mm, pt, pc)
et pourcentage (%).

/-?([0-9]*.)?[0-9]+(em|ex|px|in|cm|mm|pt|pc|%)/g

Et maintenant, si on veut accepter aussi auto ou inherit...

/(auto|inherit|-?([0-9]*.)?[0-9]+(em|ex|px|in|cm|mm|pt|pc|%))/g

Argh ! On a perdu la belle simplicité du début...



LOL, tu m'étonnes, jamais j'aurais pu pondre un tel truc...

--
laurent
Avatar
Laurent vilday
SAM a écrit :
Laurent vilday a écrit :
Olivier Miakinen a écrit :
Le 16/07/2008 09:23, SAM a écrit :
Accessoirement, n'y aurait-il pas une méthode + simple d'extraire
les 4 réglages de clip ?



Cf. ci-dessus. Chez moi ça marche avec :
------------------------------------------------
clip = 'clip: rect(15px 200px 150px 50px);';
clip = clip.match(/[0-9]+/g);
var haut = clip[0], droite = clip[1];
------------------------------------------------
-> haut vaut 15 et droite vaut 200



Allez, je vais faire mon chieur.



C'est rien d'le dire :-)
Imaginer qu'en plus on puisse jouer avec les unités !

Au fait, comment déclipe t-on ?
au lieu d'enlever l'extérieur on troue (et on voit l'image de fond par
exemple)



décliper ... dans le sens enlever le clip:rect() ?

<http://www.w3.org/TR/CSS21/visufx.html#clipping>
Values have the following meanings:

auto : The element does not clip.

Donc appliquer "auto" à la règle pour enlever le clipping.

var clip = 'clip:rect(15em, 1.5pt, 15px, 1.5pc)';
clip = clip.match(/[0-9]+/g);

alert(clip.join(', '));



alert(clip);

==> 15, 1, 5, 15



Hein ? le séparateur est out ? (et les dizaines aussi ?!)



Quoi? Moi pas comprendre ?

Le séparateur c'est le join(', ') qui l'a ajouté.
alert(clip.join('-'));
==>15-1-5-15

IMO, si qqun voulait extraire les valeurs du clip (même si j'ai bien
compris que c'est un cas d'école),



Oui.

il faudrait obligatoirement extraire les unités avec. Quitte à
manipuler les valeurs ensuite pour retomber sur une unité simple comme
le pixel.

var clip = 'clip:rect(15em, 1.5pt, 15px, 1.5pc)';



C'est quoi des pc ? des pouces ? ça existe ?



Euh je sais plus :) C'est pas des picas ?

et les mm ? ou cm ?



Oups, pas pensé à eux.

Et maintenant ... les conversions en px ?



Trop facile :D

function toPixel(longueur)
{
var
valeur,
div = document.createElement('DIV');
div.style.width = longueur;
document.body.appendChild(div);
valeur = div.offsetWidth;
document.body.removeChild(div);
return valeur;
}
alert(toPixel('10em'));

--
laurent
Avatar
SAM
Olivier Miakinen a écrit :
Le 17/07/2008 09:09, Olivier Miakinen a écrit :

/(auto|inherit|-?([0-9]*.)?[0-9]+(em|ex|px|in|cm|mm|pt|pc|%))/g



/(auto|inherit|[-+]?([0-9]*.)?[0-9]+(em|ex|px|in|cm|mm|pt|pc|%))/g
ou
/auto|inherit|[-+]?([0-9]*.)?[0-9]+(em|ex|px|in|cm|mm|pt|pc|%)/g




/auto|inherit|[-+]?([0-9]*.)?[0-9]+(em|ex|p[xtc]|in|cm|mm|%)/g


/auto|inherit|[-+]?([0-9]*.)?[0-9]+([ecm]m|[ep]x|p[tc]|in|%)/g

bon ... on ne gagne pas grd chose (à part de ne + rien y comprendre)


Si inherit n'est pas autorisé par M$

/auto|[-+]?([0-9]*.)?[0-9]+([ecm]m|[ep]x|p[tc]|in|%)/g

--
sm
Avatar
SAM
Laurent vilday a écrit :

Tiens, je croyais les longueurs en pourcentages non valides. Mais j'ai
beau lire et relire je ne retrouve pas cette "info".

En passant la règle " p { clip:rect(1%, 2%, 3%, 4%) } " au validateur
CSS, il me dit bien que c'est pas bon, mais il me dit pas que c'est à
cause des %.

Pourtant ça doit bien être les % qui l'embête puisqu'il arrête de raler
si je lui dit " p { clip:rect(1px, 2px, 3px, 4px) } "



Réfléchissons ...
à quoi normalement les % se réfèrent-ils ?
si je n'm'abuse : sauf pour les image, au contenant s'il est positionné
Clipper un élément proportionnellement à son contenant ... ça doit
donner de curieux résultats


La longueur peut être négative : « Les valeurs négatives sont admises. »
http://www.yoyodesign.org/doc/w3c/css2/visufx.html#clipping



<http://www.w3.org/TR/CSS21/visufx.html#clipping>
The 'clip' property applies only to absolutely positioned elements.



Oui ? et alors ?
Qu'a-ce à voir avec les négatifs ?

<http://www.yoyodesign.org/doc/w3c/css2/visufx.html#clipping>
La propriété 'clip' s'applique aux éléments dont la valeur de la
propriété 'overflow' est autre que 'visible'

Erreur de traduction de yoyodesign.org.



??? je ne pense pas : d'un côté 'css2' de l'autre 'css21'
<http://www.w3.org/TR/CSS2/visufx.html#clipping>


--
sm
Avatar
Laurent vilday
SAM a écrit :
Laurent vilday a écrit :
<http://www.w3.org/TR/CSS21/visufx.html#clipping>
The 'clip' property applies only to absolutely positioned elements.
<http://www.yoyodesign.org/doc/w3c/css2/visufx.html#clipping>
La propriété 'clip' s'applique aux éléments dont la valeur de la
propriété 'overflow' est autre que 'visible'

Erreur de traduction de yoyodesign.org.



??? je ne pense pas : d'un côté 'css2' de l'autre 'css21'
<http://www.w3.org/TR/CSS2/visufx.html#clipping>



Oups, ça m'apprendra à croire qu'une spec est backward compatible. CSS2
vers CSS2.1 je croyais, mais en l'occurence elle ne l'est pas.

mea culpa.

--
laurent
Avatar
SAM
Laurent vilday a écrit :
SAM a écrit :

Au fait, comment déclipe t-on ?
au lieu d'enlever l'extérieur on troue (et on voit l'image de fond par
exemple)



décliper ... dans le sens enlever le clip:rect() ?



non : faire le contraire de clip
c a d un trou

alert(clip);

==> 15, 1, 5, 15



Hein ? le séparateur est out ? (et les dizaines aussi ?!)



Quoi? Moi pas comprendre ?



je parle de clip:rect(15em, 1.5pt, 15px, 1.5pc)
dont le . et ce qui suit sont oubliés

C'est quoi des pc ? des pouces ? ça existe ?



Euh je sais plus :) C'est pas des picas ?



Ha ? peut-être.

Et maintenant ... les conversions en px ?



Trop facile :D

function toPixel(longueur)
{
var
valeur,
div = document.createElement('DIV');
div.style.width = longueur;
document.body.appendChild(div);
valeur = div.offsetWidth;
document.body.removeChild(div);
return valeur;
}
alert(toPixel('10em'));



Boudiou !

--
sm
Avatar
SAM
Laurent vilday a écrit :
SAM a écrit :
Laurent vilday a écrit :
<http://www.w3.org/TR/CSS21/visufx.html#clipping>
The 'clip' property applies only to absolutely positioned elements.
<http://www.yoyodesign.org/doc/w3c/css2/visufx.html#clipping>
La propriété 'clip' s'applique aux éléments dont la valeur de la
propriété 'overflow' est autre que 'visible'

Erreur de traduction de yoyodesign.org.



??? je ne pense pas : d'un côté 'css2' de l'autre 'css21'
<http://www.w3.org/TR/CSS2/visufx.html#clipping>



Oups, ça m'apprendra à croire qu'une spec est backward compatible. CSS2
vers CSS2.1 je croyais, mais en l'occurence elle ne l'est pas.



Je ne vois pas en quoi le positionnement empêcherait de styler l'overflow.
à mon idée ça reste compatible

Le coup de l'absolute çà doit être une concession à M$

--
sm
Avatar
Olivier Miakinen
Le 17/07/2008 10:12, Laurent vilday a écrit :

J'essaye mais j'imagine qu'il y a bien plus efficace comme regexp, mes
capacités regexp sont trop limitées :/

var clip = 'clip:rect(15em, 1.5pt, 15px, 1.5pc)';
clip = clip.match(/[0-9.]+[em|px|pc|pt]{2}/g);



Petite confusion entre [] et (), même si tu rattrappes un peu le coup



LOL, petite confusion ? Ahaha, connaissant mes compétences regexp tu
peux largement parler d'énorme confusion et d'incompréhension totale :)



:-D

avec le {2} qui suit. Je suppose que tu voulais (em|px|pc|pt) au lieu de
[em|px|pc|pt]. Pour info, [em|px|pc|pt] est équivalent à [cemppptx|||],
c'est-à-dire à [cemptx|].

Mais je suis persuadé que la regexp est foireuse, le [em|px|pc|pt]{2}
surtout, je pense que ça doit pouvoir se remplacer par [empxct]{2} mais



Ah oui, désolé d'avoir enfoncé une porte ouverte. Note quand même
qu'elle n'était qu'entrebaillée car tu as oublié le « | » dans ton
équivalence.



Pourquoi ajouter le pipe | ?



C'est toi qui l'as mis, par trois fois, dans [em|px|pc|pt] !

Je croyais (à tort j'en suis sur) que le pipe servait à séparer des
valeurs dans l'expression entre crochets. Visiblement, c'est pas ça.



En effet : le caractère « | » n'est pas un caractère spécial dans une
classe de caractères. Par conséquent, il ne peut pas *séparer* des
valeurs, mais il *est* une des valeurs possibles.

En revanche, ce caractère « | » sert à séparer des valeurs *en dehors*
des classes de caractères.

Ainsi, les règles suivantes sont toutes équivalentes :
1) [em|px|pc|pt]
2) [cemppptx|||]
3) [cemptx|]
4) [c]|[e]|[m]|[p]|[t]|[x]|[|]
5) c|e|m|p|t|x|[|]
6) c|e|m|p|t|x||
N'hésite pas à demander des précisions si le passage d'une ligne à une
autre n'est pas clair, par exemple 3->4.

Allons-y. Je pars de /[0-9]+/g.



Cool, à partir de là je comprend :D

On veut accepter les nombres non entiers : « zéro, ou plusieurs
chiffres, suivi par un point (.) et un, ou plusieurs, chiffres ».
/([0-9]*.)?[0-9]+/g



Et voila ça commence, je comprends dèjà beaucoup moins. Obligé de
décortiquer atome par atome pour esquisser un début de compréhension.
Grr, j'aime pas les regexp.



Désolé.

Je fais l'hypothèse que tu as fini par comprendre, mais au besoin je
veux bien détailler. Voici déjà un début.

Nombre entier :
/[0-9]+/g
Nombre à virgule :
/[0-9]*.[0-9]+/g
Nombre entier ou nombre à virgule :
/[0-9]+|[0-9]*.[0-9]+/g
« ac|bc » est équivalent à « (a|b)c », même avec « a » vide :
/(|[0-9]*.)[0-9]+/g
« (|x) » est équivalent à « (x)? » :
/([0-9]*.)?[0-9]+/g

La longueur peut être négative : « Les valeurs négatives sont admises. »
http://www.yoyodesign.org/doc/w3c/css2/visufx.html#clipping



<http://www.w3.org/TR/CSS21/visufx.html#clipping>
The 'clip' property applies only to absolutely positioned elements.

<http://www.yoyodesign.org/doc/w3c/css2/visufx.html#clipping>
La propriété 'clip' s'applique aux éléments dont la valeur de la
propriété 'overflow' est autre que 'visible'

Erreur de traduction de yoyodesign.org.



... ou différence entre CSS2 et CSS2.1, mais cela ne concerne pas la
possibilité ou non d'avoir des valeurs négatives :

http://www.w3.org/TR/CSS21/visufx.html#clipping
« Negative lengths are permitted. »
Avatar
Laurent vilday
Olivier Miakinen a écrit :
Le 17/07/2008 10:12, Laurent vilday a écrit :
J'essaye mais j'imagine qu'il y a bien plus efficace comme regexp, mes
capacités regexp sont trop limitées :/

var clip = 'clip:rect(15em, 1.5pt, 15px, 1.5pc)';
clip = clip.match(/[0-9.]+[em|px|pc|pt]{2}/g);


Petite confusion entre [] et (), même si tu rattrappes un peu le coup


LOL, petite confusion ? Ahaha, connaissant mes compétences regexp tu
peux largement parler d'énorme confusion et d'incompréhension totale :)



:-D

avec le {2} qui suit. Je suppose que tu voulais (em|px|pc|pt) au lieu de
[em|px|pc|pt]. Pour info, [em|px|pc|pt] est équivalent à [cemppptx|||],
c'est-à-dire à [cemptx|].


Pourquoi ajouter le pipe | ?



C'est toi qui l'as mis, par trois fois, dans [em|px|pc|pt] !



Vi, je croyais que : [em|px] voulait dire "trouver em, ou px". Mais
visiblement non. Je suis bon pour relire un ènième fois "Mastering
Regular Expressions" de O'Reilly ...
<http://oreilly.com/catalog/9781565922570/>

Je croyais (à tort j'en suis sur) que le pipe servait à séparer des
valeurs dans l'expression entre crochets. Visiblement, c'est pas ça.



En effet : le caractère « | » n'est pas un caractère spécial dans une
classe de caractères. Par conséquent, il ne peut pas *séparer* des
valeurs, mais il *est* une des valeurs possibles.



Humm, "classe de caractères" c'est le [ ], c'est ça ?

En revanche, ce caractère « | » sert à séparer des valeurs *en dehors*
des classes de caractères.



OK, donc :

/em|pt/ ça trouve "em" ou "pt"

Tandis que /[em|pt]/ ça trouve "e", "m", "|", "p" ou "t", c'est ça ?

Ainsi, les règles suivantes sont toutes équivalentes :
1) [em|px|pc|pt]
2) [cemppptx|||]
3) [cemptx|]
4) [c]|[e]|[m]|[p]|[t]|[x]|[|]
5) c|e|m|p|t|x|[|]
6) c|e|m|p|t|x||
N'hésite pas à demander des précisions si le passage d'une ligne à une
autre n'est pas clair, par exemple 3->4.



Humm je crois avoir pigé. Du 3 au 4, ça va. C'est plus le "[|]" du 5 qui
devient "|" dans le 6, même si avec tes explications je pense
apercevoir l'astuce.

5) [|] c'est une classe de caractère donc on parle du caractère "|"

6) | c'est pas une classe de caractère donc le "|" possédant une
signification propre en dehors des classes de caractères, il faut l'escaper.

C'est ça ?

Allons-y. Je pars de /[0-9]+/g.


Cool, à partir de là je comprend :D

On veut accepter les nombres non entiers : « zéro, ou plusieurs
chiffres, suivi par un point (.) et un, ou plusieurs, chiffres ».
/([0-9]*.)?[0-9]+/g


Et voila ça commence, je comprends dèjà beaucoup moins. Obligé de
décortiquer atome par atome pour esquisser un début de compréhension.
Grr, j'aime pas les regexp.



Désolé.



LOL, faut pas.

Je fais l'hypothèse que tu as fini par comprendre, mais au besoin je
veux bien détailler. Voici déjà un début.



En fait, la lecture du bidule est à peu près comprise. C'est la création
d'une regexp complète qui m'est quasi impossible.

C'est bien pour ça que j'utilise très peu les regexps, préférant de loin
manipuler des substr(), charAt() et autre indexOf() sur les chaines de
caractères.

Nombre entier :
/[0-9]+/g



OK

Nombre à virgule :
/[0-9]*.[0-9]+/g



0.1111 mais aussi .1111, n'est-ce pas ?

Ou j'ai encore rien compris au "*" :D

Nombre entier ou nombre à virgule :
/[0-9]+|[0-9]*.[0-9]+/g



OK

« ac|bc » est équivalent à « (a|b)c », même avec « a » vide :
/(|[0-9]*.)[0-9]+/g



KO ....

(|[0-9]*.) je comprends pas trop à quoi ça peut correspondre.

Pourquoi le pipe "|" ? Pour lui indiquer que ça peut être vide ? Dans ce
cas, le "|" possède une signification propre lorsque entre parenthèses ?

Non, décidémment KO sur celle là.

« (|x) » est équivalent à « (x)? » :
/([0-9]*.)?[0-9]+/g



J'ai déjà dit que j'aimais pas les regexps ? :)

--
laurent
Avatar
SAM
Olivier Miakinen a écrit :
En revanche, ce caractère « | » sert à séparer des valeurs *en dehors*
des classes de caractères.



Qu'est-ce que c'est une "classe" de caractères ?
o [abc]
o (abc)
o autre [ si "autre" remplir cette case ]

Ainsi, les règles suivantes sont toutes équivalentes :
1) [em|px|pc|pt]
2) [cemppptx|||]
3) [cemptx|]
4) [c]|[e]|[m]|[p]|[t]|[x]|[|]
5) c|e|m|p|t|x|[|]
6) c|e|m|p|t|x||
N'hésite pas à demander des précisions si le passage d'une ligne à une
autre n'est pas clair, par exemple 3->4.



Tu rigoles ?
Tu peux commencer par le 1 -> 2
et p't'et' même bien par le 1 :
(donne: rien ou e ou m ou em ou p ou x ou px ...etc.) oui/non ?


si je pense par exemple que le truc va répartir également les 'ou' dans
les caractères précédents
2 -> [ce|mp|pp|tx]
3 -> [cem|ptx]
sinon pour le 4 je comprends qu'on pourra avoir
rien ou c ou e ou ... toujours qu'un seul (donc différent de 1)
5 et 6 je lâche la rampe (non, c'est finalement aussi simple que le 4).

veux bien détailler. Voici déjà un début.

Nombre entier :
/[0-9]+/g
Nombre à virgule :
/[0-9]*.[0-9]+/g



Là il n'y a pas moyen de raccourcir ?
/[.0-9]+/g
sauf à vouloir ne pas matcher les coquilles comme '.px'
(je ne vois pas d'autre coquille possible dans les nombres)

Nombre entier ou nombre à virgule :
/[0-9]+|[0-9]*.[0-9]+/g
« ac|bc » est équivalent à « (a|b)c », même avec « a » vide :
/(|[0-9]*.)[0-9]+/g
« (|x) » est équivalent à « (x)? » :
/([0-9]*.)?[0-9]+/g



Moins de détails ! Moins de détails !
Tenons-nous en à une option.
J'en ai pour 3 semaines pour digérer la variante |x.
1 2 3