Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Implement inset box-shadow #3

Open
lojjic opened this issue May 21, 2010 · 38 comments
Open

Feature: Implement inset box-shadow #3

lojjic opened this issue May 21, 2010 · 38 comments

Comments

@lojjic
Copy link
Owner

@lojjic lojjic commented May 21, 2010

Implement rendering of the 'inset' keyword in box-shadow.

Currently the code will allow this keyword when parsing but will not render it.

There is some partly-implemented code in BoxShadowRenderer.js, which no longer functions but at one point had a fairly good implementation for when the box is perfectly square (no rounded corners). Making this work with rounded corners will require a way to mask one shape with another, so we can create a border which gets blurred and then clipped to the shape of the padding-box. The Compositor filter may be an option.

@jrmgx
Copy link

@jrmgx jrmgx commented Jan 11, 2011

Is it possible to activate the inset keyword rendering and specify in the doc that it will work well only into squared element ?
I think that's a better way than preventing any rendering.

What should I change for my personnal use to get this working ?
Thanks

@lojjic
Copy link
Owner Author

@lojjic lojjic commented Jan 11, 2011

The old code has been totally removed, because it didn't render accurately even in the square corners case, and used the blur filter which is horrible for performance. This needs to be rethought from the ground up.

@matthew-dean
Copy link

@matthew-dean matthew-dean commented Feb 15, 2011

I don't understand why this is so difficult. Say you want an element with a 5px inset shadow. Create a VML element 5px inside the target element, and give the new VML element a 5px outset shadow, only reversing the alpha / color darkness values. Done.

Or some other such method. Is it really such a challenge though?

@thirdeyeblind82
Copy link

@thirdeyeblind82 thirdeyeblind82 commented Apr 20, 2011

I've the same problem! I can't see my inset shadow in a rounded div! :(
Hope that will be a solution early!

@excitedleigh
Copy link

@excitedleigh excitedleigh commented May 30, 2011

@MatthewDL Does VML allow for outset shadows that have, say, gradients or images, and so on?

@matthew-dean
Copy link

@matthew-dean matthew-dean commented Sep 16, 2011

I dunno, maybe I have to learn some VML and throw something into this project. :-)

@tmikaeld
Copy link

@tmikaeld tmikaeld commented Nov 6, 2011

matthewdl: Please do if you have the time, text-shadow is very needed.

EDIT: Looking at CUFON, we might be able to use their method of creating text-shadow.

@jimmyheaddon
Copy link

@jimmyheaddon jimmyheaddon commented Dec 9, 2011

I'm really looking for an implementation of inset box-shadows in CSS3 PIE please! :)

@barryvdh
Copy link

@barryvdh barryvdh commented Jan 19, 2012

Same for me, is there any progress on this issue? This would save me a lot of time/work for nicer css buttons in CSS3 (Like from http://www.cssbuttongenerator.com/ which is much nicer with the inset box radius)

@ayoung
Copy link

@ayoung ayoung commented Mar 14, 2012

poke.

@BMCouto
Copy link

@BMCouto BMCouto commented Mar 19, 2012

Important issue here. Any plans to implement this feature?

@lojjic
Copy link
Owner Author

@lojjic lojjic commented Mar 19, 2012

Of course I hope to be able to implement this. Unfortunately I've made several attempts and have not yet found a method that works in any but the simplest cases. The issue is the limited nature of VML gradients and the lack of a way to clip shapes to non-rectangles in IE. I will of course continue to try, but be aware that this may prove to be impossible.

@BMCouto
Copy link

@BMCouto BMCouto commented Mar 19, 2012

That's too bad. Hope you can keep trying and find a way to implement it as soon as possible.

@matthew-dean
Copy link

@matthew-dean matthew-dean commented Mar 19, 2012

What about something other than VML's gradients? This might seem unconventional, but what about exploring something like VML extrusion? If you can extrude away from the visible object (into the bg), and if the extrusion could fade with a perspective distance, then maybe it could APPEAR to be an inset shadow as an optical illusion.

This is just a guess from poking around the VML documentation this morning. Not sure if it works that way in reality at all, but just tossing out ideas.

@lojjic
Copy link
Owner Author

@lojjic lojjic commented Mar 19, 2012

@MatthewDL I'm open to anything that works! Extrusion is an interesting idea, I'm not sure if you can do the sort of fading you describe but let me know if you find otherwise.

@matthew-dean
Copy link

@matthew-dean matthew-dean commented Mar 21, 2012

Another idea: what about creating four elements, one on each side of the box, and creating a box shadow for each of them? Is that possible?

@q13
Copy link

@q13 q13 commented Apr 1, 2012

wait in hope

@mcmwhfy
Copy link

@mcmwhfy mcmwhfy commented Jul 28, 2012

You can do it Jason, you did things much heavier than that :)

