1

I think this question is only related with css... but I will give you some context:

I am working with the zk framework and I have some comboboxes in my zul page... ZK render its components and turn them into html components with some predefined styles (css classes)... I can override those styles... but I want to override a whole css class with another so I can put my css class only in the components I want to change its style.

This is how a combobox is created:

Combobox creation

As you can see, it is turn into an input with a css class called z-combobox-input

If I overwrite that class directly, like this:

.z-combobox-input{
    border:1px solid #000;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;-o-border-radius:3px 0 0     3px;-ms-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;margin:0;padding:4px 5px;line-height:14px;background:#fff
}

It will afect every combobox in the page, as a result I get:

css-rule afecting every component

So I want to know if exist a way to do something like this:

.class-original{
    //some styles in here
}

.class-overriding{
    .class-original{
        //new styles in here
    }
}

So I can put my .class-overriding only in the components I need to change and not in every component of the same type.

<combobox id="newCombo" sclass="class-overriding" />

I made this fiddle if you want to try a solution.

I was seeing this question and apparently it is not possible... So: is there another way to achieve that?

Thank you.

UPDATE

I cannot use the id that is generated dinamically (in this case "vXgV3-real").

I can modify some properties from the combobox either by putting a css class or by using the tag style:

<combobox id="combo1" style="background: red" />

But I cannot change that border in particular, like this:

<combobox id="combo2" style="border:1px solid #000;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;-o-border-radius:3px 0 0     3px;-ms-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;margin:0;padding:4px 5px;line-height:14px;background:#fff"/>

Because when it is render (when zk change its component to html components) it turns in this:

Result using tag style

So, when zk change the combobox component to:

<span id="nZEQo" style="width:80%;" class="myCombo z-combobox">
    <input id="nZEQo-real" class="z-combobox-input" autocomplete="off" value="" type="text" style="width: 269px;">
    <a id="nZEQo-btn" class="z-combobox-button">
        <i class="z-combobox-icon z-icon-caret-down"></i>
    </a>
    <div id="nZEQo-pp" class="z-combobox-popup myCombo" style="display:none">
        <ul id="nZEQo-cave" class="z-combobox-content"></ul>
    </div>
</span>

It put random id's to the html components.

Fiddle with this particular part

Some documentation:

Customize Look and Feel of ZK Components Using CSS3 - Part 2

ZK Component Reference>Input>Combobox

Community
  • 1
  • 1
Dazak
  • 1,011
  • 2
  • 9
  • 17
  • `ZK` has a few specific rules regarding styling. I took a few minutes to browse through it and updated my answer. You want to use `sclass` and `zclass` attributes on any element to add to or completely replace the default styling of that element. That's the basics. – tao Mar 15 '17 at 20:15
  • I already replace the default style of the element... the problem @AndreiGheorghiu is that I need that some of that elements has the default look and the other mine – Dazak Mar 15 '17 at 20:18

2 Answers2

3

When you can get ZK to render the element as

<input class="class-original class-overriding" />

you can use the following CSS to style only elements which do have both classes on them.

.class-overriding.class-original {
    background-color: red;
}

This will override the background-color property from .class-original. All properties you don't overwrite will be taken from .class-original-CSS

Edit: Just checked what ZK actually renders. It is (with the class names you provided in the fiddle)

<span class="another-class z-combobox">
    <input class="z-combobox-input" />
</span>

Given that, depending on whether you want to style the outer span or the inner input, you can use one of those CSS-Rules respectively:

.z-combobox.another-class {
  /*styles for the outer span*/
}
.z-combobox.another-class .z-combobox-input {
  /*styles for the outer span*/
}

The first one meaning "Everything with both classes (z-combobox and another-class)", the second one meaning "Everything with class z-combobox-input which is inside of something with both classes z-combobox and another-class

SilverNak
  • 3,283
  • 4
  • 28
  • 44
1

Update: According to ZK documentation you could use sclass attribute to add classes to any element.

So, using the code I see in your screenshot...

 <vbox>
   <combobox>
   <combobox sclass="whatever">
   <combobox>
 </vbox>

...you'll be able to use the following selector to specify rules for the <combobox>es you place whatever class on:

.v-combobox.whatever .z-combobox-input {
  border:1px solid #000;
  border-radius: 3px 0 0 3px;
  margin:0; padding:4px 5px;
  line-height: 14px;
  background: #fff;
}

For more information use this guide.

According to this guide, you should use sclass when you want to add to the default styles applied to an element and zclass attribute when you want to reset the default styles (that means only what you define in your custom class will apply, and not the default styling for that element).


Initial answer:

This is the most important principle in CSS and it's called specificity.
Learning CSS means learning how you can use selectors and their specificity in order to apply rules selectively to some elements and not to others. It's what CSS is typically used for and it's totally possible.

Referencing an element by its id will be stronger (and hence override) any rules specified for any of its classes.

To understand specificity, I recommend this article as a starting point. You should also search for specificity calculator in your search engine of choice.

And in order to be able to use everything you learn about specificity you'll need to understand CSS Selectors and CSS Combinators.


For your specific [ :) ] case, you probably want to use the element's id as selector to apply rules to that element only. Given the id from your first example, this will work:

#vXgV3-real {
  /* the rules here will override the rules for .z-combobox-input
   * for the element with id="vXgV3-real" and only for that element 
   */
  border:1px solid #000;
  border-radius: 3px 0 0 3px;
  margin:0; padding:4px 5px;
  line-height: 14px;
  background: #fff;
}
tao
  • 82,996
  • 16
  • 114
  • 150
  • I have a problem with this aproximation... the id "vXgV3-real" is auto-generated... the id I knew when I created the combobox was "combo1" ``, and as you can see, zk translate this `combobox` to a span with other elements inside... (that's the real problem here... that I don't know (and can't trust in) the id of that input) – Dazak Mar 15 '17 at 19:44
  • What happens when you specify an `id`? Have you read their documentation? This is a very basic need and everyone using their framework has it. They most certainly have a solution for it. You can always use an `.z-combobox:nth-child(x) .z-combobox-input{ /* rules here */}`, where `x` is the index of the element in its parent. Maybe it allows you to place an id on the parent. On `.z-combobox`. There has to be a convenient way to do it. – tao Mar 15 '17 at 19:46
  • @Dazak, please do. And note `CSS` applies to the final markup, independently of what system you are using to generate that markup. So I'll be interested in the final markup, and so should you. You have to find ways to place `id`s or attributes on your elements and you can use those to set `CSS` rules for particular elements. A link to ZK documentation would be useful, too. – tao Mar 15 '17 at 19:53
  • @Dazak Updated answer with (hopefully) sufficient information. Happy coding! – tao Mar 15 '17 at 20:05
  • I appreciate your help... but it still do not work... I put your idea in [this fiddle](http://zkfiddle.org/sample/ile9mb/2-Overriding-zk-combobox-style) – Dazak Mar 15 '17 at 20:14
  • Of course it doesn't. Instead of `v-combobox.whatever.z-combobox-input` you should use `.v-combobox.whatever .z-combobox-input`. It might look minor, but there's a huge difference. You just didn't take the time to understand what the ***empty space combinator*** does in CSS. You're also missing a `.` (dot) which, again makes a world of difference in `CSS`. Unfortunatelly, `CSS` is quite exact. Spaces matter. Dots matter. Almost every character matters. – tao Mar 15 '17 at 20:19
  • That's right... it was my bad... sorry... and Thank you for your helpfull answer :) – Dazak Mar 15 '17 at 20:22
  • @Dazak, there's another detail you should notice: while playing with their fiddle, I noticed ` – tao Mar 15 '17 at 20:29