> On Jun 7, 2018, at 10:44 PM, Alex Harui <aha...@adobe.com.INVALID> wrote: > > Are you testing with the selector that sets position!=static throughout the > DOM?
No. I’m testing with no extra selectors. I dropped that idea. Thanks for pointing out the problems with it. :-) I don’t think it’s usually necessary. The real problem turns out to be the use of offsetParent. > If not, then I think that the "get what you set" rule has to apply and I > would think that code is necessary. That was also a rule in Flex. The > following was always true: > > Var value:int = 10; > someWidget.x = value; > value == someWidget.x; // this was always true. This is still true. With the current code in the branch, once set, the getter and setter will always match. > Otherwise, I think simple animation code might fail: > > Function timerHandler():void > { > someWidget.x += 10; > } > > The above reads x and sets it to x+10. This will work (and I see animations working perfectly in RoyaleStore). The only case it will not work is if three conditions are fulfilled: 1. The x value started off being undefined and you do someWidget.x += 10; 2. The offsetParent is not the parent. 3. The element is offset from the offsetParent at some value other than 0. I have yet to find a case where this is a problem. If there is, then by all means, I’d like to know, but I’m willing to bet there’s some way of fixing it other than paying for that code in UIBase. > It is not PAYG to worry about the performance of an API that is rarely used. > That is how PAYG works. You pay for it when you use it. If you can lower > the cost without making everyone pay for it, great, but the most important > principle is that you cannot make everyone pay for it just-in-case. > Migrating apps may pay more in order to change less code, but AIUI, the trend > in UI design in general is to get away from absolute positioning and use > flexbox and CSSGrid in order to have responsive UIs, so I don't see x,y > performance as important. I did a lot of profiling. Trust me. It’s important. It’s the single-largest performance bottleneck I’ve found in Royale apps. Sometimes, you can improve it by being smarter about where you set x and y values, but not always. It effects every use of x=“” and y=“” used in MXML. The vast majority of apps will have some x and y value somewhere. In your animation code example, having the offsetParent code in the setter makes the animation *way* less efficient. There is a an extra forced reflow for every assignment of the new value. Also, it’s extra code in UIBase “just in case” we care about the offsetParent relative position. I don’t see how you can claim it’s not a violation of PAYG. It’s code in UIBase that is just in case. Also, the vast majority of uses of x and y do not need that code. It’s “just in case”. It also has nasty side effects. Without a clear need for this code, I don’t know why you are arguing so strongly to keep it. > I think you are saying there is a bug in the current code, but it somehow > involves offsetParent changing. Can you explain what causes offsetParent to > change? If/when the parent (or grandparent or great-grandparent, etc.) element position changes from static to some other value, the offsetParent will change. > > Thanks, > -Alex > > On 6/7/18, 12:22 PM, "Harbs" <harbs.li...@gmail.com > <mailto:harbs.li...@gmail.com>> wrote: > >> I hope the current implementation tries to mimic Flash/Flex for backward >> compatibility reasons. > > Here’s the kicker: > > I have not yet found a *SINGLE* case yet where this attempt to mimic the > Flash/Flex behavior is necessary to *GET THE SAME RESULT*. Both my own app > and the examples that I’ve tested seem to work perfectly without the > offsetParent code. The *ONLY* effect I’ve seen from this code is that it: > > 1. Causes bugs in the layout lifecycle. > 2. Causes a significant performance hit when writing x and y values. > > So, to me the question is *WHAT IS THE CASE WHERE THIS CODE IS ACTUALLY > NEEDED*? Sure. I understand theoretically why it’s needed, but I don’t see an > *ACTUAL* problem with removing the code. It seems to me like the theoretical > case can be handled with utility functions. > > I’ll try to do some more testing, but after my initial tests, I’m > questioning whether this code is serving a function anymore. I remember it > being needed at some point in the past, but it could be it’s legacy code > which is no longer useful. > > Harbs > >> On Jun 7, 2018, at 10:13 PM, Alex Harui <aha...@adobe.com.INVALID> wrote: >> >> I'm not sure I'm understanding. >> >> There is no x,y in HTML/JS, so we can make it mean anything we want it to. >> I hope the current implementation tries to mimic Flash/Flex for backward >> compatibility reasons. We could agree to change that if we really want to, >> but I think backward-compatibility is useful here. >> >> In Flex/Flash, if you set the x,y to 10,10, then the object is offset by 10 >> pixels from the top-left of the parent. If you read back x,y it will be >> 10,10. However, in Royale, we map x,y to the "left" and "top" styles. if >> the parentNode has position=static, then we need code to compensate for that. >> >> One way is to make sure nobody has position=static. That doesn't seem PAYG, >> might break snippets from the internet, and can be overridden by someone >> setting position=static on an element (not sure why anyone would do that). >> >> Another way is, when you set x,y, we set position!=static on the parent. I >> think we tried that and there was some problem, but maybe we should try that >> again. That would be PAYG, IMO. It is only applied when used. >> >> But again, I want to understand the fundamental use cases. The one you >> cited in RoyaleStore turned out to be an un-needed hack. What are the real >> use cases we need to consider? How important/prevalent is setting x,y >> outside of effects, popups, and absolute layout going to be? Otherwise, >> the code can be inefficient because you only pay for it in rare cases, which >> is more PAYG then making every node pay for it "just-in-case". >> >> My 2 cents, >> -Alex >> >> On 6/7/18, 12:00 PM, "Harbs" <harbs.li...@gmail.com >> <mailto:harbs.li...@gmail.com> <mailto:harbs.li...@gmail.com >> <mailto:harbs.li...@gmail.com>>> wrote: >> >> I don’t think I was clear enough. The original issue that started this >> thread is actually caused by the code which sets the y value based on the >> parentOffset. If the parentOffset is ignored, the issue goes away and we >> don’t have to care about layout lifecycles. >> >> For the few cases where we need to read and set the *actual observed* x >> and y positions based on the offsetParent which might be different than the >> actual parent, we can use utility functions to get and set these values. >> >>> On Jun 7, 2018, at 9:27 PM, Harbs <harbs.li...@gmail.com >>> <mailto:harbs.li...@gmail.com>> wrote: >>> >>>> So, if we don't force position!=static throughout the DOM, then you have >>>> to have code that compensates for that difference. >>> >>> I don’t think I agree. Right now we’re modifying the x and y values because >>> we *might* care about the offsetParent. That’s not PAYG. In fact, the set >>> values will be *wrong* if the position of the parent is changed after the x >>> and y values of the child are set. >>> >>> Based on my observations, most apps will not need to set the values based >>> on the offsetParent, so hard-wiring that code in is not PAYG. This is >>> especially true since setting x and y currently forces a reflow of HTML. >>> We’re suffering a major performance hit for no reason. >>> >>> In cases where we care about the parentOffset, we can use observedX and >>> observedY utility methods which account for offsetParent. That seems much >>> more PAYG to me. >>> >>> Removing the assumptions of reliance on offsetParent seems to eliminate all >>> needs to care about parent positioning. >>> >>> My $0.02, >>> Harbs >>> >>>> On Jun 7, 2018, at 8:23 PM, Alex Harui <aha...@adobe.com.INVALID >>>> <mailto:aha...@adobe.com.INVALID> <mailto:aha...@adobe.com.INVALID >>>> <mailto:aha...@adobe.com.INVALID>> <mailto:aha...@adobe.com.INVALID >>>> <mailto:aha...@adobe.com.INVALID><mailto:aha...@adobe.com.INVALID >>>> <mailto:aha...@adobe.com.INVALID>>>> wrote: >>>> >>>> IIRC, the parentNode is always the parent of the child if you examine the >>>> DOM. offsetParent is the parent or grandparent, etc, that has position != >>>> static, and left/top/right/bottom styles are always relative to >>>> offsetParent. So, if we don't force position!=static throughout the DOM, >>>> then you have to have code that compensates for that difference. >>>> >>>> IMO, the key issue is whether it is "ok" to force position!=static >>>> throughout the DOM. Can someone look at other JS frameworks? I'll bet >>>> most of them use border-box like we do. If the major JS frameworks have >>>> opted for position!=static, then it might be the right thing for us to do >>>> as well. IMO, we would like to make it easy for snippets found on the >>>> internet to work in Royale and they may not all presume position!-static. >>>> >>>> Also, IMO, our Containers should not presume position!=static. Containers >>>> accept assignable Layouts and the Layouts can set position!=static on the >>>> children and be appropriately named (VerticalLayoutWithXYSupport). That's >>>> PAYG to me. Remember that TLCs should have very little assumptions as >>>> illustrated in the ExplodedComponent example. The beads can make >>>> assumptions and be appropriately named and documented. >>>> >>>> My 2 cents, >>>> -Alex >>>> >>>> On 6/7/18, 6:15 AM, "Harbs" <harbs.li...@gmail.com >>>> <mailto:harbs.li...@gmail.com> <mailto:harbs.li...@gmail.com >>>> <mailto:harbs.li...@gmail.com>> <mailto:harbs.li...@gmail.com >>>> <mailto:harbs.li...@gmail.com> <mailto:harbs.li...@gmail.com >>>> <mailto:harbs.li...@gmail.com>>>> wrote: >>>> >>>> I created a “simplify-position” feature branch which does away with the >>>> offsetParent logic in UIBase. It does not change anything regarding >>>> position: static. >>>> >>>> I have tested with my own app and a number of the examples. I haven’t >>>> found any problems yet. >>>> >>>> Input welcome… >>>> >>>> Harbs >>>> >>>>> On Jun 7, 2018, at 12:20 PM, Harbs <harbs.li...@gmail.com >>>>> <mailto:harbs.li...@gmail.com> <mailto:harbs.li...@gmail.com >>>>> <mailto:harbs.li...@gmail.com>> <mailto:harbs.li...@gmail.com >>>>> <mailto:harbs.li...@gmail.com> <mailto:harbs.li...@gmail.com >>>>> <mailto:harbs.li...@gmail.com>>>> wrote: >>>>> >>>>>> So, IMO, it would be nice to do a similar investigation of >>>>>> controlsPallette. >>>>> >>>>> You are right. Removing the y value has no effect. >>>>> >>>>> I am wondering that maybe it makes sense to apply relative to the >>>>> Container CSS selector and possibly a few others. >>>>> >>>>> I’m trying to understand the specific cases where: >>>>> if (positioner.parentNode != positioner.offsetParent) >>>>> >>>>> Is required in setX, get x and setY, get y in UIBase. I would *really* >>>>> like to get rid of that code, and I’m, wondering what doing so would >>>>> cause. >>>>> >>>>>> On Jun 7, 2018, at 12:36 AM, Alex Harui <aha...@adobe.com.INVALID >>>>>> <mailto:aha...@adobe.com.INVALID> <mailto:aha...@adobe.com.INVALID >>>>>> <mailto:aha...@adobe.com.INVALID>> <mailto:aha...@adobe.com.INVALID >>>>>> <mailto:aha...@adobe.com.INVALID><mailto:aha...@adobe.com.INVALID >>>>>> <mailto:aha...@adobe.com.INVALID>>> <mailto:aha...@adobe.com.INVALID >>>>>> <mailto:aha...@adobe.com.INVALID> <mailto:aha...@adobe.com.INVALID >>>>>> <mailto:aha...@adobe.com.INVALID>><mailto:aha...@adobe.com.INVALID >>>>>> <mailto:aha...@adobe.com.INVALID><mailto:aha...@adobe.com.INVALID >>>>>> <mailto:aha...@adobe.com.INVALID>>>>> wrote: >>>>>> >>>>>> In the case of the controlsPallette, how did it get its size? I could >>>>>> certainly understand that if you didn't have position!=static, that >>>>>> setting top on the dockAndOuterContainer would have no effect, but you >>>>>> shouldn't have had to set y or top in the first place. IIRC, you >>>>>> couldn't use x,y in Flex layouts like VerticalLayout/HorizontalLayout so >>>>>> migrating code shouldn't be using it. It is fine to create other >>>>>> layouts that support x,y as exceptions. >>>>>> >>>>>> In general, for a framework, we want to make sure we understand and fix >>>>>> the fundamental problem before we address any hacks/exceptions. IMO, >>>>>> the fundamental problem in the scenarios you've provided so far is that >>>>>> the layout did not do what was expected so someone tried using x,y to >>>>>> fix it. First we need that layout do what is expected, then worry about >>>>>> how folks might resolve other issues, if any. >>>>>> >>>>>> In ProductsView in RoyaleStore, the grip is an image loaded later, so >>>>>> there might have been an issue there, especially on the SWF side, but I >>>>>> would expect the browser to automatically re-layout once the grip image >>>>>> loaded. I dug through Git history and found that I was the one who >>>>>> hacked in the x,y. It could be that early on, the layout did not use >>>>>> FlexBox so we had a similar problem of responding to the grip image >>>>>> loading late. But we should remove the x,y and see if there is still a >>>>>> problem and ponder the right fix for that. ProductsView should not need >>>>>> to be setting x,y. >>>>>> >>>>>> So, IMO, it would be nice to do a similar investigation of >>>>>> controlsPallette. IMO, if you examine that div, it's offsetHeight >>>>>> should be 40 and if it is then you shouldn't need to set style.top=40 on >>>>>> docAndOuterContainer which means that it shouldn't matter what >>>>>> style.position is. >>>>>> >>>>>> My 2 cents, >>>>>> -Alex >>>>>> >>>>>> On 6/6/18, 2:12 PM, "Harbs" <harbs.li...@gmail.com >>>>>> <mailto:harbs.li...@gmail.com> <mailto:harbs.li...@gmail.com >>>>>> <mailto:harbs.li...@gmail.com>> <mailto:harbs.li...@gmail.com >>>>>> <mailto:harbs.li...@gmail.com> <mailto:harbs.li...@gmail.com >>>>>> <mailto:harbs.li...@gmail.com>>> <mailto:harbs.li...@gmail.com >>>>>> <mailto:harbs.li...@gmail.com> <mailto:harbs.li...@gmail.com >>>>>> <mailto:harbs.li...@gmail.com>> <mailto:harbs.li...@gmail.com >>>>>> <mailto:harbs.li...@gmail.com> <mailto:harbs.li...@gmail.com >>>>>> <mailto:harbs.li...@gmail.com>>>>> wrote: >>>>>> >>>>>> >>>>>>> On Jun 6, 2018, at 11:05 PM, Harbs <harbs.li...@gmail.com >>>>>>> <mailto:harbs.li...@gmail.com> <mailto:harbs.li...@gmail.com >>>>>>> <mailto:harbs.li...@gmail.com>> <mailto:harbs.li...@gmail.com >>>>>>> <mailto:harbs.li...@gmail.com><mailto:harbs.li...@gmail.com >>>>>>> <mailto:harbs.li...@gmail.com>>> <mailto:harbs.li...@gmail.com >>>>>>> <mailto:harbs.li...@gmail.com> <mailto:harbs.li...@gmail.com >>>>>>> <mailto:harbs.li...@gmail.com>><mailto:harbs.li...@gmail.com >>>>>>> <mailto:harbs.li...@gmail.com><mailto:harbs.li...@gmail.com >>>>>>> <mailto:harbs.li...@gmail.com>>>>> wrote: >>>>>>> >>>>>>> <js:Label x="20" y="20" >>>>>>> text="{locStr.UPLOAD_YOUR_IMAGE}"/> >>>>>>> >>>>>> >>>>>> It actually, looks like the x and y values no longer have an effect on >>>>>> this particular component, but there was clearly a reason they were >>>>>> needed to be specified at some point… >>>>>> >>>>>> Another one. I have an image which needs to stick to the bottom right of >>>>>> the app. To do that I needed to following: >>>>>> >>>>>> top: calc(100% - 21px); >>>>>> left: calc(100% - 187px); >>>>>> position: fixed; >>>>>> >>>>>> With a default of position: relative, I’m able to do this: >>>>>> >>>>>> top: -21px; >>>>>> float: right; >>>>>> right: 10px; >>>>>> >>>>>> This being said, it actually looks like I’m wrong about the way to set >>>>>> the defaults being .Application *{}. This actually has a *higher* >>>>>> specificity than .foo{}.[1] >>>>>> >>>>>> I think the only way to guarantee that it’ll have a lower specificity >>>>>> than other selectors is to use: >>>>>> >>>>>> *{ >>>>>> position: relative; >>>>>> } >>>>>> >>>>>> I’m less happy about this option than ."Application *” because it’ll >>>>>> effect elements outside the Royale app if it’s not in an iframe. >>>>>> >>>>>> Harbs >>>>>> >>>>>> [1]https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0 >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0> >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0 >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0>> >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0 >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0> >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0 >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0>>> >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0 >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0> >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0 >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0>> >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0 >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0> >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0 >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0>>>> >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0 >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0> >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0 >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0>> >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0 >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0> >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0 >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0>>> >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0 >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0> >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0 >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0>> >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0 >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0> >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0 >>>>>> >>>>>> <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.smashingmagazine.com%2F2007%2F07%2Fcss-specificity-things-you-should-know%2F&data=02%7C01%7Caharui%40adobe.com%7C36c2eb99bf2e4b45c44d08d5cbf2422f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636639163710627765&sdata=1YPJLfmzcaeFlh%2Bu2FTmbTHgvIvS6n%2BhVQiZhiucJqs%3D&reserved=0>>>>>