@ghost
Copy link

@ghost ghost commented Oct 10, 2012

are there any workarounds available? I'd really like to have this...

@Axle-Ryde
Copy link

@Axle-Ryde Axle-Ryde commented Oct 10, 2012

I've used border-image png with transparency for inset shadows where I need them in my projects, This is of-course not at all flexible if any properties change - border-radius, changing shadow properties, and you lose your CSS borders to the border-image. But it's a workaround to acheive a similar effect and at least there is still no extra markup.

If you're IE8+ then you could pseudo-element (:before + content) and style that with the border-image in order to save your regular element for normal borders. Just a few ideas - but all hacky workarounds . . .

@ghost
Copy link

@ghost ghost commented Oct 11, 2012

Ok thanks, I'll give that a try!

@mturley
Copy link

@mturley mturley commented Dec 19, 2012

Has anyone been working on this lately, or had any success with workarounds?

@lojjic
Copy link
Owner Author

@lojjic lojjic commented Dec 19, 2012

@mturley No.

@MinionMan
Copy link

@MinionMan MinionMan commented Jan 30, 2013

Thought:

Can you just do multiple background-gradients on the element in question? Render a gradient from [starting color] to [transparent] from each side depending on the shadow values. You should be able to round the corners with the background gradients, at least as far as I can tell with how PIE operates now.

