-
21 Mar 2012 6:37 AM #1
[4.1 RC1] Scoped CSS Incorrect in IE7/8
[4.1 RC1] Scoped CSS Incorrect in IE7/8
REQUIRED INFORMATION
Ext version tested:- Ext 4.1 RC1
- IE8
- IE7
- Chrome
- If you open the test case below in IE7/8, any of the browser specific CSS doesn't apply properly. For modern browsers (I tested in Chrome as well) this isn't really a problem that I can see, though it's still possible other errors can arise from the same thing.
- I reported this previously several versions ago as part of another issue, but it was not resolved despite the thread being marked as fixed. That thread can be found here: http://www.sencha.com/forum/showthre...=scoperesetcss. That particular thread provides a good overview of which classes are incorrect in the SASS.
Code:<html> <head> <title>Test</title> <link rel="stylesheet" type="text/css" href="resources/css/ext-all-scoped.css" /> <script type="text/javascript" src="ext-all-debug.js"></script> <script type="text/javascript"> Ext.scopeResetCSS = true; Ext.onReady(function() { var store = Ext.create('Ext.data.ArrayStore', { fields: ['company', 'price', 'change'], data: [ ['3m Co', 71.72, 0.02], ['Alcoa Inc', 29.01, 0.42], ['Altria Group Inc', 83.81, 0.28], ['American Express Company', 52.55, 0.01], ['American International Group, Inc.', 64.13, 0.31], ['AT&T Inc.', 31.61, -0.48] ] }); var grid = Ext.create('Ext.grid.Panel', { title: 'Array Grid', store: store, columns: [ {text: 'Company', flex: 1, dataIndex: 'company'}, {text: 'Price', width: 75, dataIndex: 'price'}, {text: 'Change', width: 75, dataIndex: 'change'} ], height: 200, width: 400, renderTo: 'test', viewConfig: { listeners: { render: function(view) { view.tip = Ext.create('Ext.tip.ToolTip', { // The overall target element. target: view.el, // Each grid row causes its own seperate show and hide. delegate: view.itemSelector, // Moving within the row should not hide the tip. trackMouse: true, // Render immediately so that tip.body can be referenced prior to the first show. renderTo: Ext.getBody(), listeners: { // Change content dynamically depending on which element triggered the show. beforeshow: function updateTipBody(tip) { tip.update('Over company "' + view.getRecord(tip.triggerElement).get('company') + '"'); } } }); } } } }); }); </script> </head> <body> <div id="test"></div> </body> </html>
HELPFUL INFORMATION
Additional CSS used:- Only ext-all-scoped.css
- WinXP Pro
-
21 Mar 2012 11:41 AM #2Sencha - Senior Forum Manager
- Join Date
- Mar 2007
- Location
- St. Louis, MO
- Posts
- 33,582
- Vote Rating
- 433
We can take a look at it.
Mitchell Simoens @SenchaMitch
Sencha Inc, Senior Forum Manager
________________
http://www.JSONPLint.com - Source to lint your JSONP!
Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
https://github.com/mitchellsimoens
Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/
Need more help with your app? Hire Sencha Services services@sencha.com
Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is almost in print!
When posting code, please use BBCode's CODE tags.
-
22 Mar 2012 9:07 AM #3
-
26 Mar 2012 12:56 AM #4
There are definitely other problems in modern browsers as well. See this thread for a few of them. For whatever reason, the button controls on fields get a width of 0px in the style attribute of the td element when using scoped css.
-
26 Mar 2012 2:48 AM #5
Line 102752 of ext-all-debug-w-comments.js reads:
My JS debugger says that me.triggerWidth is always 0. If triggerWidth isn't defined when initCompnent of Ext.form.field.Trigger is run, then it tries to compute the width of the trigger:Code:style: 'width:' + me.triggerWidth + (hideTrigger ? 'px;display:none' : 'px'),
The problem with this is that it is working with the body of the document, not the element that Ext creates with the x-reset class. The css rule that gives a trigger its width is x-form-trigger (the class applied to the temporary element). When using it in scoped mode, that css rule becomes:Code:if (!me.triggerWidth) { Ext.form.field.Trigger.prototype.triggerWidth = (tempEl = Ext.getBody().createChild({style: 'position:absolute', cls: Ext.baseCSSPrefix + 'form-trigger'})).getWidth(); tempEl.remove(); }
Notice the .x-reset. The body element doesn't have the x-reset class and hence this rule is never matched. That fixes some of the problems in the thread I linked to but it doesn't address other scoped problems.Code:.x-reset .x-form-trigger { background-image: url('../../resources/themes/images/default/form/trigger.gif'); background-position: 0 0; width: 17px; height: 21px; border-bottom: 1px solid #b5b8c8; cursor: pointer; cursor: hand; overflow: hidden; }
-
28 Aug 2012 7:13 PM #6
I see this line in initExtCss function:
add() accumulates a list of classes that are then applied to body tag. Should that line be negation? If we're not using scope reset, why add the reset class?Code:initExtCss = function() { ... if (!Ext.scopeResetCSS) { add('reset'); } ...Last edited by alicexyl; 29 Aug 2012 at 10:39 AM. Reason: More details
-
28 Aug 2012 7:42 PM #7
x-reset refers to the CSS reset that normalizes default values across browser. We only add it to the body if you're not scoping the css.
Evan Trimboli
Sencha Developer
Twitter - @evantrimboli
Don't be afraid of the source code!
-
29 Aug 2012 10:39 AM #8
If that's so, the usage of this class doesn't seem very clear to me then. For instance, in your SASS code, you use the class only if $scope-reset-css is true (I'm assuming that's the SASS conterpart of scopeResetCss ):
There are also places in your js code where you add the class if scopeResetCss is true:Code:// _reset.scss @if $scope-reset-css { .#{$prefix}border-box .#{$prefix}reset, .#{$prefix}border-box .#{$prefix}reset * { box-sizing:border-box; -moz-box-sizing:border-box; -ms-box-sizing:border-box; -webkit-box-sizing:border-box; } .#{$prefix}reset { html, body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td { margin:0; padding:0; } ...
Could you give more details as to how the class x-reset is used?Code:onRender : function(container, position) { ... if (Ext.scopeResetCSS && !me.ownerCt) { if (el.dom == Ext.getBody().dom) { el.parent().addCls(Ext.baseCSSPrefix + 'reset'); } else { me.resetEl = el.wrap({ cls: Ext.baseCSSPrefix + 'reset' }); } }
Update: I have Ext JS 4.1.0.
-
29 Aug 2012 2:42 PM #9
Also, the scoped stylesheet isn't generated correctly because of how the SASS code is structured. In ext4/default/_all.scss, the reset class is wrapped around all the module @includes:
Inside module code, we have code e.g.:Code:@if $scope-reset-css { .#{$prefix}reset { @if $include-default { @include extjs-boundlist; @include extjs-button; ...
So in the final CSS, the class selectors are not generated in correct order for a scoped sheet:Code:@if not $supports-gradients or $compile-all { @if $background-gradient != null { .#{$prefix}nlg { .#{$prefix}btn-#{$ui} { background-repeat: repeat-x; background-image: theme-background-image($theme-name, 'btn/btn-#{$ui}-bg.gif'); } } }
What you need are smarter browser/feature selectors. For instance, take .x-nlg:Code:.x-reset .x-nlg .x-btn-default-small
Then instead of .#{$prefix}nlg, use #{$nlg-selector}:Code:$nlg-selector: if($scoped-reset-css, '.#{$prefix}nlg &', '.#{$prefix}nlg');
Then the selectors will be generated in the right order:Code:@if not $supports-gradients or $compile-all { @if $background-gradient != null { #{$nlg-selector} { .#{$prefix}btn-#{$ui} { ... } } }
UPDATE: I just realized that if there's an SASS existing selector '.#{$prefix}nlg &', we can't just replace .#{$prefix}nlg there. Extra logic is needed to make sure '&' is applied ONLY if $scope-reset-css is false.Code:.x-nlg .x-reset .x-btn-default-small
Also, the fix should eliminate the need to run NeoJS's sed script: http://www.sencha.com/forum/showthread.php?142841-Ext.scopeResetCSS-Tooltip-Positioning-Issues/page2&highlight=scoperesetcss
UPDATE 2: I suggest that instead of using $scope-reset-css in _all.scss, that it be put into all the widget @mixins. Otherwise people who want to @include individual modules instead of using ext4/default/all would not be generating a scoped stylesheet.Last edited by alicexyl; 29 Aug 2012 at 2:57 PM. Reason: More detail
-
29 Aug 2012 2:46 PM #10
If you look at the file:
You'll see it just resets the styles directly, there's no need for x-reset, because it's already applied to the elements themselves. Similarly, if we're scoped, we wrap any components inside an x-reset div, so the reset changes are localized to that element, instead of being applied to the whole document.Code:@if $scope-reset-css { .#{$prefix}border-box .#{$prefix}reset, .#{$prefix}border-box .#{$prefix}reset * { box-sizing:border-box; -moz-box-sizing:border-box; -ms-box-sizing:border-box; -webkit-box-sizing:border-box; } .#{$prefix}reset { html, body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td { margin:0; padding:0; } // snip @else { html, body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td { margin:0; padding:0; }Evan Trimboli
Sencha Developer
Twitter - @evantrimboli
Don't be afraid of the source code!
Success! Looks like we've fixed this one. According to our records the fix was applied for
EXTJSIV-5678
in
4.2.


Reply With Quote

