Drawing a ribbon on a <div> using images and CSS - css

I'm looking to make a ribbon with a div, :before and :after psuedo-elements and 3 pictures. I got the :before image to work, but I can't seem to get the :after image to align to the right side. (please don't link to css-tricks, they use pure CSS, I'm after images!)
I think using relative placements might be a better alternative to floats, but I don't quite understand them.
Aside: does anyone know what is causing the border around the bottom and sides of navbar-inner?
EDIT: Updated CSS because I hate when people post temporary websites on SO:
div.hero-unit {
background: url(../img/ribbon-center.png) repeat-x;
border-radius: 0;
margin: 0 -15px;
padding: 30px;
float: left;
}
div.hero-container:before {
content: url(../img/ribbon-fold-left.png);
float: left;
margin-left: -30px + -48px + 15px; /* - Padding size (30px) - image width (48px) + margin (15px) */
}
div.hero-container:after {
content: url(../img/ribbon-fold-right.png);
background: transparent;
float: right;
margin-right: -48px + -15px; /* - image-width (48px) - margin (15px) */
}
HTML:
<div class="hero-container">
<div class="hero-unit">content</div>
</div>

One option is to use a negative right margin on div.hero-container::after .. I played around with it in Firebug and 15px seems about right. I'm not sure why the image isn't aligning to the right though.
Aside: does anyone know what is causing the border around the bottom and sides of navbar-inner?
Thats a box-shadow on .navbar-inner not a border

Related

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

Div Container Cleanup?

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.

CSS Positioning - Top and Right

I'm creating a div which has to have a close button in the upper right corner just like in the image
image http://rookery9.aviary.com.s3.amazonaws.com/4655000/4655386_f01b_150x250.jpg
The first image was made in photoshop. I'm trying to do the same but with CSS. "Fechar" is the close button (in Portuguese). What is the better way to properly position it without workarounds, with clean CSS and Web Standards?
Here is my code: http://jsfiddle.net/wZJnd/
This is as far as I could reach.
I would use absolute positioning inside a relatively positioned #header:
HTML
<div id="header">
<h1>Your Title</h1>
Close
</div>
CSS
#header {
width: 700px;
height: 200px;
position: relative;
text-align: center;
background: #000 url(the-logo.png) no-repeat 30px 10px;
}
#header .close {
position: absolute;
top: 20px;
right: 20px;
}
This will cause the a.close link to use the #header as its coordinate system and position it 20px from the top and right edge.
In my experience padding, margins and float are more sensitive to rendering inconsistency and font size changes than positioning. As a result, I use position whenever possible.
You could do a :
img.close {
float:right;
margin:25px 25px 0 0;
}
I would work with div wrappers around the img
So you would have a div for your header "div.header" that would contain these div :
div.logo : The logo on the left containing an img tag;
div.title : The title of the page;
div.close : The close button that would contain your img tag.
I better like using the padding than the margin attribute. I think it works better for compatibility purposes.

align icons with text

