I’m tasked with developing a widget with buttons in SmartGWT (enterprise). The design calls for borders around the buttons. I’ve designed the CSS for this. However, SmartGWT insists on overriding my CSS border definition by filling in the “style” attribute on the generated TD. The docs for Canvas.setBorder actually say “This property applies the same border to all four sides of this component. Different per-side borders can be set in a CSS style and applied via styleName.” Clearly, it’s meant to be able to control border definitions with CSS.
I realize that I could just call setBorder with a concrete border definition, but I need to have different borders based on state (hover, down, etc.)
For example, the button label is “Review”. Here is the generated HTML:
<td class="controlButton" style="border: currentColor; border-image: none; text-align: center; padding-top: 0px; padding-bottom: 0px; vertical-align: middle;">
<div style="vertical-align: middle; display: inline-block; white-space: nowrap; max-width: 100%;">
<div id="isc_1G" overflow: hidden; vertical-align: middle; display: inline-block; -ms-text-overflow: ellipsis; max-width: 100%; box-sizing: border-box;">Review</div></div></td>
In my CSS, I have a class (controlButton) defined with a border, but the explicit border declaration in the “style” overrides it.
Here’s the code where I create the button:
Button button = new Button(“Review”);
button.setBaseStyle(“controlButton”);
button.setBorder("inherit");
button.setHeight(28);
I’ve also tried not calling setBorder, calling setBorder(null), and as above, setBorder(“inherit”). Nothing affects the inline style.
Here’s the CSS (omitting all of the state definitions for brevity):
.controlButton {
background-color: #353535;
text-align: center;
font-size: 14px;
vertical-align: middle;
padding: 2px;
margin: 2px;
border-radius: 5px;
border: 1px solid #b9b9b9;
color: #d5d5d5;
}
In the browser’s programming mode, I can manually un-check the border definition in “inline style”, and my button looks correct using my class CSS.
By the way, I realize that I can use the !important modifier on the CSS, but there must be a way to make SmartGWT stop overriding without it.
The SmartGWT version is 4.0.5.
The GWT version is 2.7.0.
Related
It seems there is some magic around the <button>element that I don't understand.
Consider this markup:
<button class="button">Some Text</button>
<div class="button">Some Text</div>
And this CSS:
.button{
background: darkgrey;
height: 40px;
border: 2px solid grey;
width: 100%;
box-sizing: border-box;
font-size: 14px;
font-family: helvetica;
text-align: center;
margin-bottom: 20px;
/*I'm aware I could use this to center it*/
/*line-height: 40px;*/
}
What makes the text in the button element vertically centered? Webkit seems to predefine a -webkit-box-align with a value of center for the <button> element. If I set that to initial the text is no longer aligned to the center. But that doesn't seem to be the full magic, since on the other hand I had no luck centering the text on the div using the -webkit-box-align property.
Here is a fiddle: http://jsfiddle.net/cburgdorf/G5Dgz/
I know this is a couple of years old, but I'll add my thoughts after some investigation in to issue while writing a reset stylesheet for a project.
NOTE** This is based on looking through the Firefox source because it was the easiest to obtain and read through. However, based on similar behaviour in other browsers the implementation is probably similar.
Firstly, the main issue here is that <button> elements - atleast in Firefox - are built with an internal element between the <button> tag and it's children. In Firefox it's called moz-button-content and isn't something that can be reached with CSS and has been set to display block without inheriting the height of the button, you can see this style declaration in the useragent stylesheet:
From "source/layout/style/res/forms.css"
*|*::-moz-button-content {
display: block;
/* Please keep the Multicol/Flex/Grid/Align sections below in sync with
::-moz-scrolled-content in ua.css and ::-moz-fieldset-content above. */
/* Multicol container */
-moz-column-count: inherit;
-moz-column-width: inherit;
-moz-column-gap: inherit;
-moz-column-rule: inherit;
-moz-column-fill: inherit;
/* Flex container */
flex-direction: inherit;
flex-wrap: inherit;
/* -webkit-box container (aliased from -webkit versions to -moz versions) */
-moz-box-orient: inherit;
-moz-box-direction: inherit;
-moz-box-pack: inherit;
-moz-box-align: inherit;
/* Grid container */
grid-auto-columns: inherit;
grid-auto-rows: inherit;
grid-auto-flow: inherit;
grid-column-gap: inherit;
grid-row-gap: inherit;
grid-template-areas: inherit;
grid-template-columns: inherit;
grid-template-rows: inherit;
/* CSS Align */
align-content: inherit;
align-items: inherit;
justify-content: inherit;
justify-items: inherit;
}
Because you can't affect any of the styles on this element, you are forced to add you styling on the <button> tags. This leads into the second issue - The browser is hard coded to vertically position the content of the button.
From "source/layout/forms/nsHTMLButtonControlFrame.cpp"
// Center child in the block-direction in the button
// (technically, inside of the button's focus-padding area)
nscoord extraSpace =
buttonContentBox.BSize(wm) - contentsDesiredSize.BSize(wm);
childPos.B(wm) = std::max(0, extraSpace / 2);
// Adjust childPos.B() to be in terms of the button's frame-rect:
childPos.B(wm) += clbp.BStart(wm);
nsSize containerSize = (buttonContentBox + clbp.Size(wm)).GetPhysicalSize(wm);
// Place the child
FinishReflowChild(aFirstKid, aPresContext, contentsDesiredSize,
&contentsReflowInput, wm, childPos, containerSize,
ReflowChildFlags::Default);
Given these two issues you can start to see how the button force the content to be centered, consider:
<button> tag
+------------------------+ ^
| button extra space | |
| | |
+------------------------+ |
|| ::moz-button-content || | button height
|| display: block; || |
+------------------------+ |
| | |
| button extra space | |
+------------------------+ v
If you give the button a height - like the 48px from your fiddle, the text will be centered because the moz-button-content element is display block and will only have the height of the content (most likely the line-height of the content by default) and when put next to another element you get this behaviour:
* {
box-sizing: border-box;
margin: 0;
border: 0;
padding: 0;
font-family: san-serif;
background: none;
font-size: 1em;
line-height:1;
vertical-align: baseline;
}
button, a {
height: 3em;
}
button {
background: red;
}
a {
display:inline-block;
background: green;
}
<button>Button content</button>
<a>Link Content</a>
This bug and this bug in the Firefox issue tracker was about a close as I could find to any actually documented bug. But the threads give the impression that despite this not appearing in any actual spec, the browsers have just implemented it this way "because the other browsers are doing it that way"
There is a work-around to the issue if you actually want to change the default behaviour, but it doesn't completely solve the problem and YMMV depending on your implementation.
If you insert a wrapper <span> with display: block as the only child of the button and put all your content inside it you can use it to skip over the moz-button-content element.
You will need to make this <span> element have height: inherit so it correctly fills the height of the button and then add your normal button styling to the <span> instead, you will get basically behaviour you want.
* {
box-sizing: border-box;
margin: 0;
border: 0;
padding: 0;
font-family: san-serif;
background: none;
font-size: 1em;
line-height:1;
vertical-align: baseline;
}
button, a {
height: 3em;
}
button {
background: red;
}
button::-moz-focus-inner {
border: 0;
padding: 0;
outline: 0;
}
button > span {
display: block;
height: inherit;
}
a {
display:inline-block;
background: green;
}
button.styled > span , a.styled{
padding: 10px;
background: yellow;
}
<button><span>Button content</span></button>
<a><span>Link Content<span></a><br/>
<button class="styled"><span>Button content</span></button>
<a class="styled"><span>Link Content<span></a>
It's also worth mentioning the appearance CSS4 rule (Not yet available):
While this is not a viable option (as of the 5th January) yet. There is a proposal to redefine the appearance rule in the CSS4 draft that might actually do the right thing an remove all assumptions made by the browser. I only mention it for completeness because it may become useful in the future.
UPDATE - 30/08/2016
You should actually use a <span> instead of a <div>, as div's aren't valid children for <button> elements. I have updated the answer to reflect this.
You could use padding.
For example
padding: 20px 10px;
I think that the only reason for this behaviour is that Google Chrome or browsers in general will take the default styles from your operating system.
For example, if you compare the button or scrollbar on Google Chrome run in windows 7 and windows 8:
In windows 7, the button will have a horizontal gradient line in the center of your button
In windows 8, the scrollbar are able to fade in and fadeout on click
This is just my opinion but hope that it can give you some ideas :)
You can use display:table-cell;
vertical-align: middle; as an alternate method.
On Mozilla Firefox I got the -moz-appearance property :
-moz-appareance: button;
In the HTML5 draft, there is a Rendering section, but doesn't details the placement :S
Button elements by default centers child elements vertically. It isn't done in a conventional CSS way, and therefor isn't trivial to override.
The best solution I have found is setting the button to flex column.
button {
height: 100px;
display: flex;
flex-direction: column;
}
span {
height: 20px;
width: 100px;
background-color: blue;
display: block;
}
<button>
<span></span>
</button>
Some answers suggested adding an inner wrapper, and setting it's height to inherit. This might not work for elements that have their height calculated dynamically.
In case you need to get rid of this behavior you can just add span as a child of button. Works better than trying to trick all the browsers.
The actual version of the Ionic progress bar comes without an option to display the percentage text.
I tried to add it manually using the ::after selector but to no avail.
This is my Ionic code:
ion-progress-bar {
height: 18px;
border-radius: 20px;
}
<ion-progress-bar color="success" value="0.9"></ion-progress-bar>
While inspecting the element this is what I get in chrome's elements inspector
.progress, .progress-indeterminate {
background: var(--progress-background);
z-index: 2;
}
.buffer-circles, .indeterminate-bar-primary, .indeterminate-bar-secondary, .progress, .progress-buffer-bar, .progress-buffer-bar:before, .progress-indeterminate {
left: 0;
right: 0;
top: 0;
bottom: 0;
position: absolute;
width: 100%;
height: 100%;
}
<ion-progress-bar _ngcontent-c0="" color="success" value="0.9" ng-reflect-value="0.9" ng-reflect-color="success" role="progressbar" aria-valuenow="0.9" aria-valuemin="0" aria-valuemax="1" class="ion-color ion-color-success progress-bar-determinate hydrated">
#shadow-root
<!-- ....... -->
<div class="progress" style="transform: scaleX(0.9);"></div>
<div class="progress-buffer-bar" style="transform: scaleX(1);"></div>
</ion-progress-bar>
The only way with which I can add a text from the elements inspector to the progress bar, is to add it inside the div with the progress class:
<div class="progress" style="transform: scaleX(0.9);">90%</div>
But adding this text from my Ionic code isn't possible, so I tried to use the ::after selector but It did not work:
.progress:after{
content: "90%";
}
I don't need that the text changes dynamically since the progress-bar must display a static value that does not change.
Thanks!
I think what I was trying to achieve is impossible since it is a direct manipulation of the shadow dom.
Based on this article, There are some key points concerning shadow dom:
You cannot style any of the internal elements of a web component from outside of the web component using CSS selectors
You can style the internal elements of a web component if CSS4 variables are being used, as you can change the values of the CSS4 variables.
You can style slotted content inside of a web component (i.e. content you have supplied to the web component) from outside of the web component
You can style the host element of the web component (i.e. the element you use to add the web component to a page) from outside of the web component
Since there is no css4 variable or property that allows us to add a text value to the progress-bar, I had no choice but to use a custom html progress bar:
.progress-outer {
width: 96%;
margin: 10px 2%;
padding: 3px;
text-align: center;
background-color: #f4f4f4;
border: 1px solid #dcdcdc;
color: #fff;
border-radius: 20px;
}
.progress-inner {
min-width: 15%;
width: 90%;
white-space: nowrap;
overflow: hidden;
padding: 5px;
border-radius: 20px;
background-color: var(--ion-color-primary);
}
<div class="progress-outer">
<div class="progress-inner">90%</div>
</div>
The appearance of the progress-bar can be then customized by changing the css properties
simply you can put
ion-progress-bar {height:15px;}
in global.scss ..
if you also want to make the border radius then you can add the radius inside as well , as
ion-progress-bar {height:15px;border-radius:15px;}
I am trying to style a tooltip in a jqgrid in a page delivered through AngularJS. Essentially in other places in the app I am using the Bootstrap tooltip styling. I'm struggling to get this to work in the AngularJS part (possibly to do with the initialisation not running in the right place). I thought I might change tack and try to emulate the styling instead.
I have started and got a very rough and ready bit of styling almost 'working' as a PoC (it needs a lot of work buit I want to see if it is possible before doing that work! It is here in the Fiddle
I have 2 questions I wondered if anyone could help me with before I try to tidy it up
1) Is there a way to stop the normal tooltip appearing as well (I thought I was styling the tooltip but I seem to be adding a second one!)
2) Is there a way to make it 'float'. In the fiddle it is not obvious but in the jqgrid where the th element is more structured (bounded) the css tooltip I have created is contained in the th element and mainly hidden (as it is too large for the element).
I'm thinking this is a CSS question more than a jqgrid question so just in case I'll point out I can't really use the span technique posted in a few answers.
Thanks.
The code in the fiddle is
<table>
<th title="This is a tooltip">John</th>
<th title="so is this">Albert</th>
<th title="And This">Spencer</th>
</table>
th[title]:hover:after {
content: attr(title);
background-color: #000;
color: #fff;
width: 120px;
text-align: center;
border-radius: 6px;
padding: 5px 0;
z-index: 1;
left: 50%;
top: 100%;
position: absolute;
margin-left: -60px;
margin-left: -5px;
border-width: 5px;
position: relative;
display: inline-block;
border-bottom: 1px dotted black;
border-style: solid;
border-color: #555 transparent transparent transparent;
}
Yes. All you need to do is change from title attribute to data-title so it would be: content: attr(data-title); Then also update the th title attribute accordingly.
I was wondering if this is possible:
if I have an input field:
<input type="button" value="some value" class="icon-button" />
and it is styled with gradient background, border, box-shadow, etc.
I want to have the button like an Icon with all its style and the value-text right next to it.
I thought of something like this, but it didn't work:
.icon-button{
display:block;
width: 25px;
height: 25px;
/* gradients, borders, shadows, etc. */
text-indent: 30px;
overflow: visible;
}
Any Idea? I know I could solve it with javascript, but I would like to know if there is a css way to do this.
I don't think you're going to achieve this (at least not very neatly) using an input. If you can amend your markup to use an actual button to submit though, it's pretty trivial:
<button type="submit">Some value</button>
CSS:
button {
line-height: 25px;
border: none;
background: transparent;
cursor: pointer;
}
button::before {
content: '';
display:inline-block;
vertical-align: middle;
width: 25px;
height: 25px;
margin-right: 3px;
/* gradients, borders, shadows, etc. */
background: red;
}
You could use a span rather than generated content if IE7 support is needed. This approach is not possible with an input, as that can't contain any elements, nor can it have generated content.
If you need to use an input, you could achieve the same thing by wrapping it in a span and styling that.
I have some HTML being generated in the controller and passed to the view to be added to a "SlickGrid". The problem I'm having, is that the CSS styles that SHOULD be applied are not being applied to that HTML. It's happening in a couple of instances, all with the same symptoms.
The HTML that is displayed is this (taken from Chrome's inspector tool):
<div id="pba-progress-688-5" class="checkpointLegend clickable A tipper" title="Approved<br><i>Composition Table</i><br>Click to go to this checkpoint.">✓</div>
The classes clickable, A, Tipper are not being applied, AND there is some checkpointLegend stuff that is not being applied as well.
checkPointLegend looks like this:
.checkpointLegend {
text-align: center;
vertical-align: middle;
font-weight: bold;
cursor: pointer;
}
.checkpointLegend div {
border: 1px solid #CCC;
border-radius: 4px 4px 4px 4px;
float: left;
height: 14px;
margin: 2px;
width: 12px;
font-size: 10px;
text-align: center;
line-height: 14px;
cursor: pointer;
}
The .checkpointLegend portion IS being applied, but the DIV part is NOT being applied.
Any thoughts as to why these classes are not being applied to the HTML when it is rendered?
For reference:
I'm using a fork of SlickGrid (https://github.com/andrewchilds/SlickGrid)
The CSS works fine in a WEBGRID (so I know it works), but the webgrid is too slow to handle the amount of data I'm throwing at it.
The controller generates the HTML and passes it to the view via an ajax call. The html is dumped directly into a cell in the slickgrid.
I'd be happy to clarify anything that needs to be clarified, or post more code if needed.
Any thoughts/pointers/suggestions/solutions would be GREATLY appreciated (I've been banging my head off my desk for 2 days on this...)