Radial box-shadow on element - css

Is there a way to create a box-shadow that radiates in a circle from a rectangular div element? So like a regular shadow, except rounded.

Strictly speaking - no. The box-shadow is tied to the shape of the object it's assigned to.
That said - assuming your code allows for nested div elements - you can effectively do this by styling a wrapping div as a circle with a drop-shadow, and the inner content div with the rectangular element.
.wrapper {
/* Equal width and height create a perfect square */
width: 300px;
height: 300px;
/* Adding a border-radius of 1/2 width or height (same value) */
/* turns that square into a circle */
border-radius: 150px;
/* Apply your box-shadow styles, which inherit the round .wrapper shape */
box-shadow: 0px 0px 200px #444444;
}
.content {
/* Apply .content styles as needed; */
/* will display on top of the round shadow */
background-color: yellow;
}
<div class="wrapper">
<div class="content">Content Here</div>
</div>

Related

CSS Transform-Origin Center Overflow Scroll Not Full Width

I've searched and can't find a solution or even ideas on this.
We have a child element inside a scrollable parent. We transform the child to scale larger. When the transform-origin is top left the overflow: scroll works correctly and you can scroll the entire thing. When the transform-origin is center top it scales but the overflow: scroll only starts from the mid-point and there's no way to scroll to the first half of the child.
Here's a simple example showing how it works:
.wrapper {
width: 200px;
height: 200px;
padding: 20px;
border: 1px solid #888;
overflow: auto;
position: relative;
border-radius: 0.001px;
}
.scale {
border-radius: 0.001px;
position: relative;
background-color: #ffff88;
transform: scale(1);
transform-origin: center top;
transition: all 0.5s ease-in-out;
}
.scale--2{
transform-origin: top left;
}
.scale {
transform: scale(4);
}
<div class="wrapper">
<div class="scale">First text - I'm scaling center top</div>
</div>
<div class="wrapper">
<div class="scale scale--2">First text - I'm scaling top left</div>
</div>
Any thoughts or hacks at this point would be awesome.
CSS3 transform has nothing to do with your issue ← you can replicate the same by using a simple left: -100px; on a standard (wider) child element.
(depending on text-direction) If you offset left an element out of a parent boundary - the browser will not paint for you the scrollbars - such element will simply be eaten by the overflow-scroll parent edge.
In the case the child is wider - the browser will paint UI scrollbars
But if you move that wide child to negative left... read again point 1.
the case can be expressed as scrollWidth = childWidth - eatenLeftPortion
Therefore
Browser paints the UI scrollbars
CSS cannot move scrollbars.
The browser will not paint scrollbars if an element is pushed negative top or left (in text-direction ltr; right for rtl)
solution
scale your element using transform-origin: top left; (your second example)
(now the scrollbar is in it's full scrollable state since there's no left-eaten portions)
using JavaScript animate or move scrollLeft by (parentScrollWidth -
parentWidth) / 2
var parent = document.querySelector('.wrapper');
parent.scrollLeft = (parent.scrollWidth - parent.clientWidth) / 2 ;
/*QuickReset*/ *{margin:0;box-sizing:border-box;} html,body{height:100%;font:14px/1.4 sans-serif;}
.wrapper {
position: relative;
overflow: auto;
width: 200px;
height: 140px;
border: 1px solid #888;
}
.scale {
position: relative;
background-color: #ffff88;
transform-origin: left top;
transform: scale(4);
}
<div class="wrapper">
<div class="scale">I'm scaling center top</div>
</div>
For centering a child element within a parent div with parent scrollbars reflecting centered position of child element, I use the following code handled by a range input:
var scaleValue = $('#mySliderRange').val();
// Handles child scaling
child.css({'width':scaleValue+'%','height':scaleValue+'%'});
// Keeps child in vertical middle position
parent.scrollTop((child.height() - parent.height())/2);
// Keeps child in horizontal middle position
parent.scrollLeft((child.width() - parent.width())/2);
The above setup is a substitution to the issue of unreliable parent scrollbar positioning when dealing with CSS3 centered scaling. Hope this helps.

