> On Jun 7, 2018, at 10:44 PM, Alex Harui <[email protected]> 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" <[email protected]
> <mailto:[email protected]>> 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 <[email protected]> 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" <[email protected]
>> <mailto:[email protected]> <mailto:[email protected]
>> <mailto:[email protected]>>> 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 <[email protected]
>>> <mailto:[email protected]>> 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 <[email protected]
>>>> <mailto:[email protected]> <mailto:[email protected]
>>>> <mailto:[email protected]>> <mailto:[email protected]
>>>> <mailto:[email protected]><mailto:[email protected]
>>>> <mailto:[email protected]>>>> 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" <[email protected]
>>>> <mailto:[email protected]> <mailto:[email protected]
>>>> <mailto:[email protected]>> <mailto:[email protected]
>>>> <mailto:[email protected]> <mailto:[email protected]
>>>> <mailto:[email protected]>>>> 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 <[email protected]
>>>>> <mailto:[email protected]> <mailto:[email protected]
>>>>> <mailto:[email protected]>> <mailto:[email protected]
>>>>> <mailto:[email protected]> <mailto:[email protected]
>>>>> <mailto:[email protected]>>>> 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 <[email protected]
>>>>>> <mailto:[email protected]> <mailto:[email protected]
>>>>>> <mailto:[email protected]>> <mailto:[email protected]
>>>>>> <mailto:[email protected]><mailto:[email protected]
>>>>>> <mailto:[email protected]>>> <mailto:[email protected]
>>>>>> <mailto:[email protected]> <mailto:[email protected]
>>>>>> <mailto:[email protected]>><mailto:[email protected]
>>>>>> <mailto:[email protected]><mailto:[email protected]
>>>>>> <mailto:[email protected]>>>>> 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" <[email protected]
>>>>>> <mailto:[email protected]> <mailto:[email protected]
>>>>>> <mailto:[email protected]>> <mailto:[email protected]
>>>>>> <mailto:[email protected]> <mailto:[email protected]
>>>>>> <mailto:[email protected]>>> <mailto:[email protected]
>>>>>> <mailto:[email protected]> <mailto:[email protected]
>>>>>> <mailto:[email protected]>> <mailto:[email protected]
>>>>>> <mailto:[email protected]> <mailto:[email protected]
>>>>>> <mailto:[email protected]>>>>> wrote:
>>>>>>
>>>>>>
>>>>>>> On Jun 6, 2018, at 11:05 PM, Harbs <[email protected]
>>>>>>> <mailto:[email protected]> <mailto:[email protected]
>>>>>>> <mailto:[email protected]>> <mailto:[email protected]
>>>>>>> <mailto:[email protected]><mailto:[email protected]
>>>>>>> <mailto:[email protected]>>> <mailto:[email protected]
>>>>>>> <mailto:[email protected]> <mailto:[email protected]
>>>>>>> <mailto:[email protected]>><mailto:[email protected]
>>>>>>> <mailto:[email protected]><mailto:[email protected]
>>>>>>> <mailto:[email protected]>>>>> 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>>>>>