I have this property with multiple background images and their respective positions:
#my_div {
background-image:url("..."), url("..."), url("...");
background-position:right bottom, right bottom, right 15px top 17px;
}
The positioning for the third image works fine on FF, IE10, Chrome.. but unfortunately not on Safari Mobile. It renders the right and top thing but not the offsets (15px for right and 17px for top).. I couldn't find any reference on this. How would you deal with this? I'd avoid having to modify the image manually adding transparent borders to make the offset.
Mobile Safari (as well as the Android browser) doesn't support the four-value syntax yet. (see the MDN article on background-position).
One possible workaround would be to extract the background image which should have the offset and put it in a pseudo element that has the corresponding offsets.
#my_div:before{
content: '';
display: block;
position: absolute;
z-index: -1;
height: 50px; /* Height of your image / parent div */
width: 50px; /* Width of your image / parent div */
/* Your offset */
top: 17px;
right: 15px;
background-image: url("...");
background-position: right top;
}
For easier understanding I created a jsFiddle: http://jsfiddle.net/pKWvp/1/
You could also try using the css calc function: http://briantree.se/quick-tip-02-use-css-calc-properly-position-background-images/
It's might be easier/cleaner than using pseudo elements.
Related
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
I have a custom webkit scrollbar like this:
::-webkit-scrollbar{
background: transparent;
width: 10px;
}
::-webkit-scrollbar-thumb{
background: #999 !important;
}
So it renders a grey custom scrollbar instead of the standard one. However, it is stuck to the right side of the page. I know I can change this by adding a margin, padding or border to my body but I am using fullscreen (on backgrounds) images. So when I try this all the images are affected by this too, which I do not want. So I tried to position the scrollbar but this does not work (as it is not an element but a user agent property...
So I'm looking for a way (without using another plugin) to customize the toolbar so that it is offset from the side.
Or, if possible that I can make the scrollbar offset in a div.
Secondly, I'm looking for a way that I can make the "track" of the scrollbar transparet. So only a handle.
Thanks in advance!
If you are still looking for for the answer (or somebody else is, like I was) - here is a definitive article about webkit scrollbars.
Answering Your first question - I'd suggest that you put all your scrollable content in a div with 100% height and 90% width - the 10% left on the right would be your offset. Like that:
.superDiv{
height:100%;
width:90%;
position:fixed;
}
body{ overflow: hidden }
The second question - you're looking for
::-webkit-scrollbar-track-piece {
background:transparent;
}
But as Apple people are pushing for no-scrollbar web browsing, only the properties set by CSS are visible, so you don't have to change the track-piece.
Clever solution I found recently was to put the border on the right hand side of the screen / div that contains scrollbar:
<div class="yourdiv">
border-right: 5px solid #(background_color);
</div>
An easy way to control the position of a custom scrollbar is to set the scrolling element (body?) using definitive positioning. You'll also need to set html to overflow:auto;
To make the thumb transparent, use a RGBa value for declaring the color. In this case I used 0,0,0,0.4 (red,green,blue,alpha). RGBa is not supported in every browser, Chris Coyier has a good table of who supports it here: http://css-tricks.com/rgba-browser-support/
If all you want to show is the thumb than also consider hiding the other elements of the scrollbar: resizer, scrollbar-button, and scrollbar-corner.
html {
overflow: auto;
}
body {
position: absolute;
top: 20px;
left: 20px;
bottom: 5px;
right: 20px;
overflow: scroll;
}
::-webkit-scrollbar{
background: transparent;
width: 10px;
}
::-webkit-scrollbar-thumb{
background: rgba(0,0,0,0.4); /*-- black at 40% opacity --*/
}
::-webkit-resizer,
::-webkit-scrollbar-button,
::-webkit-scrollbar-corner { display: none; }
Check out the working demo at http://jsfiddle.net/Buttonpresser/G53JQ/
I have this HTML:
<div class="demo">hello world</div>
and this CSS:
.demo { width: 100px;
height: 50px; margin-bottom: 50px;
background-color: red; position: relative;
z-index:-1;
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorStr=#40ffffff,EndColorStr=#12ffffff);zoom: 1;}
.demo::after {
width: 95px;
height: 95px;
position: absolute; left: 0; top: 0; border: 5px solid blue; content:"";
background-color: yellow; opacity: .75;}
I wanted the pseudo element to completely cover the origin element (which contains a 50% gradient for IE7,8 - therefore height: 50%, margin-bottom: 50%;)
However in IE9... the ::after element only covers 50%, although I specifically set the height to be 44px. Is this because of the use of filter? Any idea how to override it?
Here is a JSBin of the example.
Thanks for help.
UPDATE
Here is an example of the whole thing:
Example
Notes:
see comments in the background.css file
I can't change the element structure or assign gradient to any other element than .ui-icon
The gradient should cover 50% of the footer. Footer is 44px so gradient stops at 22px
IE7+8 cannot do this (or color stops), so I making .ui-icon height 22px plus filter-gradient
using ::before I add the gradient for all other browsers sitting on top of .ui-icon
Problem 1 = IE9+ renders ::before - I use z-index:-1, so .ui-icon sits behind ::before = OK
Problem 2 = on IE9+ the ::before background is cut off by .ui-icon.
Question: How can I avoid the gradient in ::before being cut off?
Is this because of the use of filter? Any idea how to override it?
Yes, it's because of the filter. Using filter causes an overflow:hidden-esque effect.
You might be aware that :after is rendered inside the element, like this:
<div class="demo">hello world<div:after></div:after></div>
If you add overflow: hidden, then all browsers are equally broken: http://jsbin.com/otilux/3
So, how to fix it? One option is to use ::before to handle drawing the thing that has filter.
See: http://jsbin.com/otilux/4
That looks the same as it did before in Chrome/Firefox, and now also looks the same in IE9.
Due to using ::after instead of :after, I can see you're not trying to support IE8. So, another option would be to use an SVG gradient instead of filter.
Very strange behavior that I haven't seen before.
I have a fixed position div that has a transparent png background image. The z-index is set to -1 so that content can scroll over the fixed image with the scrollbars.
I have it positioned with the bottom and right at 0px, but the image overlaps the scrollbars (on FF and Safari, anyway.)
Here's the link:
http://adamjcas.www59.a2hosting.com/pg/show/id/4
CSS:
#plants /*for the cut paper plants in the background*/
{
background: transparent url(../background_images/plants.png) no-repeat;
bottom:0px;
right:0px;
z-index: -1;
position:fixed;
height:691px;
width:475px;
}
One hack I used was to use
right: 16px;
Which worked fine, as there is always (probably) a right scrollbar. But the bottom scroll is only sometimes there. Is this a simple CSS issue?
That was a strange issue. But I figured out that the scroll bar was not from the browser but instead from the parent div which had overflow: auto.
This is how I fixed that. Change the style for div id="rightpanel" to remove the overflow: auto;.
Then update the #rightcontent styles as follows:
#rightcontent {
left: 445px;
padding-top: 127px;
position: relative;
width: 650px;
}
Hopefully that should fix the issue for all browsers. Besides that I also found the browsers complaining about not finding Cufon.js. You might want to look into that as well.
Just wondering if its possible to cleanup (less code needed to do the same thing) making this div container. Basically it's just a div with a background image however the top & bottom of the div have rounded graphical corners which is why I have a top, middle, and bottom div inside the container div.
<div class="fbox">
<div class="ftop"></div>
<div class="fmid">
Fullbox Text Goes Here
</div>
<div class="fbot"></div>
</div>
Css:
.fbox {
width: 934px;
margin: 0 auto;
opacity: 0.70;
}
.ftop {
width: 934px;
background:url(../images/cb/full.png) no-repeat 0 -34px;
height: 17px;
margin:0
}
.fmid {
width: 894px;
padding-left: 20px;
padding-right: 20px;
background:url(../images/cb/fullmid.png) repeat-y;
min-height: 50px;
margin:0
}
.fbot {
width: 934px;
background:url(../images/cb/full.png) no-repeat 0 -17px;
height: 17px;
margin:0
}
Outcome:
http://img709.imageshack.us/img709/6681/fbox.jpg
http://www.the-art-of-web.com/css/border-radius/
You can use CSS Border Radius with a single div instead of creating the top and bottom. IE won't recognize this but there are some handy work arounds for that as well.
I will commonly use CSS3 PIE which is an htc behavior for IE. It does a bunch of other stuff like linear gradient background colors etc. All you do is supply the border radius css for each browser and the browser will know which one to use.
http://css3pie.com/
.yourbox {
/* PIE Sample */
border: 1px solid #696;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
behavior: url(/PIE.htc);
}
All you really need is the border radius stuff for other browsers though.
You could use the border-radius CSS property. In Firefox, you would use -moz-border-radius and in WebKit you would use -webkit-border-radius. I generally will use all three. This will round the corners of the box without need for all the extra div's.
Of course, users of IE are S.O.L. but sometimes you have to give a little to take a little, right? :)
<div id="box">Blah blah blah.</div>
#box{border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px}
The easiest way would be to use border-radius, but it's not compatible across all browsers. Support is decent. Also, covering all supported browsers requires vendor specific code, which is kind of annoying:
-webkit-border-radius: 4px; /* Vendor code */
-moz-border-radius: 4px; /* Vendor code */
border-radius: 4px; /* CSS 3 Standard */
You can add borders to divs with border-radius applied, and it'll follow the round of the corners as you'd hope.
If you have to use images which is what it sounds like. Create a single image file that has the borders you want and use special css selectors to adjust the background position so your not loading 3 different background images.
.fbox .border {
background: url(bg.png);
}
.border.mid {
background-position: center center;
background-repeat: repeat-y
}
.border.top {
background-position: top left;
background-repeat: no-repeat
}
and so on and so forth
I can't say exactly how you would adjust the bg position because it will depend on the image you use and whether or not your using a constant fixed width. But I highly recommend using only one image and then using an additional selector to just move the bg position.