Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Suggested approach for integrating FontAwesome, WebFonts, etc

    SmartGwt 3.0 Power
    FF10 and IE8
    Quirks Mode

    I've been playing with the idea of writing an integration of FontAwesome into SmartGwt by creating a new button class extended from StatefulCanvas.

    I'm running into a couple of issues:
    1) Compatibility : In order for @font-face to be recognized by FF10 and IE8 (the only 2 browsers I'm testing with so far), I have to declare a DOCTYPE and some standards mode. This makes the @font-face be recognized by both but then several other issues occur in SmartGwt. I know the suggested best practice is to leave out the DOCTYPE and use quirks mode. In doing so, FF10 still works fine with @font-face but IE8 stops seeing the font icons. I've just decided to exclude IE for now and continue on but if you have any suggestions for this, I'm all ears.

    2) CSS not being respected. I've taken the Twitter Bootstrap .btn css and added it as the baseStyle for my new button class. I've tried the suggested approach of overriding getInnerHTML() as well as playing around with setContents() but certain things from the baseStyle CSS are not honored using either approach.

    Are there certain css properties that are tied to StatefulCanvas that cannot be changed via css?

    So far, here is a compiled list of all the css properties that don't seem to work correctly or at all:
    - cursor
    - padding (left, top, bottom works but right does not)

    Finally, setTitle() and setIcon() don't seem to do anything with a class extended from StatefulCanvas. What am I doing wrong?

    Here is some code:
    css
    Code:
    .myBtn,
    .myBtnOver,
    .myBtnFocused,
    .myBtnFocusedOver,
    .myBtnDown,
    .myBtnFocusedDown,
    .myBtnSelected,
    .myBtnSelectedFocused,
    .myBtnSelectedDown,
    .myBtnSelectedFocusedDown,
    .myBtnSelectedOver,
    .myBtnSelectedFocusedOver,
    .myBtnDisabled,
    .myBtnSelectedDisabled {
    	display:inline-block;
    	*display:inline;
    	*zoom:1;
    	padding:4px 10px 4px;
    	margin-bottom:0;
    	font-size:14px;
    	line-height:20px;
    	*line-height:20px;
    	color:#5c5f63;
    	text-align:center;
    	text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);
    	vertical-align:middle;
    	cursor:pointer;
    	background-color:#551122;
    	background-image:-moz-linear-gradient(top, #f7f8fa, #edeeef);
    	background-image:-ms-linear-gradient(top, #f7f8fa, #edeeef);
    	background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f7f8fa), to(#edeeef));
    	background-image:-webkit-linear-gradient(top, #f7f8fa, #edeeef);
    	background-image:-o-linear-gradient(top, #f7f8fa, #edeeef);
    	background-image:linear-gradient(top, #f7f8fa, #edeeef);
    	background-repeat:repeat-x;
    	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7f8fa', endColorstr='#edeeef', GradientType=0);
    	border-color:#edeeef #edeeef #c5c8cb;
    	border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
    	*background-color:#551122;
    	filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);
    	background:#f7f8fa;
    	border:1px solid #e1e2e5;
    	*border:0;
    	border-bottom-color:#c6c8cd;
    	-webkit-border-radius:4px;
    	-moz-border-radius:4px;
    	border-radius:4px;
    	*margin-left:.3em;
    	-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
    	-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
    	box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
    }
    FontIcon.java
    Code:
    public class FontIcon extends StatefulCanvas {
    	String icon;
    	String title;
    	
    	public FontIcon(String iconStr, String label) {
    		this.icon = "icon-" + iconStr;
    		this.title = label;
    		setBaseStyle("myBtn");
    		this.setContents("<span style=\"white-space:pre;\"><i class=\"" + icon + "\"></i>" + title + "</span>");
    		this.setSize("1", "1");
    	}
    }
    FontIconTestPage.java
    Code:
    public class FontIconTestPage extends VLayout {
    	
    	public FontIconTestPage() {
    		setSize("100%", "100%");
    		setPadding(16);
    		setMembersMargin(8);
    		
    		final FontIcon btn1 = new FontIcon("ok", " Okay");
    		addMember(btn1);
    	}
    }

    #2
    Unfortunately IE9 now turns off several critical features if you do not use HTML5 DOCTYPE (eg, <canvas>), so we've been forced to change the recommendation.

    We don't know of any issue that would cause disappearing icons in IE8 with HTML5 DOCTYPE, but we would recommend excluding IE from a cosmetic upgrade like FontAwesome anyway - it doesn't exactly have performance to burn :)

    If you want to attempt this, you definitely want to extend Button, not StatefulCanvas.

    In general, we faithfully apply your CSS and you can see this in Firebug, but browsers do have bugs.

    "cursor" is controlled by Canvas.cursor because it has more going on than can be dealt with just with CSS.

    There shouldn't be issues with padding, but again, if you are trying to create a custom Button, extending from Button makes more sense, so that would be the next step.

    Comment


      #3
      Funny you should say this... my forked approach for the last couple of hours has been extending Button.

      This is nice for several reasons:
      - it has a more natural API to override (for setting icon, title, etc)
      - it is already nowrap
      - it already handles some cursor stuff
      - others I can't remember right now

      However, I'm now running into issues where it seems my css is fighting some in-line style defaults of Button (like size). Setting Overflow to VISIBLE fixes how it looks, but then state changes make the button grow / shrink despite there not being anything in the css that would make this happen. Calling setSize() doesn't have an impact on the visual button - it instead changes the size of the parent <tr> entry... which StatefulCanvas doesn't seem to use but Button does.

      I'll try to put together some screenshots and the new code and explain the new quirks I'm seeing.

      Comment


        #4
        Adding padding or just changing font style to bold will affect size. So would updating to a new font-face via WebFonts - you might need a call to adjustForContent() to compensate once the text has been replaced (there's no way to auto-detect this).

        If you're seeing things clipped off when overflow is not set to visible, it's probably yet another instance where the browser reports sizes wrong - browsers in general are riddled with bugs where they forget to report right-hand padding or margins or whatever as part of the size.

        We'd have to see a specific Button and CSS applied to it to say for sure, so we'll wait for your next bit of sample code.

        Comment


          #5
          Was out of town for a 3-day weekend. Will post code in just a few (I'm updating SmartGwt libs).

          As a side note - any idea on how to get @Font-Face to work with IE, Chrome, and FF with the same DOCTYPE? I can't find anything that works for all 3 at the same time.

          Comment


            #6
            Here is what it looks like in quirks mode and HTML 5 DOCTYPE in FF10.

            FontIconTestPage.java
            Code:
            public class FontIconTestPage extends VLayout {
            	
            	public FontIconTestPage() {
            		setSize("100%", "100%");
            		setPadding(16);
            		setMembersMargin(8);
            		
            		Button btn2 = new Button("Test Button");
            		addMember(btn2);
            
            		FontIconButton btn1 = new FontIconButton("ok", " Okay");
            		addMember(btn1);
            	}
            		
            }
            FontIconButton.java
            Code:
            public class FontIconButton extends Button {
            	String icon;
            	String title;
            	
            	public FontIconButton(String iconStr, String label) {
            		this.icon = "icon-" + iconStr;
            		this.title = label;
            		setBaseStyle("myBtn");
            		this.setTitle("<i class=\"" + icon + "\"></i>" + title);
            	}
            }
            CSS
            Code:
            @font-face {
            	font-family: 'FontAwesome';
            	src: url('../fonts/fontawesome-webfont.eot'); /* IE9 Compat Modes */
            	src: url('../fonts/fontawesome-webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
            	     url('../fonts/fontawesome-webfont.woff') format('woff'), /* Modern Browsers */
            	     url('../fonts/fontawesome-webfont.ttf')  format('truetype'), /* Safari, Android, iOS */
            	     url('../fonts/fontawesome-webfont.svg#svgFontName') format('svg'); /* Legacy iOS */
            	font-weight: normal;
            	font-style: normal;
            	}
            
            /*  Font Awesome styles
                ------------------------------------------------------- */
            [class^="icon-"]:before, [class*=" icon-"]:before {
              font-family: FontAwesome;
              font-weight: normal;
              font-style: normal;
              /* display: inline-block; */
              text-decoration: inherit;
            }
            a [class^="icon-"], a [class*=" icon-"] {
              /* display: inline-block; */
              text-decoration: inherit;
            }
            
            .myBtn,
            .myBtnOver,
            .myBtnFocused,
            .myBtnFocusedOver,
            .myBtnDown,
            .myBtnFocusedDown,
            .myBtnSelected,
            .myBtnSelectedFocused,
            .myBtnSelectedDown,
            .myBtnSelectedFocusedDown,
            .myBtnSelectedOver,
            .myBtnSelectedFocusedOver,
            .myBtnDisabled,
            .myBtnSelectedDisabled {
            	/* display:inline-block;
            	*display:inline; */
            	*zoom:1;
            	padding:4px 10px 4px;
            	margin-bottom:0;
            	font-size:14px;
            	line-height:21px;
            	*line-height:20px;
            	color:#5c5f63;
            	text-align:center;
            	text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);
            	vertical-align:middle;
            	/* cursor:pointer; */
            	background-color:#551122;
            	background-image:-moz-linear-gradient(top, #f7f8fa, #edeeef);
            	background-image:-ms-linear-gradient(top, #f7f8fa, #edeeef);
            	background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f7f8fa), to(#edeeef));
            	background-image:-webkit-linear-gradient(top, #f7f8fa, #edeeef);
            	background-image:-o-linear-gradient(top, #f7f8fa, #edeeef);
            	background-image:linear-gradient(top, #f7f8fa, #edeeef);
            	background-repeat:repeat-x;
            	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7f8fa', endColorstr='#edeeef', GradientType=0);
            	border-color:#edeeef #edeeef #c5c8cb;
            	border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
            	*background-color:#551122;
            	filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);
            	background:#f7f8fa;
            	border:1px solid #e1e2e5;
            	*border:0;
            	border-bottom-color:#c6c8cd;
            	-webkit-border-radius:4px;
            	-moz-border-radius:4px;
            	border-radius:4px;
            	*margin-left:.3em;
            	-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
            	-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
            	box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
            }
            Attached Files

            Comment


              #7
              adjustForContent doesn't seem to do anything - I could be using it wrong I guess. I tried calling it in FontIconButton constructor and it didn't seem to do anything.

              Okay - so the issue seems to center around some defaults being set by the Button class. Specifically, its size and its visibility.

              If I change the visibility to be .VISIBLE, then the button is just large enough to fit the content (as I would expect), but hovering over the button causes the bottom to grow just slightly and the text to move down and if I mouseOut on the button, the text and bottom shift back.

              If I set the size specifically, then the outcome depends on whether or not the size is >= what the min size of the content is. If it is too small, then the bottom is cut off. If it is too large then mouseOver doesn't cause the button to grow larger, but it causes the icon and label on the button to move up/down on mouseOver / mouseOut.

              Upon further investigation, it appears that the width:1.25em is being ignored. And setWidth("1.25em") just makes the button really small - I'm guessing it doesn't accept 'em' and is just reading the 1.25.

              So the big question is... how can I make a custom button that extends from Button have its size determined by css?

              Comment


                #8
                Worked on this some more tonight - I believe I may have narrowed down the culprit(s).

                Setting the line-height in css just causes the vertical sizing to be messed up in SmartGwt. It doesn't matter if it is pixel, em, %, etc.

                If I remove line-height from the css, the vertical sizing works fine.

                The width was set to 1.25em in the FontAwesome CSS. This makes sense - their css is for the single icon. In SmartGwt land, the width is applied to the entire button's "title" so 1.25em is bad. :) However, correcting it doesn't solve the problem. It appears SmartGwt width doesn't play nice with 'em'. Bug?

                It would be real nice to fix the 'em' and 'line-height' issue because it would allow the API to set the button size depending on the font-size (ideal) and keep a consistent look & feel as far as padding and such goes. Without it, it kind of works but the padding doesn't scale well for buttons of various sizes.

                So here is the work around for now:
                - Use Quirks Mode (doesn't work for IE8 - haven't tested other IE versions). Works perfect for Chrome and FF10.
                - Comment out any 'display' entries in CSS for the custom button base style
                - Comment out any 'line-height' entries in CSS for the custom button base style
                - Width of type 'px' works fine in the CSS. Using 'em' will cause some rendering issues
                - Set custom button to Overflow.VISIBLE

                If you want IE to work, you can use DOCTYPE (I tested HTML5 DOCTYPE). This causes IE8 to work fine but then FF10 had an issue where the initial drawing of the button would be cut off on the right-hand side but once you hover over it, it redrew to the correct size and stayed that way. This DOCTYPE also caused issues in Chrome where the button would change size back and forth as you mouseOver and mouseOut on it.

                So questions are: Any idea why the button would behave that way in DOCTYPE HTML5 with FF and Chrome? Also, is the 'em' issue a bug?
                Last edited by amcculley; 9 Sep 2012, 20:45.

                Comment


                  #9
                  setWidth('1.25em') is not supported - the String argument is there to allow percents ("25%") but not other units.

                  "em" as a sizing unit for widgets in general is basically not supportable in current browsers with the sizing-related features (auto-sizing and various advanced layouts) that SmartGWT needs to support. There basically is not strong enough browser support to make this possible. Maybe in another 5 years when more legacy browsers have been retired.

                  Applying "em" just to HTML content that SmartGWT is auto-sizing to (such as HTML within an HTMLFlow) is generally fine, however in this case if you're doing it via 'line-height' in a replacement for button.baseStyle then you are applying the line-height to the wrong element.

                  Similar issues with copying over 'display' settings - these are intended for a different HTML structure.

                  You could use CSS selectors to apply these settings to appropriate elements but bear in mind this too will disqualify older IE, and the specific HTML structures we output aren't actually supported aspects of the framework.

                  The combination of all of this stuff appears to be revealing sizing bugs in FF/Chrome. This might be because the browsers are drawing at sub-pixel precision but reporting whole pixel sizes to SmartGWT.

                  Make sure you don't use quirks mode for IE9 or again it turns off features (like <canvas>, which is used for FacetChart).

                  Comment


                    #10
                    Originally posted by Isomorphic View Post
                    setWidth('1.25em') is not supported - the String argument is there to allow percents ("25%") but not other units.

                    "em" as a sizing unit for widgets in general is basically not supportable in current browsers with the sizing-related features (auto-sizing and various advanced layouts) that SmartGWT needs to support. There basically is not strong enough browser support to make this possible. Maybe in another 5 years when more legacy browsers have been retired.
                    This makes sense to me. The workaround will be buttons of various sizes with the padding specified accordingly as opposed to buttons that resize automatically depending on font-size. Not a big deal really on this one. Thanks.

                    Originally posted by Isomorphic View Post
                    Applying "em" just to HTML content that SmartGWT is auto-sizing to (such as HTML within an HTMLFlow) is generally fine, however in this case if you're doing it via 'line-height' in a replacement for button.baseStyle then you are applying the line-height to the wrong element.
                    I noticed this in FireBug. What would be the correct element to apply it to then and how do I get a hook to this element from within Java? I tried getParent() and getParentElement() and both returned 'null'.

                    Originally posted by Isomorphic View Post
                    You could use CSS selectors to apply these settings to appropriate elements but bear in mind this too will disqualify older IE, and the specific HTML structures we output aren't actually supported aspects of the framework.
                    I have about had it with IE to be honest :) Unfortunately, almost all of our clients insist on using it for security reasons so we have to support IE8+. Is this an issue for IE8 and newer or only IE6 and IE7?

                    Originally posted by Isomorphic View Post
                    Make sure you don't use quirks mode for IE9 or again it turns off features (like <canvas>, which is used for FacetChart).
                    I'm going in and doing some refactor for !DOCTYPE HTML. It is causing some of our fonts and stuff to look odd so trying to clean this up.

                    Comment


                      #11
                      Remember that the DOM of a SmartGWT widget is considered undocumented internals, subject to change without notice.

                      It has to be this way because browser bugs force different structures on different browsers, and new versions of browsers often introduce bugs that require DOM structure changes to work around.

                      Perhaps in 5 years things will be consistent enough to document portions of the DOM of simpler widgets.

                      However if you're prepared to deal with different DOMs and possible future breakage, right now there is a two-cell <table> holding the title and icon. You would use standard CSS selectors to target this structure (look out for IE8's spotty selector approach).

                      "line-height" would be something to apply to the title cell only. "display" is just inappropriate - meant for a totally different DOM.

                      Comment


                        #12
                        Just for completeness - the other way to handle this is to use Feature Sponsorship to have support for font rendering engines like these built-in, or just to get some additional APIs that would let you, for example, apply CSS properties to the title without having to know the DOM structure.

                        Comment


                          #13
                          Font-rending is in and works awesome. Getting completely original skinned buttons in (like the ones from Twitter Bootstrap) is proving to be the difficult part.

                          Comment


                            #14
                            Spoke too soon. Had several issues with cross-browser compatibility and eventually just opted to use the original twitter bootstrap glyphicon approach (not font-based). I'll revisit the selector approach when I have more time but from trying it very quickly, it seems that different browsers have slightly different dom structures or in-line settings.

                            Not sure if I want to go down that slippery path knowing that it could all change (however unlikely that may be).

                            Comment


                              #15
                              I've solved the issue of the font icon causing the width to shift upon css replacement.

                              What was happening is that the size of the element is calculated prior to the font replacement. So once the font is replaced by the icon, it causes the old calculated size to be invalid. As soon as you would mouse over, the element would shift, cut off, etc.

                              I was able to "wrap" the font icon in a display:table-cell with a fixed width which accounts for the post-replacement size of the icon so now it doesn't resize horizontally. However, I'm unable to accomplish the same thing vertically. Min/Max/Fixed height doesn't seem to work the same way that Min/Max/Fixed width did.

                              Still plugging away :)

                              Comment

                              Working...
                              X