I'm trying to make a button using three background images so that we can pull in translations for the the text of the button and expand nicely. We'll probably add a base style for IE8 but our designer wants us to use this style and we couldn't recreate it nicely with pure CSS3.
Here are the images:
Here's the HTML (just a simple button, but thought I should put it anyway:
<button class="back clickable" aria-label="Back" onclick="javascript:history.back();">Back</button>
I've already tried a couple of things; I'll paste the CSS of both attempts.
Attempt 1: Using Pseudo-selectors
http://jsfiddle.net/c2B6X/
.back {
background: url("images/back-middle.png") 14px 0 repeat-x;
color: $white;
height: 28px;
padding: 5px;
&:before {
background: url("images/back-front.png") 0 0 no-repeat;
width: 14px;
}
&:after {
background: url("images/back-end.png") 100% 0 no-repeat;
width: 8px;
}
}
Attempt 2: Three background-images
http://jsfiddle.net/nPUQN/
.back {
background: none;
background-image: url("images/back-middle.png"), url("images/back-end.png"), url("images/back-front.png");
background-position: 14px 0, 100% 0, 0 0;
background-repeat: repeat-x, no-repeat, no-repeat;
border-right: 8px transparent;
border-left: 14px transparent;
color: $white;
height: 28px;
padding: 5px;
}
If it looks like atypical CSS that's because we're using SASS.
Is there something obvious I'm missing or doing wrong? Any advice on how to make this work would be greatly appreciated.
EDIT
Since I got so many answers that "work", I'll mark correct the answer that works best in Chrome, FF and IE9.
EDIT 2
I've tried all answers and none work in IE9. We have to support IE9 (and IE8, but I won't even go there for now). I'm going to start a bounty. Anyone who can supply an answer that works for IE9, Firefox and Chrome gets it.
Pseudo-content requires content, so you'll first need to specify that:
.selector::before {
content: ' ';
}
Then to define any layout such as width and height you'll need to display the pseudo elements as a block or inline-block. Block layout will force each pseudo element to wrap and inline-block will sit on the line so you'll either have to use floats or absolute positioning.
.selector {
position: relative;
height: 28px;
/* allow for the pseudo-elements which do not have layout due to absolute positioning */
margin: 0 15px;
}
.selector::before,
.selector::after {
content: ' ';
position: absolute;
top: 0;
width: 15px;
height: 28px;
}
.selector::before {
left: -15px;
}
.selector::after {
right: -15px;
}
Demo here for you: http://codepen.io/anon/pen/yaJGI
You'll need to add content for :before and :after to show. After that, you can position them absolutely and by giving them right: 100% and left: 100% respectively, you can position them in front of and behind the button.
button {
background:transparent;
border: none;
padding: 0;
margin: 0;
line-height: 1;
font-size: 12px;
cursor: pointer;
margin-left: 14px; /* width of :before */
}
.back {
background: url("http://i.stack.imgur.com/DaQcG.png") 14px 0 repeat-x;
color: white;
height: 28px;
padding: 5px;
position: relative;
}
.back:before {
position: absolute;
content: "";
height: 28px;
top: 0;
right: 100%;
background: url("http://i.stack.imgur.com/6m2HC.png") 0 0 no-repeat;
width: 14px;
}
.back:after {
position: absolute;
content: "";
height: 28px;
top: 0;
left: 100%;
background: url("http://i.stack.imgur.com/2WA5B.png") 100% 0 no-repeat;
width: 8px;
}
The definitions of before and after are slightly the same, so you could write it down more compactly, but you need to re-sass it anyway. ;)
http://jsfiddle.net/c2B6X/
Tip: Note that downloading three images is less efficient. You can create one image that contains the start and end at the top, and the middle part at the bottom. By positioning the background, you can show the right part inside the elements. This technique is called sprites and it decreases the number of requests to make.
I came up with a little something that you can take a look at. You can modify it to best fit your needs.
http://jsfiddle.net/Xy7Hv/1/
HTML:
<button class="back">Back</button>
CSS:
.back {
border: none;
height: 28px;
padding-right: 8px;
padding-left: 14px;
background-image: url("http://i.stack.imgur.com/DaQcG.png"),
url("http://i.stack.imgur.com/6m2HC.png"),
url("http://i.stack.imgur.com/2WA5B.png");
background-position: 14px 0px, left, right;
background-size: 30px 100%, 14px 28px, 8px 28px;
background-repeat: no-repeat,no-repeat,no-repeat;
}
("background-size: 30px" is the width of the button, so if all your buttons are the same size it shouldn't be a problem)
with your multiple background version, you could add gradient or white image to build your button bg , keeping some space with padding.
http://jsfiddle.net/nPUQN/1/
.back {
background:
url("http://i.stack.imgur.com/2WA5B.png") 100% 0 no-repeat ,
url("http://i.stack.imgur.com/6m2HC.png") 0 0 no-repeat,
-webkit-linear-gradient(0deg, white 0, white 14px , transparent 14px ,transparent) 0 0 no-repeat ,
-webkit-linear-gradient(180deg, white 0, white 8px , transparent 8px ,transparent) 0 0 no-repeat ,
url("http://i.stack.imgur.com/DaQcG.png") 14px 0 repeat
;
color: $white;
height: 28px;
padding: 5px 8px 5px 14px;
}
prefixed for chrome, add other prefix needed or use a prefix js :)
I add this answer because i like to keep the other as it is.
This one is to be tested in IE8/9 with pseudo and position:
http://codepen.io/gcyrillus/full/lBpaI or to edit :
http://codepen.io/gcyrillus/pen/lBpaI
.back {
background:
url("http://i.stack.imgur.com/DaQcG.png") 14px 0 repeat
;
color: white;
height: 28px;
padding: 5px;
position:relative;
overflow:visible;
}
.back:before {
content:url(http://i.stack.imgur.com/6m2HC.png);
top:0;
left:-14px;
position:absolute;
}
.back:after {
content:url(http://i.stack.imgur.com/2WA5B.png);
position:absolute;
right:-8px;
top:0;
}
I used this code today. It's similar to your 2nd example, but uses the background shortcut property and a mixture of position strings.
background: url("../images/img01.png") 0px 0px no-repeat, url("../images/img02.png") 53px 0px repeat-x, url("../images/img03.png") right top no-repeat;
img01 = left image (53px wide)
img02 = fill image
img03 = right image
Related
I've been working on my first website and run out with some questions I couldn't find any solution online. Hopefully someone could guide me what are the keywords I should lookup.
1) How can I define the length of the border of the output (without wrapping it with div)? I would like to set a constant width of the output value (that would be empty if there is no value), but I can't seem to find how to do so. In CSS, border-bottom-width actually set the height.
output {
border-bottom: 1px solid #000000;
margin: 3em 0% 3em 0%;
color: aquamarine;
background: transparent;
text-align: center;
}
2) How can I set to a floating button a gradient in the back background and an image in the front? For some reason, it seems that I can use only one of them.
<button onclick="calc(this)" class="calc" src="/img/calculator.svg"></button>
.
.calc {
width: 4em;
height: 4em;
padding: 0.3em;
position: fixed;
bottom: 3em;
right: 3em;
background-image: radial-gradient(#aac0e8, #b9cde5, #dce6f2) url('/img/calculator.svg'); //the picture isn't shown
border-radius: 50px;
box-shadow: 2px 2px 3px #999;
outline: none;
border: #17375e;
}
I have tried to code my page as follows:
<div class="Conttent-Group">
<div class="Conttent-Group-Body">
<div class="Conttent-Body-Right">
<div class="Conttent-Body-Left">
<h1>News operations</h1>
</div>
</div>
</div>
</div>
and although the following css:
* {
background-color: #006;
}
.Conttent-Group {
margin-top: 5px;
height: 300px;
width: 788px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
background: white;
}
.Conttent-Group-Body {
margin-left: 4px;
margin-top: 5px;
width: 386px;
height: 30px;
float: left;
background: url (Image / module-bg-bodynew.jpg) repeat-x top center;
}
.Conttent-Body-Right {
height: 30px;
background: url (image / module-bg-rightnew.jpg) top right no-repeat;
}
.Conttent-Body-Left {
background: url (image / module-bg-leftnew.jpg) top left no-repeat;
height: 30px;
}
.Conttent-Body-Left div {
background: #fff;
border:> 1px solid # C6B389;
border-top: none;
padding: 0;
margin-top: 7 pixels;
height: 243px;
}
.Conttent-Body-Left h1 {
display: block;
margin: 0;
padding: 20px 0 0 7 pixels;
text-align: left;
font-weight: bold;
color: # E1F1FE;
font-size: 13px;
}
But when running my code I only see the background-color
* { background-color: # 006; }
And not the background-images I have set. How can I fix this and show the images?
Currently you are using * {background-color: #006}. The * selector targets every element, thats on your side, thats why every background color is the same.
When you are using an image as background, first of all look up its file path:
/index.html
/style.css
/images/
/images/picture1.jpg
/images/picture2.jpg
If you want to target an picture, you always have to choose the file path regarding to your css file. So in this case for example your path is images/picture1.jpg. Although be aware of uppercase and lowercase letters inside your file structure (like Images or images) or not wanted spaces.
Using this you can set your background-image, and although add multiple variables, like:
background-image: url(images/picture1.jpg); /* no spaces inside your url */
background-repeat: no-repeat; /* or "repeat-x", "repeat-y" */
background-size: cover; /* for a fullscreen background */
background-color: #fff /* for everything your background images does not cover */
/* or combine them all into one */
background: url(images/picture1.jpg) no-repeat top center;
Furthermore you have got quite a lot of errors inside your code. Maybe you should consider refreshing the basics, using online helpers like codeacademy or something else you will find.
I've recently encountered some problems with CSS Sprites.
I want them to switch pictures every function call, function itself is OK since it only removes and adds css class.
I have following CSS:
#slider_arrow {
padding-left: 200px;
position: relative;
top: -1px;
}
.red_arrow_sprite {
background: url(/Images/onex/arrows.png) 0 0 no-repeat;
width: 25px;
height: 12px;
}
.yellow_arrow_sprite {
width: 25px;
height: 12px;
background: url(/Images/onex/arrows.png) -26px 0 no-repeat;
}
.black_arrow_sprite {
width: 25px;
height: 12px;
background: url(/Images/onex/arrows.png) -51px 0 no-repeat;
}
Slider_arrow is:
<span id="slider_arrow" class="red_arrow_sprite"></span>
the element in which I change class.
And the problem is that my Sprite file has 75px width and 25px height.
(3x 25px/25px)
With the CSS I Presented I get the result where I see all 3 pictures at the time with red_arrow_sprite class, 2 pictures with yellow_arrow_class and 1 picture which is desired with black_arrow_class.
What have I done wrong with CSS?
Thanks in advance.
http://jsfiddle.net/9b57pb50/
Check out this solution
I've removed padding and add some display properties.
I am trying to create a box that has a 'highlight' down the sides of it, and at the top.
The CSS for the box was pretty simple, however, now that I introduced this 'highlight' to the design, it has added another level of complexity to the CSS...
I have tried a lot of things, not sure if they will help but here is my most recent:
/* Define the Main Navigation Drop Downs */
#mn_navigation .dd {position:relative;width:226px;padding:29px 0 0;background:transparent url("//beta.example.co.uk/_images/_global/dd_handle.png") no-repeat;z-index:1000;}
#mn_navigation .dd nav {padding:30px 0;background:#3E5032 url("//beta.example.co.uk/_images/_global/dd_bg.png");border-radius:3px;}
#mn_navigation .dd nav a {font-family:Arial, Helvetica, sans-serif;font-size:12px;color:#fff !important;height:25px;line-height:25px;}
Please note I have posted the above to show that I have actually tried to sort this myself. The above code will probably not even help as a starting point as a restructure of the HTML may be necessary!
Here is the current HTML (probably needs to be restructured):
<div id="dd_foo" class="dd">
<nav>
LINK
</nav>
</div>
Here is a possible restructure (something like):
<div id="dd_foo" class="dd">
<div class="handle"><!-- Dropdown Handle --></div>
<nav>
LINK
</nav>
</div>
This is what I need the box to look like (notice the faint white border at the top and half way down the sides):
I have also included the box split into its separate elements (handle and background)
I think I can see how this can be done with clever overlaps and nested divs, but ideally I don't really want to resort to this... Can anybody suggest an alternative solution?
Simplest approach
You can try achieving this using a simple box shadow:
.plaque {
box-shadow: inset 0 1px 1px 0 rgba(255, 255, 255, 0.32);
/*...*/
}
An Example
Here's an example using 1 class and a div on jsbin.
Copy paste code
This code is only for modern browsers; it might cause ie < 9 and other non supporting browsers to explode.
.plaque:after {
top: -9px;
content: " ";
height: 11px;
width: 30px;
position: absolute;
pointer-events: none;
left: 50%;
margin-left: -15px;
display: block;
background-repeat: no-repeat;
}
.plaque {
width: 250px;
height: 100px;
display: block;
border: 0;
outline: 0;
padding: 12px 16px;
line-height: 1.4;
box-shadow: inset 0 1px 1px 0 rgba(255, 255, 255, 0.32);
border-radius: 5px;
border: 1px solid transparent;
font-family: sans-serif;
color: white;
font-size: 1.2em;
text-overflow: ellipsis;
position: relative;
top: 6px;
}
/* Use whatever background you want */
.plaque { background-color: green; }
.plaque:after { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAALCAYAAACZIGYHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAcJJREFUeNqMUktPU0EU/mZuL6Up1RCjC4oRau4t4FJ84EKID/ZAjI9/6Mo/4MadG5dqJGjBatpyuY+2UNreeXDOBE0MNHGSSWZyzvnOd77zicdbd+EVJKyxGPSHmC4XIYSAMQYCoJhn81wJKSnHWhR8D1oZl69yhamiD8GBSefpywc2XKzjy7fP+PDuk5iUJxnksvvkxX1buxkgThOEt5exvr1qJ+XKy5CfvXpow9oSsn6GdqeF40EPK+GKY/ZfTNa3Vm1AI6TdFAeNfQgp0CKgrJehVg1AGl5gJLTWfxGfv15zI3BBnB5CehJGG5Cw8EjY6tw8KjNXsfv9K96//SguMOERgoU6+ic9NH8eQClNGzDQBMLb4FU1fzdxFB+hev0WNnbu2X802TxnkGQJoriNymwZHrFgAbhdidbOK+YTxR0ojLEc3sHmm0dOI8Gq10n9OI1xGLVcMvuGGYyHOYqlKcfK9wvOF3/i12ZvoFK+gsavPUgGSLsJkm4En4xDTqMi45iUZqZdd34zJY7L8was2enoGMHCEmS3l6LxYx9qrJ2I7FTNelBxPlKuYDgYu9nzUe6cenoygqF/J2o7AmcCDACumSjtgWp8aAAAAABJRU5ErkJggg==); }
I have a problem positioning an inputfield with variable size and a post button with fixed size inside of a div with fixed "outer-margin".
I've provided a jfiddle example where you can see the wrong version.
Here you can see my problem:
Wrong version: Actual website
"Should-be" version: This is what it should look like
Textual description:
As you can see in the 2nd picture, it's important for me that the bottom-part always sits on the bottom...
.submitform {
display: block;
position: fixed;
bottom: 0;
...more on jfiddle...
}
... and the post-button always on the right. The bottom-part should have the same gap on the left and right as the upper-part. The difficult thing is, that the inputfield should have flexible size but should take all the space between left gap and post-button.
I hope you can help me because hours of trying and searching on the web didn't brought me the right solution.
Try this: http://jsfiddle.net/jgHAA/1/
.submitform {
background: white;
display: block;
position: fixed;
/* Instead of applying margin and width, simply set the bottom, left,
and right properties to 13px */
bottom: 13px;
left: 13px;
right: 13px;
/*box-shadow: 0 2px 7px rgba(0, 0, 0, 0.1);*/
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
padding: 7px;
overflow:hidden;
box-sizing:border-box;
}
to have the textbox fill the width, you can use the same technique: http://jsfiddle.net/jgHAA/2/
.submitform #post_input {
display: block;
font-size: 18px;
border: none;
outline: none;
padding: 3px;
/* set left and right, and z-index to make it appear behind the button.*/
left:7px;
right:7px;
position:absolute;
z-index:-1;
}