I can't seem to get the background of a <legend> element to be transparent. See this jsFiddle: http://jsfiddle.net/hWZa6/ (tested in Chrome and Firefox)
The effect I am trying to accomplish is actually moving the <legend> element below the top border of the containing <frameset> element, but nothing I do makes the top border complete. It is always missing the bit of the line where the legend would be, whether I try to use transparency or position:
http://cl.ly/image/1W043h0I3f0A/Edit%20this%20Fiddle%20-%20jsFiddle.jpg
How can I make the area of border where the legend WOULD be, complete?
You can add position:absolute to the legend. Optionally add position:relative to the fieldset so you can move things around.
You can position it off the screen,
position:absolute; left:-999em;
Or your favorite offsetting technique that's compatible with screenreaders and such. ( Perhaps investigate boilerplate's image replacement styles )
Try this, just hide the fieldset border and wrap the element in a div with a border. http://jsfiddle.net/hWZa6/15/
<div id="wrapper">
<fieldset>
<legend>Test</legend>
The top border is never fully visible, despite the legend being set <code>visibility: hidden</code>.
<div id="A">
<div id="B">Upon applying <code>visibility: hidden</code> this div becomes transparent, and the red div behind it is fully visible.</div>
</div>
</fieldset>
</div>
fieldset { border: none; }
#wrapper { border: 1px solid black; }
legend { display: block }
#A { background-color: red; width: 300px; height: 150px; padding: 10px;}
#B { background-color: blue; width: 400px; height: 100px;}
Use this CSS for the legend element.
legend { margin-left: -9999px; }
If you don't want to, or can't change the HTML, and you don't need the legend text to be visible, you can turn the display off.
legend { display: none; }
If you do have control over the HTML, then #user1289347's solution would work, though it requires adding wrapper elements.
Related
For a simple landing page I wanted to let some text box overlap an header image. To make it simple, I just have a structure like:
<header>
<img src="path/to/img.png" />
<h1>Awesome headline</h1>
</header>
All elements are set to display:block and the h1 is dragged inside the image with a negative margin. I also gave the headline some padding and background:white.
Now the problem: The headline text is shown on top of the image but the background colour is behind it! You can see an example here: https://jsfiddle.net/cv12evLn/
My guess is, that a browser renders all sibling blocks in layers, starting with all backgrounds and borders, then rendering images (img-tags) and finally text on top of everything else.
Is that right? And why the actual… I mean, that seems crazy unexpected to me.
To solve the issue, I've put the headline in a wrapper and set this to position:absolute. See here for a live example: https://jsfiddle.net/f5sd1u6o/
Use position:relative rather than negative margin. Then the z-index works automatically.
#container {
width: 500px;
height: 300px;
margin: auto;
}
#container img {
display: block;
width: 100%;
}
#container h1 {
display: block;
width: 50%;
height: 1em;
margin: auto;
padding: .5em 1em 1em;
font-size: 3rem;
background: yellow;
text-align: center;
border: 1px solid red;
position: relative;
top: -4.6rem;
}
<div id="container">
<img src="//placekitten.com/500/300">
<h1>
headline
</h1>
</div>
To get the Z-index to work, you need to apply position:relative anyway but you can still use negative margin if that is a design requirement.
JSfiddle demo (with negative margin)
Basically, backgrounds are rendered first before anything else (as I understand it) so they always come at the bottom of the stacking order. You just need to create a new stacking context and changing the position property does that.
As it happens so does changing the opacity of the element so a quick fix is to set opacity:.9999;
JSfiddle Demo (opacity 'hack')
TLDR: this codepen works fine in Chrome, but the alignment is off in Firefox.
I'm building a jQuery plugin which modifies a text input to give it a dropdown button on the left. In order to get the positioning right, I add a wrapper div, which is the same height as the input, so the button can be absolutely positioned on top of the input, and yet still have the same height:
#wrapper {
position: relative;
}
#overlay {
position: absolute;
top: 0;
bottom: 0;
width: 30px;
}
This works fine until the input has vertical margin: then the container grows to include the margin, and so the dropdown button grows with it. My solution to this was margin collapsing: I gave the input display:block which meant that the container ignored it's margin. All good.
input {
margin: 20px 0 40px; /* testing */
display: block;
}
But now the problem is that by default, inputs are inline elements e.g. you might want to have a submit button next to the input. So I wrapped the whole thing in a container div with display:inline-block, so another inline element like a button can happily sit next to it.
#container {
display: inline-block;
}
This works fine in Chrome, but has weird alignment issues in Firefox when there's any vertical margin on the input. Below I've added the final markup. There's also a codepen link at the top.
<div id="container">
<div id="wrapper">
<input>
<div id="overlay"></div>
</div>
</div>
<button>Submit</button>
Edit: the point is that this is a plugin and I'm trying to work with the user's existing markup and CSS e.g. they have this markup:
<input><button>Submit</button>
and their existing CSS has vertical margin on the input, and I want them to be able to just initialise my plugin on the input and it just work, without forcing them to change their markup/CSS. Now because the plugin needs to add lots of markup around the input (for the overlay and the dropdown list), I wrap it all up in a container div. This container div is the limit of our reach (and does not include the button element, or anything else they choose to put next to their inputs).
To fix this, you'll need to define a line-height in your parent div#test2. Without it, different browsers will give it different values. This will cause Firefox to cause this weird result.
Now, the line-height isn't the only problem, also the vertical-align's baseline value will generate a different result for inline elements than it is for inline-block elements that have a different height than the surrounding inline content. To fix this, change the value to top for the #container element (since that's the inline-block element).
The final result would have the following changed (only pasting the parts that changed):
#test2 {
background-color: green;
line-height:70px;
#container {
// replicate the inline nature of the input
display: inline-block;
vertical-align:top;
}
//the rest of the #test2 nested code
}
That would look like this.
Reply to comment
I've made something that does work by the requirements set. Since you said the extra code (so the divs around the input) are made by the plugin itself, I've taken the liberty of changing that a bit to make this work.
The way it can work quite easily is just not using inline-blocks at all, and sticking with the inline elements. This would change the styles to the following:
#container {
// replicate the inline nature of the input
display: inline;
}
#wrapper {
display: inline;
position: relative;
}
input {
// you'll want to make sure the typed text doesn't appear behind the overlay
padding-left:35px;
}
#overlay {
position: absolute;
top: 0px;
bottom: 0px;
left: 1px;
width: 30px;
background-color: #00C2FF;
}
Notes:
I didn't bother making the overlay cover the full height of the input, since your plugin would just make it a flag anyway. To make it cover the full height, just set negative top and bottom styles on the overlay, equal to the computed padding-top and padding-bottom (resp.) on the input. In this case, you'd have to change them to top:-5px;bottom:-5px;. (you can get the computed style via jQuery's $(input).css('padding-top'))
You could actually also remove the whole #container from it, since the only style it has now is display:inline which really doesn't add anything to the whole thing.
I've added a padding-left to your input, because otherwise you'd have to type behind the overlay, which is just silly.
Is the HTML generated by the plugin and it needs to stay exactly the same? I'm not sure I can figure out exactly why the second example is not working, but you seem to have too many div elements there. You could make since simpler:
HTML
<div id="test1">
<div id="wrapper">
<input>
<div id="overlay"></div>
<button>submit</button>
</div>
</div>
SCSS
input, button {
border: 1px solid black;
padding: 5px;
}
input {
display: inline-block;
padding-left: 35px;
}
#test1 {
background-color: yellow;
padding: 20px 0 40px 0;
#wrapper {
position: relative;
#overlay {
position: absolute;
top: 1px;
left: 1px;
width: 30px;
background-color: #00C2FF;
}
}
}
Codepen example
I've removed the margin, and instead used padding on the parent, it achieves the same thing. You'll also want some padding-left on your input field so the entered text doesn't disappear behind your overlay div.
EDIT: In case you are unable to change the markup:
SCSS:
#test2 {
background-color: green;
#container {
// replicate the inline nature of the input
display: inline-block;
padding: 20px 0 40px 0;
}
#wrapper {
// this is just here to be display:block and ignore the margin on the input
display: block;
position: relative;
}
input {
// tell parent to ignore margin
//display: block;
margin: 0;
}
#overlay {
position: absolute;
top: 1px;
bottom: 1px;
left: 1px;
width: 30px;
background-color: #00C2FF;
}
}
codepen demo
Removed the block and margin declarations from the input field, and moved the spacing to padding of the #container element.
"Disclaimer": Let me just start by saying that I did not find exactly what is causing the problems in Firefox, but I did think of an alternative way you could do it.
The way this works in both Firefox and Chrome is just to use the exact same HTML as you used for your #test1, but on top of that, also using the CSS :before pseudo-element (instead of using the #container and #wrapper). The code I used was:
#test2 {
background-color: green;
position:relative;
&:before {
content:"";
display:block;
position:absolute;
left:1px;
top:1px;
bottom:1px;
margin:20px 0 40px 0;
width:30px;
background:#00C2FF;
}
}
demo
The way this works is to simply position the :before overlay on exactly the same place as the divs previously were. As you can see, I've used most of the same styles as you did, but instead, I've put them on the :before pseudo-class.
Other answers don't know why it doesn't work on Firefox. Well, I think that Firefox has the right behavior and it's a Chrome problem.
In short, you want to align an input with a button. But the input is inside a wrapper. Then, you can use vertical-align to control the vertical aligning between the wrapper and the button, but not between the input and the button.
Here you can see an screenshot with different vertical-align:
See the code.
If you want to align the input and the button (last case in the image), you have a problem, because any of the keywords you can use with vertical-align does that. Only in case that input's top margin and bottom margin are equal, then vertical-align: middle works.
But in general, you have have another solution: vertical-align also accepts a <length> value.
And, to get a perfect alignment, you should use the formula
vertical-align: -(input bottom margin)
Or, if you want to align them even if the button has a bottom margin, then
vertical-align: -(input bottom margin) + (button button margin)
The code formula above works with inline-block <div>, but not with <buttons>.
The formula must be fixed to
vertical-align: -(input bottom margin) -(input offsetHeight)/2 + 6
In your example
(Input bottom margin) = 40px
(Input offsetHeight) = 31px
Then, you need
vertical-align: -(input bottom margin) -(input offsetHeight)/2 + 6
Demo
I could achieve it with the following.Codepen You will have to know the css applied to input and apply it to button as well
button{
position:absolute;
margin-left:5px;
}
input, button {
display: inline-block;
margin: 20px 0 40px 0;
}
please update below in your code.
input, button {
border: 1px solid #000000;
margin: 20px 0 40px;
padding: 5px;
vertical-align: top;
}
hope it will work
http://codepen.io/anon/pen/Isycu
Well I'm not sure how to ask this with words so I will post an image:
So in the image, there is a main div, lets call it "red".
Inside "red" there is another div called: "green"
Inside "green" there is an ul, with some li elements, they are supposed to have an underline, but that underline must get out of the div, so the problem I have, is getting that line outside of "green", when in the code, it is inside.
I'm guessing there might be some kind of overflow setting or some technique to achieve this, maybe its much easier than I think, but I just can't figure it out.
The sum it up, I need to get something from within a div, and get it to show outside of it as well.
I tried to google it as much as I could but I couldn't find anything that worked for me, maybe because I'm not even sure how to ask.
That depends on situation. If it is fixed size elements and they are always same size no matter what you could do it:
Position red div as relative, then green div as absolute and ul again as absolute. That will allow you move elements. Relatively to red div.
If it is stretching elements depending on size of window, it is harder and margin-left, margin-top and float:left would do the trick, but you should be very careful with it as it is hard to make cross-browser.
You cannot solve this with overflow. What you need to do is to let the ul inside green be set to position: absolute and the red box to position: relative.
I made a jsfiddle for it (my first).
see the demo as per your requirement :-
DEMO
HTML
<div class="red">
<div class="green">
<ul>
<li>loreum</li>
<li>loreum</li>
<li>loreum</li>
<li>loreum</li>
</ul>
</div>
</div>
CSS
.red {
width:300px;
height:300px;
background:red;
}
.green {
float: right;
height: 200px;
margin: 30px 30px 0;
width: 200px;
background:green;
}
.green ul {
left: 8px;
margin: 0;
padding: 0;
position: absolute;
width: 200px;
}
.green ul li {
list-style-type:none;
display:block;
border-bottom:1px solid white;
text-align:right;
}
Use "overflow : hidden" (css) for green div
I have a problem concerning CSS and HTML.
I'm trying to wrap a DIV around another element (an UL in this case) and having it wrap around it and at the same time keeping both centered. As an added bonus I can't set a specific width since the width of the content inside the wrapping DIV have to be dynamic (since this is basically a template).
I've tried floating, and that works as far as wrapping goes, but then the thing ends up either to the right or to the left.
I'm going a bit crazy over this, and google is no help!
Thanks in advance!
UPDATE:
Sorry about not including code or images. This is what I'm trying to do illustrated with images:
One state of the UL width
Another state of the width
The wrapping DIV can't stretch the full width of the container. It has to wrap around the UL.
The dark grey is the DIV around the UL. I need the DIV to wrap around the UL (which has a horizontal layout) no matter the width of the content, since like I said above, the content of the UL is going to by different from time to time. The text in the LIs are going to change.
I also need it to be centered. I've made it work with float left and float right, but I need it to be centered.
This is the code I'm currently using for the container DIV and the UL and LI elements:
#container{
height: 100px;
width: 500px;
font-size: 14px;
color: #grey;
display: table-cell;
vertical-align: middle;
}
#container ul{
text-transform: uppercase;
text-align: center;
font-weight: bold;
}
#container li{
background: url(checkmark.png) center left no-repeat;
display: inline;
padding-left: 20px;
margin-right: 5px;
}
#container li:last-child{
margin-right: 0;
}
UPDATED
I got it. Is it this you were looking for?? http://jsfiddle.net/vZNLJ/20/
#wrapper {
background: #ccc;
margin: 0 auto; /* to make the div center align to the browser */
padding: 20px;
width: 500px; /* set it to anything */
text-align: center;
}
#wrapper ul {
background: #aaa;
padding: 10px;
display: inline-block;
}
#wrapper ul li {
color: #fff;
display: inline-block;
margin: 0 20px 0 0;
}
#wrapper ul li:last-child {
color: #fff;
display: inline-block;
margin: 0;
}
<div id="wrapper">
<ul>
<li>Menu</li>
<li>Menu</li>
<li>Menu</li>
</ul>
</div>
This is an old post, but what you can do now is:
<div style="display: flex; justify-content: center;">
<div style="display: inline-block;">
<input type="button" value="Example Button" />
</div>
</div>
The problem isn't wrapping the DIV around the content, but getting the content to state it's actual size, therefore pushing the DIV boundaries out. There are several things that need to be considered when tackling this issue. Not just from an existing UL or LI tag, but a DIV within a DIV.
I use custom tags to help describe layouts cleaner. Custom tags are DIV tags, thus their properties must be manipulated by CSS in order to get the proper behavior.
<layout-linear horizontal>
<control-label>Label 1</control-label>
<control-label>Label 2</control-label>
<control-label>Label 3</control-label>
<control-label>Label 4</control-label>
<control-label>Label 5</control-label>
</layout-linear>
This layout suggests that the contents .. the control-label(s) tags .. will be display in a horizontal row. To get the border for the layout-linear tag to wrap around the content of the control-label tags, there are several things to do:
layout-linear[horizontal]
{
display : block;
box-sizing: border-box;
border : 1px solid black;
padding : 1px 1px 1px 1px;
white-space: nowrap;
width : 100%;
clear : both;
text-align : center;
}
First, the box-sizing property must be set to border-box. This will force the linear-layout (DIV) tag to wrap around content. Padding, Border, Margin will insure that an empty DIV tag displays. Other tricks to make an empty DIV tag display are to use or :after { content:.; visibility: hidden; }.
If you don't want the control-label tags to wrap, adding white-space : nowrap.
I will discuss text-align when I discuss the float property of the control-label tag.
The next part requires the inner DIV tags (control-labels) to properly specify their box-sizing type and borders.
control-label
{
display : inline-block;
/* float : left; */
box-sizing: border-box;
border : 1px solid black;
margin : 5px 5px 5px 5px;
padding : 5px 5px 5px 5px;
}
Display : inline-block, causes the control-label tags to flow left to right. Display : Block, will cause the tags to stack up vertically.
Float is commented out specifically to draw your attention to the fact that float will cause the layout-linear tag shrink to its smallest box size, based on the margins, padding, and border.
To have the control-labels flow right to left, add text-align : right to the layout-linear tag. Or in this specific case, set text-align : center.
Again, box-sizing is used to tell the control-label (DIV) tag to wrap around it's content completely. Not just the text, but the edges of the box as drawn by the border, padding and margin settings.
This arrangement of CSS properties is what causes the outer and inner boxes to be rendered properly, or as expected.
Happy Coding.
You didn't supply code, but take a look at this fiddle I just setup, which might help:
http://jsfiddle.net/qXDJr/
Please let me know if I'm misunderstanding what you mean. Example code will always help for future reference.
This might help.
If you cant set the width you can just add align='center' in the div wrapping ul
<div align="center">
<ul>
<li>MenuItem</li>
<li>MenuItem</li>
<li>MenuItem</li>
</ul>
</div>
How can I show only the border of a div, but not the text using CSS?
This is not well supported by IE, but you could use:
#mydiv { color:rgba(0,0,0,0); border:1px solid #000 }
This makes the text color fully transparent, but leaves the border visible.
A simple cross-browser solution is the Phark "text indent" method. It's usually used for image replacement.
div.example {
border: 2px solid red;
/* Hide text inside "off left" */
text-indent: -10000px;
/* Make sure to set a width and height */
height: 100px;
width: 100px;
}
Pros:
Doesn't need any extra elements
Works in screen-readers
Cons:
Doesn't work in IE5
You can make the text the same color as the div's background. Or nest the text inside another div.