Assign CSS attributes according to class “range”

2019-01-27 00:52发布

I have some HTML code I need to style that is being automatically generated by a web service. Part of the code I'm given looks something like this:

<input type='text' id='txtField001' class='txtField150'>foo</input>    
<input type='text' id='txtField002' class='txtField10'>bar</input>
<input type='text' id='txtField001' class='txtField142'>sum</input>

Now, here comes the "weird" part: the numbers that follow the class name (i.e.: 150, 10 and 142) are, in fact, the max. number of characters the text field accepts, slo it gives me a "hint" as to how wide the text field should render: wide for 150, shorter for 10; since this number varies wildly (it's user defined by whomever is calling the web service) it is not practical to have "n" classes to comply with all possible values.

So: is there a way to have a "ranged class" or something like that - keeping in mind that, theoretically, I cannot change whatever the web service is delivering, and that I don't really want to evaluate things with javascript?

Concretely, is there any way to declare something like this (I know it's somewhat wild):

.txtField1 ... .txtField50 {
    width: 50px;
}

.txtField50 ... .txtField100 {
    width: 80px;
}

.txtField100 ... .txtField150 {
    width: 120px;
}

(how I'm reading this in my mind: "for any class txtField ranging from 1 to 50, use a 50px width... and so on)

Thanks for any help. I know it's a long shot, and that my best option is to use javascript, but hey, I had to ask ;-)

3条回答
戒情不戒烟
2楼-- · 2019-01-27 01:11

If you cannot modify the class in any way, you can do a partial match via CSS attribute selectors:

input[class^="txtField10"] /* catch txtField10, txtField100, txtField1000, etc */
input[class^="txtField150"] /* catch txtField150, txtField15064, txtField150829, etc */

I've chosen the "begins with" syntax for the example, you can see the other types here: http://css-tricks.com/attribute-selectors/

The max length of the field really should be set via the maxlength attribute (which you can also match on like I've done above). But if it is auto generated, there's not really much you can do.

查看更多
仙女界的扛把子
3楼-- · 2019-01-27 01:12

Another method would be to have more than one class on your objects:

<input type='text' id='txtField001' class='txtField width150'>foo</input> 

Or better yet something not tied to the absolute implementation (this is what I do in my in-house development framework where I have narrow, wide, and so forth as standard field widths):

<input type='text' id='txtField001' class='txtField wide'>foo</input> 

That way, if you adjust the details of your implementation, you wont feel the need to adjust every class.

This method combines very well with scripting techniques, or with generated CSS files, or a number of other efficiency or consistency mechanisms.

To follow the example from the previous answer, using Dojo, since I am not a jQuery guy, you could then do formatting something like this:

var widths = {
   narrow:  '10em';
   wide: '30em';
}

for (m : widths) {
   if widths.hasOwnProperty(m) {
      dojo.query('.' + m).style('width', widths[m]));
   } 
}

If you absolutely must encode the specific width in a variety of styles, having a single additional class to select the nodes on for scripting would still help you. You would select based on the shared class, then check all classes for the one with the parameter.

If you are not an adherent to rigid validation compliance, you could also embed this information in a custom attribute rather than a class, and then parse for that in your JavaScript.

There are many approaches.

查看更多
Fickle 薄情
4楼-- · 2019-01-27 01:16

Yes, with Limits

I have been pondering a solution that is similar to cimmanon's, only I knew it needed to be far more refined than that (which is why it has taken some time to answer).

Let me state up front that this probably needs a practical limit (I don't know if there is a limit on the number of characters that it can be in your situation). As you can see in my example fiddle, anything 300+ fails to resolve to larger sizes. If there is a high or unknown upper limit, then javascript is really going to be your best solution. My example works for less than 300, and perhaps up to 999 could be made with not too much more code. But 1000+ I think would be unreasonable.

CSS

/* set default as small size */
[class ^= "txtField"] {
    width: 50px;
}

/* weed out 50-99, making sure not to get 5-9 */
[class *= "d5"]:not([class $= "d5"]),
[class *= "d6"]:not([class $= "d6"]),
[class *= "d7"]:not([class $= "d7"]),
[class *= "d8"]:not([class $= "d8"]),
[class *= "d9"]:not([class $= "d9"])
{
    width: 80px;
}

/* weed out 100-199, making sure not to get 1 or 10-19
   NOTE: this becomes a highly specific selector
*/
[class *= "d1"]:not([class $= "d1"]):not([class $= "d10"]):not([class $= "d11"]):not([class $= "d12"]):not([class $= "d13"]):not([class $= "d14"]):not([class $= "d15"]):not([class $= "d16"]):not([class $= "d17"]):not([class $= "d18"]):not([class $= "d19"])
{
    width: 120px;
}

/* weed out 150-199, making sure not to get 15-19
   NOTE: because the previous selector is so specific, this one
   needed the !important flag (which I hate to use, but here
   seemed to be the best and only solution)
*/
[class *= "d15"]:not([class $= "d15"]),
[class *= "d16"]:not([class $= "d16"]),
[class *= "d17"]:not([class $= "d17"]),
[class *= "d18"]:not([class $= "d18"]),
[class *= "d19"]:not([class $= "d19"])
{
    width: 150px !important;
}

/* weed out 200-299, making sure not to get 2 or 20-29
   NOTE: again high specificity
*/
[class *= "d2"]:not([class $= "d2"]):not([class $= "d20"]):not([class $= "d21"]):not([class $= "d22"]):not([class $= "d23"]):not([class $= "d24"]):not([class $= "d25"]):not([class $= "d26"]):not([class $= "d27"]):not([class $= "d28"]):not([class $= "d29"])
{
    width: 180px;
}

/* weed out 250-299, making sure not to get 25-29
   NOTE: !important needed again;
   also, anything 300+ reverts back to smallest size unless
   one keeps going... maybe 999 could be reached "reasonably"
*/
[class *= "d25"]:not([class $= "d25"]),
[class *= "d26"]:not([class $= "d26"]),
[class *= "d27"]:not([class $= "d27"]),
[class *= "d28"]:not([class $= "d28"]),
[class *= "d29"]:not([class $= "d29"])
{
    width: 210px !important;
}
查看更多
登录 后发表回答