What's the best way to align icons (left) and text (right) or the opposite text on left and icon on right?
Does the icon image and text have to be the same size? Ideally I would like them to be different but be on the same vertical alignment.
I am using background-position css property to get the icons from a larger image.
Here is how I do it now, but I am struggling with either getting them to be on the same line or be vertically aligned to the bottom.
Text
This is what I get after I try your suggestions.
Though the text is now aligned with the icon, it is superimposed over the icon to the right of the icon that I want. Please note that i am using the background position to show the icon from a larger set of images.
Basically I am getting
<icon><10px><text_and_unwanted_icon_to_the_right_under_it>
<span class="group3_drops_icon group3_l_icon" style="">50</span>
group3_drops_icon {
background-position:-50px -111px;
}
.group3_l_icon {
-moz-background-clip:border;
-moz-background-inline-policy:continuous;
-moz-background-origin:padding;
background:transparent url(/images/group3.png) no-repeat scroll left center;
height:35px;
overflow:hidden;
padding-left:55px;
}
I usually use background:
<style type="text/css">
.icon {
background-image: url(path/to/my/icon.jpg);
background-position: left center;
background-repeat: no-repeat;
padding-left: 16px; /* Or size of icon + spacing */
}
</style>
<span class="icon">Some text here</span>
You can do it on the same line using vertical-align and line-height
<p style='line-height: 30px'>
<img src='icon.gif' style='vertical-align: middle' />Icon Text
</p>
Alternatively, you can go the background approach with no-repeat and positioning:
span.icontext {
background: transparent url(icon.gif) no-repeat inherit left center;
padding-left: 10px /* at least the width of the icon */
}
<span class="icontext">
Icon Text
</span>
Sadly, neither of these answers are bullet proof and each have one big flaw.
#rossipedia
I used to implement all my icons this way and it works quite well. But, and this is a big but, it does not work with sprites, since you're using the background-position property to position the icon inside the container that includes your text.
And not using sprites where you can is bad for performance and SEO, making them imperative for any good modern website.
#Jamie Wong
The first solution has two markup flaws. Using elements semantically correctly is sadly underrated by some, but you'll see the benefits in prioritizing form in your search engine ranking. So first of all, you shouldn't use a p-tag when the content is not a paragraph. Use span instead. Secondly, the img-tag is meant for content only. In very specific cases, you might have to ignore this rule, but this isn't one of them.
My Solution:
I won't lie to you, I've checked in a lot of places in my time and IMHO there is no optimal solution. These two solutions are the ones that come closest to that, though:
Inline-Block Solution
HTML:
<div class="container">
<div class="icon"></div>
<span class="content">Hello</span>
</div>
CSS:
.container {
margin-top: 50px;
}
.container .icon {
height: 30px;
width: 30px;
background: #000;
display: inline-block;
vertical-align: middle;
}
.container .content {
display: inline-block;
vertical-align: middle;
}
"display:inline-block;" is a beautiful thing. You can do so much with it and it plays very nicely with responsive design.
But it depends on your client. Inline-Block does not work well with IE6, IE7 and still causes problems with IE8. I personally no longer support IE6 and 7, but IE8 is still out there. If your client really needs his website to be usable in IE8, inline-block is sadly no option. Assess this first. Replace the black background of the icon-element with your sprite, position it, throw no-repeat in there and voilĂ , there you have it.
Oh yeah, and as a plus, you can align the text any way you want with vertical-align.
P.S.: I am aware that there's an empty HTML-tag in there, if anyone has a suggestion as to how to fill it, I'd be thankful.
Fixed Height Solution
.clearfix:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
.clearfix {
display: inline-block;
}
html[xmlns] .clearfix {
display: block;
}
* html .clearfix {
height: 1%;
}
.container {
margin-top: 50px;
border: 1px solid #000;
}
.container .icon {
height: 30px;
width: 30px;
background: #000;
float:left;
}
.container .content {
line-height: 30px;
float: left;
display: block;
}
I hate this one. It uses a fixed line height for the text, and if you choose the same height as the Icon's box, the text is centered to that height. To align the text to the top, cut the line height, and as to the bottom, you'll have to fix that with position: absolute and a fixed width and height for the container. I'm not going to get into that unless someone requests it, because it's a whole issue for itself, and brings with it a lot of disadvantages.
The main disadvantage of this path is the fixed height. Fixed heights are always unflexible and especially with text, it can cause a bunch of problems (You can no longer scale the text as a user without it being cut off, plus different browsers render text differently). So be sure that in no browser the text is cut off and that it has some wiggle room inside its line height.
P.S.: Don't forget the clearfix for the container. And, of course, replace the black background with your sprite and according position + no-repeat.
Conclusion
Use inline-block if at all possible. ;) If it's not, breath deeply and try the second solution.

Getting image to stretch a div

How can I get an image to stretch the height of a DIV class?
Currently it looks like this:
However, I would like the DIV to be stretched so the image fits properly, but I do not want to resize the `image.
Here is the CSS for the DIV (the grey box):
.product1 {
width: 100%;
padding: 5px;
margin: 0px 0px 15px -5px;
background: #ADA19A;
color: #000000;
min-height: 100px;
}
The CSS being applied on the image:
.product{
display: inline;
float: left;
}
So, how can I fix this?
Add overflow:auto; to .product1
In the markup after the image, insert something like <div style="clear:left"/>. A bit messy, but it's the easiest way I've found.
And while you're at it, put a bit of margin on that image so the text doesn't butt up against it.
Assuming #John Millikin is correct, the code
.product + * { clear: left; }
would suffice to do the same thing without forcing you to manually adjust the code after the div.
One trick you can use is to set the <div>'s overflow property to hidden. This forces browsers to calculate the physical size of the box, and fixes the weird overlap problem with the floated image. It will save you from adding in any extra HTML markup.
Here's how the class should look:
.product1 {
width: 100%;
padding: 5px;
margin: 0px 0px 15px -5px;
background: #ADA19A;
color: #000000;
min-height: 100px;
overflow: hidden;
}
This looks like a job for clearfix to me ...
Try the following:
.Strech
{
background:url(image.jpg);
background-size:100% 100%;
background-repeat:no-repeat;
width:500px;
height:500px;
}
display:inline
float:left
is your problem
Floating makes the parents width not be stretched by the child, try placing the image without the float. If you take the float off, it should give you the desired effect.
Another approach would be to make sure you are clearing your floats at the end of the parent element so that they don't scope creep.
Update: After viewing your link Your height issue as displayed, is because the floats are not being cleared.

Resources