Button out of 3 graphic parts with fluid mid-part

I have an image:
with 3 parts:
, and
I want a button with a repeating part2, so the button text (centered) is variable.
But the button text should range 50% into the other pieces.
Part1 and part3 need a min width I think, unfortunately I have no useful example.
:before and :after didn't work very well (with position:absolute or similar), because the repeat part have to be fluid between the outer parts.
Any ideas? Greetz.
A modern posibility would be using border-image.
But if you want a wider support, do it with backgrounds.
The problem is that a repeating bkg is difficult to size . So, it's best to handle it in a pseudo element
.test {
min-width: 200px;
text-align: center;
line-height: 90px;
display: inline-block;
margin: 20px;
height: 100px;
padding: 0px 20px;
font-size: 30px;
color: white;
background-image: url('//i.stack.imgur.com/mYxcX.png'), url('//i.stack.imgur.com/TlpN0.png');
background-size: auto 100%;
background-repeat: no-repeat;
background-position: left top, right top;
position: relative;
}
.test:after {
content: "";
position: absolute;
background-image: url('//i.stack.imgur.com/GMhMi.png');
background-size: auto 100%;
left: 90px;
right: 100px;
top: 0px;
bottom: 0px;
z-index: -1;
}
<div class="test">TEST</div>
<div class="test">long test</div>
<div class="test">much longer test</div>
And the same, using border image. Using this image
we will get this: (note the trick about height:0px to allow for a single image in all the left and right sides.)
.test {
display: inline-block;
margin: 20px;
height: 0px;
font-size: 30px;
border-width: 50px;
border-image-source: url(http://i.stack.imgur.com/oXiA6.png);
border-image-slice: 50% 49% 50% 50% fill;
border-image-repeat: repeat repeat;
}
<div class="test">TEST</div>
<div class="test">long test</div>
<div class="test">much longer test</div>
UPDATED and totally Changed:
Thanks to #vals comment below which let me had the "idea bulb" above my head, hence the "unless.." part in the comment.
This new solution is much cleaner in CSS and HTML, less code, no need to worry about position:absolute, no need for extra mess, just simply uses "multiple backgrounds" (1) as well as calc()(2) function with min-width too techniques. but first here's the code and comments will explain:
JS Fiddle
.test-class {
/* so that div can expand to contain the text as well as the padding */
width:auto;
/* min width = 173px left image width + 199px right image width */
/* without this it'll collapse */
min-width:372px;
padding:0 20px 0 10px; /* just to give it breathign space on sides */
line-height: 148px;
color: white;
font-size:24px;
/* no color background because the images are PNGs with alpha */
background-color: transparent;
/* setting multiple images having the middle "extendable" one as third background */
background-image: url('//i.stack.imgur.com/mYxcX.png'),
url('//i.stack.imgur.com/TlpN0.png'),
url('//i.stack.imgur.com/GMhMi.png');
/* set no repeat to all, even the extendable otherwise it'll appear behind the
other two images, instead we don't repeat it but control its size later */
background-repeat: no-repeat, no-repeat, no-repeat;
/* position each image to its corresponding position, the 46.5% for the middle
image is because the left-side image has less width than the one on the right */
background-position:left center, right center, 46.5% 50%;
/* finally giving the images on the sides their exact-pixel size, while for the
one on the middle we make use of calc() function, so the width size of the middle
image = full div size (100%) - the width values of the left and right image (173+199) */
background-size: 173px 148px, 199px 148px, calc(100% - 372px) 148px;
display: inline-block;
text-align:center;
}
<div class="test-class">Home</div>
<div class="test-class" style="margin-left:200px;">about company</div>
<div class="test-class">example dummy text for demo only</div>
Alternatively, as I commented, you can use the CSS Sliding Door technique which was so practical and used a lot before CSS border-radius and CSS shadow presented and simplified interfaces. another example perfect CSS sprite sliding doors button
This JS Fiddle 2 shows how to implement the sliding door method for achieving such task, while it looks kind too much wide for this images set, since the right side image has 199px width, it could be used for images with less width values.
And this JS Fiddle 3 is similar to sliding door but with :before and :after but with one issue that it has to have display:block which make it not workign for horizontal alignment but could be fixed with javascript after settign it's display to inline-block.
Also there's another way, using SVG as background image which is better first because it is scale-able especially for non linear images like the blue ink circle used in the great example by #vals .
Second benefit of using SVG is using inline SVG and because SVG is made of groups and element could be targeted with CSS just like targeting other DOM elements.
https://css-tricks.com/using-svg/
----------------------------------------------------------------------------
(1). Resources:
caniuse - Multiple backgrounds
MDN - Using CSS multiple backgrounds
(2). Resources:
caniuse CSS calc()
MDN - calc()
CSS-Tricks - A couple of use cases for calc

Parent has background color, but child is transparent

I was wondering if it was possible to have a parent div have a particular background color, and the child div, be transparent using only CSS.
Let me show you a diagram, which displays what I want:
I can't do it with two sibling Divs, because the divs have rounded corners.
I could do this, using images for the corners, and sibling divs, but I'll like to know if there is a elegant and simple way of doing what I want, with only CSS.
You can do it with siblings and allow rounded corners only for the corners you want. This page has good information about how to do it. It basically consists on using: border-top-left-radius: 10px 5px;.
So,
<div id = "container">
<div></div>
<div></div>
</div>
CSS:
#container div:first-child
{
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
background-color: blue;
}
#container div:last-child
{
border-radius: 10px;
background-color: rgba(0,0,0,0);
/* Same color as the sibling div and a distance of the radius + the separation */
box-shadow: -12px 0 blue;
}
I think that should work. It works. Here's the jsfiddle with some more aesthetic modifications (for resembling more to your image).
EDIT: the right one needed a radius with the border in the original color, so I put together a new jsfiddle and edited the code above.

CSS sprites as background

Is it possible to position a sprite icon as a background of an element?
I have a file, "icons.png" which contains several icons. I want to select one of those as a background of an element.
Usually I would use
.sprite {
background: url('imgs/icons.png') no-repeat 0 -21px;
width: 17px;
height: 10px;
} and use this class for a button, etc...
The problem is I have a text input and I want to modify it's placeholder
.First I did this, which works perfectly if the file I use is the icon itself
:-webkit-input-placeholder{ background: url('singleIcon.jpg') center right no-repeat; }
But now I want to use a file which contains more icons.
Is it possible to use something like this ?
:-webkit-input-placeholder{ background: url('imgs/icons.jpg') center right no-repeat; }
The problem in the last line of code is that it will select all my image (which of course contains all my icons I want to use on the website), I want to select only a part of that image ( the icon I want to use )
Actually, the sprites are used only as background (or you've to set up some kind of complicated cropping).
What you have to do is to set the size of the element to the same sprite's part that you have to show, and the position of the background equal to the x and y coordinates of the icon in the sprite, starting from the top left.
An example taken from this nice article:
"Item 2" is 116x48, begins at 12px (x coord) and 70px (y coord).
So your element's CSS should be:
.element {
width:116px;
height:48px;
background:url(sprites.png) -12px -70px no-repeat;
}
But, what if your element is taller/wider than the above dimensions? Then, you've to isolate that icon with enough transparent/white space so that the other icons won't show up.
If you look up at Facebook sprites, you'll notice that some of them are very long, some others groupped, some others isolated. You've to adapt the sprite for each situation.
Edit: ok, i got your actual needing.
It's not easy with inputs because you can't use pseudo-elements on it. Here comes a workaround.
Demo
First of all, wrap the input inside a div:
<div class="inputWrapper">
<input type="text" placeholder="placeholder text">
</div>
Then add some CSS:
div.inputWrapper {
position:relative; /* that's important */
float:left; /* or display:inline-block; */
}
div.inputWrapper:after {
background:#000 url(sprites.png) 0 -2px no-repeat; /* adjust background position */
content:" "; /* whitespace needed for the pseudo-element to be displayed */
position:absolute;
top:1px; right:2px; /* some room for the borders */
width:16px; /* icon width */
height:18px; /* icon height */
}​
div.inputWrapper input {
padding-right:16px; /* so the text won't go behind the icon */
}
I know it's complicated, but the alternative is to create another http-request ... the choice is yours.
Here's a quick n dirty sample. Basically, just set the background-position attribute of the element's CSS.
<!DOCTYPE html>
<html>
<head>
<script>
var curFrame = 0;
var numFrames = 10;
var animTimer;
function advanceFrame()
{
var hero;
curFrame++;
if (curFrame >= numFrames)
curFrame = 0;
hero = document.getElementById("hero");
var posX = curFrame * -64;
curPos = posX+"px 0";
hero.style.backgroundPosition = curPos; //offsets[curFrame];
}
function myInit()
{
animTimer = setInterval(advanceFrame, 200, false);
}
</script>
<style>
#hero
{ /* image is 638x64 pixels - it has 10 sprites in it, horizontally offset */
background-image: url(http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-53-00-metablogapi/5545.image_5F00_13D4E783.png);
display: block;
width: 64px;
height: 64px;
}
</style>
</head>
<body onload='myInit();'>
<div id='hero'></div>
</body>
</html>
It's possible, but some things to note:
The placeholder pseudo-class works inconsistently across browsers, e.g. Firefox on the entire input element, Chrome only on line-height.
The placeholder pseudo-class by default adds a opacity layer on top of the original input box.
Background-images on the placeholder pseudo-class need to be "repeated" if the cropped icon is not the first icon on the sprite image.
The default box-sizing for form elements may be different for the rest of the elements, so borders/paddings may change the calculation of the size of your background-image.
I think it's best to keep your sprite a long vertical list of icons, make your placeholder style opaque, use the border-box box model. Also, the icon height dimension should be exactly the height of the available background space. It is also a good idea to keep the background-* properties separate so what you are doing with the sprites becomes clearer and easier to read.
Assuming you have a list of 4 50x50 icons - i.e. a 50x200 image, you can do the following:
input {
box-sizing: border-box; /* keep box-sizing consistent */
width: 200px;
height: 52px; /* compensate 2px for border */
border: 1px solid black;
background-color: blue;
background-image: url('icons.png');
background-size: 50px 200px;
background-position: right 20px top 0; /* assuming you want the icon to "float" right */
background-repeat: repeat-y;
}
::-webkit-input-placeholder {
background-color: yellow;
background-image: url('icons.png');
background-size: 50px 200px;
background-position: right 20px top 50px; /* use second icon in the sprite */
background-repeat: repeat-y;
opacity: 1; /* don't show the underlying input style */
}
Also remember to apply the styles to ::-moz-placeholder and :-ms-input-placeholder
I might be stating the obvious, but have you tried:
:-webkit-input-placeholder{ background: url('imgs/icons.jpg') no-repeat 0 -21px; width: 17px; height: 10px;
}

CSS Dashed and Angled borders

I've found several articles on how to angle borders, but what I'm trying to do is a little different.
I have an element with dashed borders like so:
.box { border: 1px dashed #fff; }
However, I am trying to simultaneously have the corners of the .box element and its dashed border be at a 45 degree angle.
Is this possible?
You could get some pretty close-to-45 degree angles by tweaking the bezier of border-radius:
http://www.css3.info/preview/rounded-border/
Is there a reason why you wouldn't want to do this with 2 background elements?
.box {
/* this background image will stick to the top of the box */
background: url(/* you would put a 10px high image that is the width of said box */) no-repeat left top;
display: block;
padding: 10px 0 0; /* this padding element needs to match the background height */
}
.box .inner {
/* this will stick the background image to the bottom, and grow with the natural height of the box */
background: url(/* you'd put a looong background image, that could stretch vertically */) no-repeat left bottom;
display: block;
padding: 0 10px 10px;
}
Your markup would look like this:
<div class="box">
<div class="inner">
...Content goes here...
</div>
</div>
I can understand if you want to do it with just the border style, but I don't know of a way to do right angles and make it work in IE, to be honsest.

Resources