I need to give a link background styling. As the width will vary I need to use 2 images, which is why I have a span within my link.
Ive also needed to float the link left, which means I have to set paragraphs to clear both.
My solution works but it seems like a lot of css and adding extra html elements. Is there a more elegant solution?
http://jsfiddle.net/p9aXg/16/
<p>Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text </p>
<a href="#" class="my-link"><span> This is a link sdafsdafsdaf </span>
</a>
<p>Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text Here is some text </p>
a {
background: url("http://smartpeopletalkfast.co.uk/body-link-bg.jpg") 100% 50%;
line-height: 50px;
float: left;
}
a span {
background: url("http://smartpeopletalkfast.co.uk/body-link-bg-2.jpg") no-repeat;
height: 49px;
display: block;
padding-left: 20px;
padding-right: 40px;
}
p {
clear: both;
}
If you use "display;inline-block" instead of floating, you can remove a bit of the CSS.
See the updated fiddle here: http://jsfiddle.net/p9aXg/19/
a {
background: url("http://smartpeopletalkfast.co.uk/body-link-bg.jpg") 100% 50%;
display:inline-block;
}
a span {
background: url("http://smartpeopletalkfast.co.uk/body-link-bg-2.jpg") no-repeat;
line-height: 50px;
display: block;
padding-left: 20px;
padding-right: 40px;
}
As a general styling note, you should always try to avoid floating if you can. When you float an element, it takes it out of the flow of the page. This typically forces you to float other elements to make them line up as if they were in the flow of the page. I've seen it snowball to the point where every element is floated, which is simply an unnecessary headache.
Using inline-block instead of float will work most of the time. See the following links for more information:
http://joshnh.com/2012/02/07/why-you-should-use-inline-block-when-positioning-elements/
float:left; vs display:inline; vs display:inline-block; vs display:table-cell;
http://www.vanseodesign.com/css/inline-blocks/
http://www.ternstyle.us/blog/float-vs-inline-block
It's possible to do this with no images and no extra elements, if you embrace 'progressive enhancement' across the range of browsers which you support. Here's an example: http://jsfiddle.net/Rt2Wa/4/
This uses CSS3 techniques to achieve a result that's as nice as your example in modern browsers, and produces a flat-but-beveled link in IE 7 & 8.
There are a few techniques at play here:
display: inline-block (mentioned by Ryan Henderson - very useful!)
border-radius
background gradient
:after pseudo-element
CSS triangles (created with a border effect).
Here's the basics of the effect (see the fiddle for a version with the vendor-prefixed styles where applicable):
a:link {
background-color: #18A580;
background: linear-gradient(to bottom, rgba(29,186,144,1) 0%,rgba(24,165,128,1) 100%);
box-shadow: 0px 1px 2px rgba(50, 50, 50, 0.35), inset 0px 0px 1em 0px rgba(255, 255, 255, 0.4);
border-radius: 0.3em;
border-top: 1px solid #67D0BF;
border-bottom: 1px solid #18805B;
color: #FFF;
display: inline-block;
padding: 0.45em 0.75em;
text-decoration: none;
margin-bottom: 0.8em;
}
a:link:after {
content: '';
display: inline-block;
width: 0px;
height: 0px;
border-style: solid;
border-width: 0.25em 0 0.25em 0.5em;
border-color: transparent transparent transparent #FFF;
margin-left: 0.75em;
}
I would use one background image and make it adjust
DEMO jsFiddle
a {
background-image: url("image.jpg");
background-repeat:no-repeat;
background-size:90% 70%;
background-position:center;
line-height: 50px;
padding:20px;
}
Related
I have the following code. It's a simplified code of a responsive design: In a certain screen size I want to show only the icon (blue - via ::before) but not the text.
When I try to hide the mail address via font-size: 0 (there will be an icon in the ::before) - the header grows in height.
Sure I could use max-height - but is there a cleaner solution?
Fiddle: https://jsfiddle.net/xs2wre4r/
<div class="header">
<span class="store-contact-email">
info#example.com
</span>
</div>
<div class="header">
<span class="store-contact-email">
<a class="hide" href="mailto:info#example.com">info#example.com</a>
</span>
</div>
Left .header frame is computed = 25px
Right .header frame is computed = 30px
.header {
float: left;
}
.header .store-contact-email a:before {
line-height: 18px;
vertical-align: -36%;
padding-right: 5px;
background-color: blue;
width: 30px;
display: inline-block;
}
.header .store-contact-email a:before {
content: "x";
}
.store-contact-email {
border: 1px solid red;
}
.store-contact-email a {
font-size: 18px;
}
.store-contact-email a.hide {
font-size: 0px;
}
The problem is with the font sizes of the ::before blocks.
Since the second one has a font size of 0 and a line height of 18, it will be vertically positioned around the baseline, with 9px above and 9px below. The first one (with the normal font size) will be positioned normally (depending on the exact font), with, say, 14px above and 4px below.
(You also have vertical-align on the ::before, but that doesn't change the situation; it moves both ::before blocks 6.48 pixels down.)
So since the second one is located 5px lower than the first one, the bottom of the bounding box will be pushed down by 5px.
To illustrate,
span {
font-size: 18px;
border: 1px solid red;
background: rgba(255, 255, 0, .4);
}
span::before {
line-height: 18px;
vertical-align: -36%;
border: 1px solid blue;
background: rgba(0, 255, 255, .4);
width: 30px;
display: inline-block;
content: "x";
}
span.hide {
font-size: 0;
}
<span>visible</span>
<span class="hide">invisible</span>
Solution: don't use the font-size:0 trick.
You can set font-size of ::before, as it's inheriting parent font-size.
.header .store-contact-email a:before {
content: "x";
font-size: 18px;
}
Or you can use display or visibility, just avoid :before to inherit that property.
wrap the text with span and hide the span
<div class="header">
<span class="store-contact-email">
<a class="hide" href="mailto:info#example.com"><span>info#example.com</span></a>
</span>
</div>
.store-contact-email a.hide span {
display:none;
}
Better to:-
(1) nest the text info#example.com inside another span, which will display:none under a breakpoint; or
(2) put the icon on .store-contact-email:before instead of .store-contact-email a:before.
The reason is that browsers often enforce a minimum font size for accessibility purposes.
This question already has answers here:
Add centered text to the middle of a horizontal rule [duplicate]
(33 answers)
Closed 8 years ago.
How to add lines to the sides of text, create something like text separator but whithout background for text.
<h5>Some text goes here</h5>
In this post CSS challenge, can I do this without introducing more HTML? all solutions are with text background.
In my case text is on the image, so text background is awful.
Could this not be done even more minimally these days with the :before & :after selectors?
h5:before, h5:after{
content: '';
width: 2em;
height: 2px;
padding: 0;
margin-right: 5px;
background-color: #000000;
display: inline-block;
position: relative;
bottom: 3px;
}
h5:after{
margin-left: 5px;
margin-right: 0;
}
Here’s a fiddle: http://jsfiddle.net/3616he4y/2/
Your best solution is probably to add another element. You can't do this without that. You could try:
<h3><span>TEXT</span></h3>
h3 {
background-image: url(single-pixel-img.gif) 50% 50% repeat-x;
text-align: center;
padding: 0 20px;
}
h3 span {
background: #fff;
display: inline-block;
}
Then you can still add some padding to the span etc... The single line image could be a 1x1 black gif that'll add almost nothing to your pageload. It's simple, elegant and adds only a couple more lines of code.
to me, the pseudo elements here are very usefull once again and as the link to csstricks explains, it is not a big deal to set.
I'd rather use the static position , cause it can have some advantage once text breaks into a few lines.
Examples behavior/DEMO :
HTML
<h1>text & strikes</h1>
<h1>text <br/>& </br/>strikes</h1>
<h1><span>text <br/>& </br/>strikes</span></h1><!-- see demo to find out <span> purpose */
CSS
h1 {
text-align:center;
overflow:hidden;/* hide parts of pseudo jumping off the box */
text-shadow:0 0 1px white;/* increase visibility of text if bg is dark too */
background:url(http://lorempixel.com/100/600/abstract);
}
h1:before,
h1:after {
content:'';
display:inline-block;
height:0.06em;
width:100%;/* could be a little less*/
box-shadow:/* looks like text */
inset 0 0 0 20px,
0 0 1px white
;
vertical-align:middle;
}
h1:before {
margin-left:-100%;/* width is virtually reduce to zero from the left side to stick to text coming next */
margin-right:0.5em;
}
h1:after {
margin-right:-100%;/* width is virtually reduce to zero from the right side to stick to text */
margin-left:0.5em;
}
span {
display:inline-block;/* holds any line breaks */
vertical-align:middle;
}
Try <hr/>
FIDDLE DEMO
hr {
width:100px;
border:2px solid;
}
h5{
text-align:center;
}
You can use borders:
h5 {
border-right: 1px solid #dadada;
border-left: 1px solid #dadada;
}
If you want to have space between the lines and the text, you can add padding left and right to the styling:
h5 {
border-right: 1px solid #dadada;
border-left: 1px solid #dadada;
padding: 0 5px;
}
If you want to use the h5 as a nav item and you want to separate it from the rest of the items (the reason you need the divider) you can put the border only on the right, and every next item will inherit the settings.
For the last item, obviously you would want to remove the border right as it doesn't have anything after it, so you can do:
h5 {
border-right: 1px solid #dadada;
}
h5:last-child {
border-right: none;
}
I'm working on a personal project, but I'm having some difficulty with a div, which has some styling that I can't seem to get around. It's a thin strip at the top of my user interface, where users have a few controls over what's shown on the screen. Pretty important to keep around (so deleting it isn't an option). In case it helps at all, I am using Eric Meyer's CSS Reset as a normalizer.
My problem is that the div element seems to have some intrinsic margin or padding that I can't seem to work around in my css. I've included a photo here for reference; the div is in green.
I need to make that green div element thinner. It would help the layout a lot if I could move it closer to the top of the page. If you have any ideas or see something that I've missed, I would appreciate the help.
I'm also including the html code for that content as follows:
<div class="new_entry_control_container">
<p>You have <span class="credits">33 Credits</span> remaining.
<span class="button">Add More Credits</span>
<span class="button">Add More Items to Study List</span>
<span class="pagination">< 1 | 2 | 3 ></span>
</p>
</div>
As well as the CSS that applies here:
div.new_entry_control_container {
background-color: green;
max-width: 900px;
margin-left: auto;
margin-right: auto;}
div.new_entry_control_container p {
text-align: center;}
.credits {
color: #ffd400;}
.button {
background-color: #ffd400;
color: #3a0091;
border: none;
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
border-radius: 6px;
padding: 1px 8px 4px 8px;
margin: 10px 0px 0px 3px;}
.pagination {
margin-left: 25px;
font-size: 17px;}
Not sure if it's caused by the padding of parent element of that green bar. A workaround would be using negative "margin-top". And to make it thinner (assuming there would only be one line in that bar), use "height" combined with "line-height".
So the css might look like this
div.new_entry_control_container {
background-color: green;
max-width: 900px;
margin-left: auto;
margin-right: auto;
margin-top: -10px;
height: 18px; line-height: 18px;
}
Hope that helps.
Try:
div.new_entry_control_container{
padding:0;
/* more CSS here */
}
.credits{
padding:0; margin:0;
/* other CSS here */
}
Is it possible to add padding before line-break? As in, making from this to this .
Current CSS code:
span.highlight { background: #0058be; color: #FFF; padding: 2px 5px; }
I had to add an extra margin-left:0; to make the two lines start at the same point.
This can be done with pure CSS. Create a solid box-shadow to the left and right of the highlight in the same color (and use margin to correct the spacing). For your case:
span.highlight {
background: #0058be;
color: #FFF;
box-shadow:5px 0 0 #0058be, -5px 0 0 #0058be;
padding: 2px 0;
margin:0 5px;
}
It took some tryouts, but here it is: the single- and multi-line highlighter with additional padding.
HTML:
<h3>Welcome to guubo.com, Gajus Kuizinas</h3>
<p><span>So far you have joined: </span><em>Networks guubo.com</em><ins></ins></p>
CSS:
h3 {
padding-left: 5px;
}
p {
background: #0058be;
position: relative;
padding: 0 5px;
line-height: 23px;
text-align: justify;
z-index: 0;
}
p span {
background: #fff;
padding: 2px 0 2px 5px;
position: relative;
left: -5px;
}
p em {
background-color: #0058be;
color: #fff;
padding: 2px 5px;
}
ins {
position: absolute;
width: 100%;
line-height: 23px;
height: 23px;
right: -5px;
bottom: 0;
background: #fff;
z-index: -1;
}
The trick is to style the whole paragraph with a blue background, and only put white background on top of that at the beginning and the end. Doing so assures blue background elsewhere...;)
Two main disadvantages:
The highlighted text has to start at the first line (but does not necessarily have to flow into a second),
The paragraph has to be aligned with justification.
Tested in Opera 11, Chrome 11, IE7, IE8, IE9, FF4 and Safari 5 with all DTD's.
See edit history for the previous less successful attempts.
You can achieve this using just box shadow, with no messy padding or margins.
The trick is to use box-shadow's spread option, and the padding on wrapped inline elements behaves as you expect.
.highlight {
background: black;
color: white;
box-shadow: 0 0 0 5px black;
}
display: block will achieve part of what you want, but of course it will make the span a block element, and so you won't get the wrapping behaviour seen in your example.
Your screenshot holds the clue to what you need to try and do: you need to impose a margin to the left and right on your "normal" paragraph text, and then have the span disregard this (and include its padding), to achieve an "overhang" of your blue highlight when compared to the rest of your text. You can't do that with straight CSS on your span, because it covers two lines and obviously "left" and "right" only refer to the span, and not the individual pieces of text contained therein.
Straight CSS isn't the answer here. You might want to take a look at this question, which uses a jQuery filter to grab the first word in an entity, etc.:
jQuery first word selector
Maybe you can use this technique.
http://samcroft.co.uk/2011/jquery-plugin-for-inline-text-backgrounds/
The closest thing, if it really matters that much I'd say is to add display: inline-block;
Problem
I am working on a project to theme a website, but I am not allowed to change the HTML or JavaScript. I can only update the CSS stylesheet and add/update images.
Requrements
I need to style a h3 tag to have an
underline/border after the content.
This h3 will be used multiple times
on the page, so the conent length can
vary
The solution needs to be
cross-browser (IE 6/7/8, FF 3, &
Safari)
Sample Code
<div class="a">
<div class="b"><!-- etc --></div>
<div class="c">
<h3>Sample Text To Have Line Afterwards</h3>
<ul><!-- etc --></ul>
<p class="d"><!-- etc --></p>
</div>
</div>
Sample Output
Sample Text to Have Line Afterwards ______________________________________
Another Example __________________________________________________________
And Yet Another Example __________________________________________________
Notes
I think #sample:after { content: "__________"; } option wouldn't work since that would only be the correct length for one of the tags
I tried a background-image, but if it gave me problems if I gave it one with a large width
Using text-indent didn't see to give me the effect I was looking for
I tried a combination of border-bottom and text-decoration: none, but that didn't seem to work either
Any ideas would be much appreciated!
This will work if class 'c' is always the parent of the h3...
.c {
position: relative;
margin-top: 25px;
border-top: 1px solid #000;
padding: 0px;
}
h3 {
font-size:20px;
margin-top: 0px;
position: absolute;
top: -18px;
background: #fff;
}
It lets the container have the border, then uses absolute positioning to move the h3 over it, and the background color lets it blot out the portion of c's border that it's covering.
try attaching a background image to class c of a repeating underline, then add a background color to the h3 to match the background of the container. I believe that you would have to float the h3 left in order to get the width to collapse. does that make sense?
.c {
background: #ffffff url(underline.gif) left 20px repeat-x;
}
.c h3 {
margin: 0;
padding: 0 0 2px 0;
float: left;
font-size: 20px;
background: #ffffff;
}
.c h3 { display: inline; background-color: white; margin: 0; padding: 0; line-height: 1em; }
.c ul { margin-top: -1px; border-top: 1px solid; padding-top: 1em; /* simulate margin with padding */ }
http://besh.dwich.cz/tmp/h3.html
H3 {
border: 1px solid red;
border-width: 0 0 1px 0;
text-indent: -60px;
}
You need to know the width of the text, but works pretty well.
The only solution I've imagined so far is to make a PNG or GIF image, with 1px height and a very large width (depends on your project, could be like 1x2000px), and do something like this:
h3#main-title { background: url(line.png) no-repeat bottom XYZem; }
where the XYZ you'd set manually, for each title, in 'em' units. But I can't figure out a 100% dynamic solution for this one, without using JS or adding extra markup.
this worked for me
div.c
{
background-image:url(line.gif);background-repeat:repeat-x;width:100%;height:20px;
}
div.c h3
{
height:20px;background-color:white;display:inline;
}
you make the div the width of your content
then you set the background of the h3 to the background of your page. this will then overlap the background imageof the full div. You might want to play with background positioning depending on your image
Can you pad content in the UL tags? If so, this might work:
h3 { display: inline; margin: 0; padding: 0 10px 0 0; float: left;}
ul { display: inline; border-bottom: 1px solid black; }
check source code of: http://nonlinear.cc/lab/friends/elijahmanor.html
then again i have NO IDEA how to control the end of the line.
Assuming that you're working with dynamic content, the best I could suggest is to accept graceful degradation and use a mix of great_llama and Bohdan Ganicky
Imagine:
A long title that will wrap to two lines___________________
and leave you like this in great_llama's solution
and nothing appearing at all with Bohdan Ganicky's solution if ul isn't immediate preceded by ul.
Solution:
.c h3 { display: inline; background-color: white; margin: 0; padding: 0; line-height: 1em; }
.c + * { margin-top: -1px; border-top: 1px solid; padding-top: 1em; /* simulate margin with padding */ }
We care about IE6, but accept that this is an aesthetic touch and IE6 users will not suffer. If you can't get the designer to accept this AND you can't alter the HTML, then do something else (before you find another job ;))
Here's a better answer:
.c {
background: url('line.png') repeat-x 0 20px;
}
H3 {
background-color: white;
display: inline;
position: relative;
top: 1px;
}
Use a small, 1px height, couple px wide image as your underline and occlude it with a background color on your H3.
h3:after {
content: '___________';
}