Something using:
progid:DXImageTransform.Microsoft.gradient (GradientType=1, startColorstr=#ff000000, endColorstr=#0);

If this sounds really dumb, sorry I'm not terribly familiar with VML. But I do love PIE!

@lojjic
Copy link
Owner Author

@lojjic lojjic commented Jan 30, 2013

@MinionMan That's a good thought, and I've tried something along those lines. The difficulty comes when the gradient itself has to follow the contours of rounded corners, and is offset in some direction like most inset shadows in the real world are.

@MinionMan
Copy link

@MinionMan MinionMan commented Jan 30, 2013

Hmmm square peg, round hole. I see the issue there...
What about (as terrible as it seems) offset elements of descending opacity with a colored border and transparent background? Not sure how the stacking works (elements cover text node?)

Or a single rounded element with a reversed outer-shadow (transparent inner to target color outer). The size and border-radius would have to be carefully calculated to match the parent element.

@mturley
Copy link

@mturley mturley commented Jan 30, 2013

If you get this working and need help debugging, I'd be happy to help.
I've been needing this feature of PIE for a while now.

Hmmm square peg, round hole. I see the issue there...
What about (as terrible as it seems) offset elements of descending opacity
with a colored border and transparent background? Not sure how the stacking
works (elements cover text node?)

Or a single rounded element with a reversed outer-shadow (transparent inner
to target color outer). The size and border-radius would have to be
carefully calculated to match the parent element.


Reply to this email directly or view it on
GitHubhttps://github.com//issues/3#issuecomment-12900299.

@MinionMan
Copy link

@MinionMan MinionMan commented Jan 30, 2013

@lojjic, you mention in the radial gradients:
"VML's "radial" gradients are actually square (they extend evenly from the edges of the shape's rectangle to the center). "
Could this gradient be used to create the inset shadow? If it's following the curvature of the element, and you can put a stop in, and use transparency.

@lojjic
Copy link
Owner Author

@lojjic lojjic commented Jan 30, 2013

Yeah radial gradients (actually "gradienttitle" gradients work better) are fine for when the shadow has no offset, but as soon as you have an offset (like most real-world inset shadows) then they don't work because you want them starting from somewhere different than the edges of the shape. VML gradients can't do that unfortunately.

It's actually pretty easy to handle inset shadows for the following cases:

  • shadows with no offset, even with border-radius
  • shadows with offset, if there is no border-radius

It's the combination of offset and border-radius that has always been the problem, and I've opted thus far to ship nothing rather than shipping an implementation that handles only those two limited cases. I could possibly be convinced to change my mind on that though.

@MinionMan
Copy link

@MinionMan MinionMan commented Jan 31, 2013

Quite the conundrum... I'll keep thinking on it. While it would be neat to have either option, the combination of both is definitely the most common call.

Perhaps a stroke on the the outside of a sub-element that contains the gradient that is offset inside the element creating the rounded corners? So we end up with a "border" the width of the offset, to fill the empty space?

@golbosoft182
Copy link

@golbosoft182 golbosoft182 commented Jul 19, 2013

best solution don't used old browser :) 👯

@s1h4d0w
Copy link

@s1h4d0w s1h4d0w commented Oct 10, 2013

I'd just like to mention that I too would love to see this implemented. I work for a company that uses CSS3PIE a lot and being able to use inset shadows would greatly improve the experience of visitors who do not use the most up to date browsers.

Buttons like these would be a breeze to make:
2013-10-10 11_54_01-button test

@henrix343
Copy link

@henrix343 henrix343 commented Oct 10, 2015

@lojjic I have a problem with box-shadow and IE - the only thing I want is to set ->inset<- in box-shadow and add some blur. Will pie support this ? If not, do you plan to add this behavior in a future version or update it? Thanks for you hard work, I'm using pie a lot.

laughinghan added a commit to mathquill/mathquill that referenced this issue Jun 11, 2016
Before, there was no visual indication whether the cursor is "under" a
diacritic (i.e., inside a diacritic block): https://git.io/votJ1

After, the diacritic block gets a box-shadow that makes it look inset
when the cursor is inside, just like text blocks: https://git.io/votJy

Note: IE8 doesn't support box-shadow, and even IE's DropShadow filter
doesn't support inset shadows [1], but the CSS3 PIE folks seem to think
it's possible with VML [2].

[1]: http://www.useragentman.com/blog/2011/08/24/how-to-simulate-css3-box-shadow-in-ie7-8-without-javascript/
[2]: > It's actually pretty easy to handle inset shadows for [...]
     > shadows with offset, if there's no border-radius
     lojjic/PIE#3 (comment)
@laughinghan
Copy link

@laughinghan laughinghan commented Jun 11, 2016

@lojjic @MinionMan:

First of all, I'm sure you get this a lot because it's so well-deserved, but this library is an absolute treasure, thank you so much for writing it!

It's actually pretty easy to handle inset shadows for the following cases:

  • shadows with no offset, even with border-radius
  • shadows with offset, if there is no border-radius

Would you be willing whip up a quick-and-dirty demo (like on http://jsbin.com or something) of the technique(s) for inset shadows with offset or border-radius?

No need for full generality, just a starting point would be immensely helpful!

@lojjic
Copy link
Owner Author

@lojjic lojjic commented Jun 12, 2016

@laughinghan Thanks for the compliment, unfortunately I'm not going to be able to put any code together to demonstrate, as I don't even have an old-IE virtual machine set up nowadays. As you can probably guess from that, development of PIE is pretty much dead as far as I am concerned.

I can try to describe the approaches for you though, working from memory...

  • shadows with no offset, even with border-radius

This should be as simple as copying most of what's in BoxShadowOutsetRenderer, but don't outset the shape at all and reverse the color/opacity attributes.

  • shadows with offset, if there is no border-radius

My memory is a little fuzzier on this one but I think it would start similar to the above, but then adjust the shape's outset, position, and focusposition/focussize to get the gradient in the right location, and then clip the whole thing (via CSS clip:rect()) to the main element's bounding rect.

I know that's probably really vague, but maybe it's a start?

@laughinghan
Copy link

@laughinghan laughinghan commented Jun 13, 2016

@lojjic: It's definitely a better start than I had before! Thank you so much, will attempt and report back.

@laughinghan
Copy link

@laughinghan laughinghan commented Jun 15, 2016

I did it! Sort of:
Sauce Labs screenshot

http://jsbin.com/rezosa/edit?js,output

It was...shockingly hard. The top Google results for "vml examples" didn't even work, they VML didn't render at all, it's just blank, in IE8 on Sauce Labs (Windows XP or 7):

But CSS3PIE still worked (well, kind of...I mean it's broken, but the box-shadow worked, so), and Raphael.js still worked (it was centered at (0,0) instead of being positioned properly, but other than that it rendered great and wasn't blank at all), so...something about VML has to work in IE8 on Sauce Labs, it's not missing the DLL or whatever. I tried to copy snippets of CSS3PIE by tracing through BoxShadowOutsetRenderer and VmlShape, but it was just too complicated...

Finally I stumbled on this StackOverflow question, with a nice short JS snippet that draws one single circle with VML, which actually worked! Tweaking that around, I found that the order in which you do .style.behavior = 'url(#default#VML)' matters a lot.

From there it was mostly MSDN VML docs (although as one of the comments note, they were wrong on at least one point, which required the 200x200 blue square div to debug), to the point where I got a cool background gradient working, but to actually get an inset box-shadow like I wanted required getting o:opacity2 working, and literally everything else was working until o:opacity2. Finally, thanks to your amazing work, I somehow stumbled across https://github.com/lojjic/PIE/blob/2.0beta1/sources/VmlShape.js#L28

The final piece of the puzzle! Opacity2! Boom! Inset shadow!

@miracleshack
Copy link

@miracleshack miracleshack commented Sep 21, 2018

Hello! Here is an example of an inset Microsoft Shadow working only in Internet Explorer 5.5 through 8.
No javascript is required, but this does use Microsoft's ActiveX CSS.

Styling Explanations:

#box {
/* Make sure to set these divs to min-width so you can push the outside "Microsoft Shadow" out of the screen to the left, right, bottom, and top, because the shadow adds pixels to the 100% width whether you set it to width:100% or not, but if you set it to 100% width, you won't be able to make the margin push the outside shadow out. */

/* For some reason, the above rule is not the case for height. I'm not sure why for Internet Explorer. */

/* I discoverd the shadow won't even appear unless there is a boder of the same div. That's no big deal, just push the border out of the screen too, along with the bleeding outside Mirosoft Shadow". */

/* For the child, (child id is called "box")... you can only push out the content to the bottom and right with margin edits, because of the natural left to right, top to bottom HTML layout. */
}

.box-parent-fix {
/* This appears to be a hack as far as I know, the bleeding Microsoft Shadow (not the inset part, the outside part is what I'm talking about) will only be pushed out if it has a parent with the follow CSS: */
}

.box-parent {
/* For the child, (child id is called "box")... you can only push out the content to the bottom and right with margin edits, because of the natural left to right, top to bottom HTML layout. */
}

body {
/* The overflow-x and overflow-y hides the pushed out bleeding non-inset Microsoft Shadow when it bleeds off the screen. Please excuse my ugly sentence, haha. */
}

Simply copy and paste the code below into a notepad and save as a .html file. Test in Internet Explorer.
PLEASE, this code will ONLY SHOW IN INTERNET EXPLORER 5.5 THROUGH 8!

<body style="position: relative; height: 100%; min-width:100%; overflow-y: hidden; overflow-x: hidden;">
    <div class="box-parent-fix" style="margin-top:-49px; margin-left:-44px; height:100%; min-width:100%; background-color: white; position: relative;">
        <div class="box-parent" style="position: relative; min-width: 100%; height: 100%;">
            <div id="box" style="filter: progid:DXImageTransform.Microsoft.Shadow(Color=#aaaaaa, Strength=33, Direction=0), progid:DXImageTransform.Microsoft.Shadow(Color=#aaaaaa, Strength=33, Direction=90), progid:DXImageTransform.Microsoft.Shadow(Color=#aaaaaa, Strength=33, Direction=180), progid:DXImageTransform.Microsoft.Shadow(Color=#aaaaaa, Strength=33, Direction=270); margin-bottom: -39px; margin-right: 130px;  zoom: 1; border: solid 1px black; position: relative; height:100%; min-width: 100%;">

            </div>
        </div>
    </div>
</body>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet