I have a web page which looks like this :
I would like to know if it is possible to have different margin-top value for the 2 outer divs. At the moment, whether I set margin : x% or margin : [value]px both outer div will receive the value from the margin. I would like it to affect only the one I set.
I mention without float because I was having problem with float and margin / width properties, but if you can come up with a proper solution using float, that'll float my boat. :)
Thanks a lot.
I'm a CSS newbie by the way so be easy on me
do you mean something like this ?
JSFIDDLE
html
<div class="container">
<div class="aaa">first</div>
<div class="bbb">second</div>
<div class="ccc">third</div>
</div>
<div class="container">
<div class="aaa">first</div>
<div class="bbb">second</div>
<div class="ccc">third</div>
</div>
css
div:not(.container){
margin: 10px 20px 30px 20px;
background: white;
height: 100px;
}
.container{
float: left;
background: black;
padding: 20px;
width: 200px;
margin-top: 25px; /*sets both divs same top*/
}
.container:not(:first-child){
margin-left: 50px;
/*margin-top: 25px*/ /*sets only second div or all others down and leaves
the first div like it is. but this for you have to
delete the margin-top entry from .container{ */
}
but actually i would use diffrent classes for this so you can set every div with his own css configuration :)
like:
.myFirstDivContainer{
/* pos data here */
}
.mySecondDivContainer{
/* pos data here */
}
and so on
EDIT
see :not() compabilitys
you can also use :nth-child() like
div.container:nth-child(0){
/* data for your first div */
}
div.container:nth-child(1){
/* data for your second div */
}
and so on...
you can use multiple css classes in the class attribute on an html element:
<div class="outer-div-wrapper">some content</div>
<div class="outer-div-wrapper larger-margin">some content</div>
then put in place some css rules:
/* this will give all divs with class 'outer-div-wrapper' a margin-top of 10px */
.outer-div-wrapper {
margin-top: 10px;
display: inline-block;
margin-right: 10px;
}
/* This will increase the margin size for the divs with the extra 'larger-margin' class */
.outer-div-wrapper.larger-margin {
margin-top: 15px;
}
Something just as good as margin-top in your case might be:
.second-div {
position: relative;
top: 15px;
}
This will move the second div 15px down relative to its default position.
BTW, you should get used to JSFiddle, it's a very good prototyping tool, and far better than making non-interactive drawings :)
Here's your drawing as a fiddle!
Related
I can not understand how css works, and it's annoying me. I was trying to do some basic side by side two divs and one div below them.
At first I've learned that I had to give float:left for both side by side divs. For curiosity I did'nt gave float:left for the second side by side div, and I came across this layout:
(source: imge.to)
Then I gave float:left for the second side by side div, and I came across this layout:
(source: imge.to)
Question: I didn't gave float:left for third div but it didn't act like the first screen shot. Why?
css code:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 1000px;
margin-left: auto;
margin-right: auto;
}
.blog-posts {
width: 50%;
background-color: #0000ff;
float: left;
}
.other-posts {
width: 25%;
background-color: #00ff00;
float: left;
}
.author-text {
background-color: #ffff00;
}
html code:
<div class="container">
<div class="blog-posts">dend endje denjde akdlsd gsjgıdg sadsujrg spsadnajd asdnsajdd</div>
<div class="other-posts">extra dummy text</div>
<div class="author-text">author text</div>
</div>
When you use a float, you break the natural box-model behavior of the markup.
Your first floated element has a width of 50%, relative to the parent (1000px) it will take the half of the .container. The second (floated) element will take the next 250px. And here comes the good thing.
The third element, which isn't floated, is also a div, thus a block-level element (so implicitly it will take 100% of the width of its parent). If you set the background-color of your first and second element to a transparent one #0000ff00 and #00ff0000 respectively. You will see your third element is growing behind them.
This is, what I mean with "breaking the box-model". Now, to understand this beter, you could start giving a explicit width to the third element. Let's say: 90%, you will see how the yellow background will reduce itself from the right side.
If you set the width to 50% it will "jump" down, to the second line. It will be even broad as the first element, but two times height. With other words, it will try to fit in the first available space.
To avoid this, in the past, we used the clearfix hack... but since flexbox and css grids are broadly supported, we don't have to rely in floats anymore for this side-by-side layouts.
Float has their own use cases, is not that float sucked, it's just not meant for layout.
For more information on this topic you can check this great article about floats on CSS-Tricks.
Wrap the items you want side by side in another wrapper, then apply flexbox to that wrapper:
.my-flex-wrap {
display: flex;
}
Then remove all the floats. Done.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 1000px;
margin-left: auto;
margin-right: auto;
}
.my-flex-wrap {
display: flex;
}
.blog-posts {
width: 50%;
background-color: #0000ff;
}
.other-posts {
width: 25%;
background-color: #00ff00;
}
.author-text {
background-color: #ffff00;
}
<div class="container">
<div class="my-flex-wrap">
<div class="blog-posts">dend endje denjde akdlsd gsjgıdg sadsujrg spsadnajd asdnsajdd</div>
<div class="other-posts">extra dummy text</div>
</div>
<div class="author-text">author text</div>
</div>
I have the following part of my html
<div class="header">
<div class="header-bar">
<div class="pull-left">
<div class="title">Ci models database</div>
</div>
</div>
<div class="clear-both"></div>
<ol class=breadcrumb>
<li class="active">All models</li>
</ol>
</div>
the css(breadcrumb and active classes are bootstrap)
.header-bar {
border: None;
background-color: #66CCFF;
min-height:30px;
}
.title {
padding: 5px 5px 10px 5px;
color: white;
font-size: large;
}
.clear-both{
clear:both;
}
But between header-bar and breadcrumb html added a white space(see bootply). How can I remove this white space, since no padding and margin can be found between to divs.
The problem is that the calculated height of the internal .title div is greater than the calculated height of the container .header-bar. Properties like height, min-height, border, padding can directly effect heights, whereas properties like display, box-sizing and position can all indirectly effect height.
The result is the internal .title div pushes down the next div in the flow by 10px.
CSS has no rules that say a div must contain it's children in height and stop them from effecting other divs, even when height is directly defined. We need to tell it exactly how it should behave when things are rendered.
There are several ways to fix this:
http://www.bootply.com/Qa1ME2M2uk - use overflow: hidden; on the parent. Overflow is a css property which is used how to control what happens when child elements are larger than their parents. It's worth noting that depending on other properties overflow won't necessarily render itself in a way that disrupts layout.
http://www.bootply.com/ssq3EAzeyk - set explicit heights to take strict control over the dimensions of the elements. This might be the best option for a header bar.
http://www.bootply.com/yeodYRLLJk - set a greater min-height on the parent, one which will definitely contain the child. This is useful if your padding is for alignment purposes - setting min-height: 40px; in the example does this.
http://www.bootply.com/GznfJxUWUF - remove the padding that is making the element calculate as taller (as mentioned in another answer).
Apostolos, the white space is coming from the .titleclass.
The bottom padding of 10px.
Zero this and the white space will go.
.title {
padding: 5px 5px 0px 5px;
you will have to add a float: left to both parent containers (.header-bar and breadcrumb) otherwise the clear won't affect anything. furthermore you will have to give both containers width: 100%
.header-bar {
border: None;
background-color: #66CCFF;
min-height:30px;
width: 100%;
float: left;
}
.breadcrumb {
width: 100%;
float: left;
}
.title {
padding: 5px 5px 10px 5px;
color: white;
font-size: large;
}
.clear-both{
clear:both;
}
I have one requirement, where I need to apply width to the parent element which is equal to the first child element's width. This can be easily achieved using display: inline-block or float: left to the parent element if it has only one child element. But I have more than two child elements in a div. Something like this:
Fiddle
<div class="main">
<div class="first">first</div>
<div class="value">valuevalue</div>
</div>
Right now, If I apply display: inline-block to the parent element, then it is having the width of the second child element.
To not happen this, I tried break-word, word-break css properties on the second child element but still no use.
What I am trying to get is illustrated in the following screenshot:
Some important points:
width of the parent element should be equal to the first child element.
height of the parent element should be equal to sum of all the child elements.
I don't know the width of the first child element.
(EDIT) The first child element has some fixed width and height. I don't know these values.
I want to do this using just css. css3 is welcome. (I know how to do this using javascript)
You can Achieve this easily with CSS3's new intrinsic and extrinsic width values(min-content in this cas), although, it's not supported on IE, so it's not an viable option but I will just post this as it's interesting that we will be able to do that in the future:
http://jsfiddle.net/S87nE/
HTML:
<div class="main">
<div class="first">first</div>
<div class="value">valuevaluevalue</div>
</div>
CSS:
.main {
background-color: cornflowerblue;
width: -moz-min-content;
width: -webkit-min-content;
width: min-content;
}
.first {
width: 50px; /* I don't know this width */
height: 50px; /* I don't know this height */
background-color: grey;
}
.value{
word-break: break-all;
}
I guess in the worst case you could use this for newer browsers and JS for IE and older versions.
Reference:
http://dev.w3.org/csswg/css-sizing/#width-height-keywords
http://demosthenes.info/blog/662/Design-From-the-Inside-Out-With-CSS-MinContent
Ideally, the layout style for a HTML snippet like:
<div class="main">
<div class="first">first</div>
<div class="value">firstvaluevalue</div>
<div class="value">second value value</div>
<div class="value">third valuevalue</div>
<div class="value">valuevalue on the fourth line</div>
</div>
is achievable using the following CSS:
.main {
display: inline-block;
background-color: cornflowerblue;
position: relative;
width: 50px;
}
.first {
width: 50px; /* I don't know this width */
height: 50px; /* I don't know this height */
background-color: grey;
}
.value {
word-break: break-all;
margin: 1.00em 0;
}
as shown in: http://jsfiddle.net/audetwebdesign/tPjem/
However, I had to set the width of .main to that of the .first element in order to get the word-break property to take effect.
The CSS rendering problem here is that you want the width of the .value siblings to be equal to the unknown width of .first, which cannot be done with CSS alone.
CSS rendering is essentially a one-pass top-to-bottom algorithm which means that parent elements cannot inherit values from child elements (tables have a multi-pass algorithm but this won't help in this case). This may change in future versions of CSS, but for the we need to design according to these limitations.
The JavaScript/jQuery solution is to get the width from .first and apply it to .main and bind that to a window re-size action.
In some ways, this problem seems to make sense if .first contains an image which would have an intrinsic height and width. If this were the case, it might make sense to set the width of .main to a reasonable value and then scale the image in .first to fill the width of the .main block.
Without knowing more about the actual content, it is hard to come up with alternatives.
Look at my latest comment for the Fiddle link. I changed some things in the html too. Did set the value div inside the first div to use it's width and added word-wrap to the value div.
.main {
display: inline-block;
background-color: cornflowerblue;
position: relative;
}
.first {
width: 50px; /* I don't know this width */
position: relative;
background-color: grey;
}
.first p {
margin-bottom: 30px;
margin-top: 0;
}
.value {
max-width: 100%;
word-wrap:break-word;
background-color: cornflowerblue;
}
html:
<div class="main">
<div class="first">
<p>first</p>
<div class="value">valuevalue</div>
</div>
</div>
http://jsfiddle.net/jxw4q/12/
Important
this answer may not be useful for you, but can help other user who have a similar problem.
you can have the same look as you desire, but without really stretching the parent height. by using position:absolute; on the second div.
Notice: if the parent don't really stretch, it causes problems.
for example, content that will come directly after the parent, will be showed after the .first element. causing an overlap.
you still can use this for cases where this is the only content in the page, and you want the second div to adjust his width to the first.
(I don't think that this is your case, but maybe it will help other user who might stumble into that question.)
anyway, I think that your only option is to use a Script.
For those who fall under the use-case I've described, Here's a Working Fiddle
HTML: (no changes here)
<div class="main">
<div class="first">First div set the width</div>
<div class="value">second fiv should wrap if bigger then first</div>
</div>
CSS:
.main
{
display: inline-block;
position: relative;
}
.first
{
background-color: gray;
}
.value
{
position: absolute;
background-color: cornflowerblue; /* moved here */
}
I don't think you will be able to achieve it without a little help of javascript. Imagine the the following markup and css :
<div class="main">
<div class="first content">first</div>
<div class="second content">valuevalue</div>
</div>
and then the following css :
.main{
background-color : red;
display: inline-block;
max-width: 50px;
}
.first{
background-color : blue;
}
.second{
background-color : green;
}
.content{
word-break: break-word;
}
Now all you gotta do is to set the max-width of your .main div to be equal to your first element and add the content class to each element. I suppose you are adding your elements dynamically.
I got the solution!!
HTML
<div class="main">
<div class="first">first</div>
<div class="value">valuevalue</div>
</div>
CSS
.main {
overflow:hidden;
width:1px;
display:table;
background-color: cornflowerblue;
}
.first {
width: 50px; /* I don't know this width */
height: 50px; /* I don't know this height */
background-color: grey;
display: inline-block;
}
.value {
word-break: break-all;
}
Working Fiddle
Related link
I have some css:
.note {
background: red;
}
.note > div {
max-width: 780px;
margin: 0px auto;
position: relative;
padding-left: 20px;
border: 1px solid black;
}
.note > div:before {
content: '⚠';
position: absolute;
left: 0px;
}
And a corresponding html like:
<div class='note'><div>Foobar</div></div>
This creates a red line across the screen, but the content will be only in the center area. It works well so far. But I want the whole content to be in a 800px width area, so I add a container:
#container {
max-width: 790px;
margin: 0 auto;
background: green;
border-radius: 10px;
padding: 5px;
}
And some html:
<div id='container'>
<p>Lorem ipsum</p>
<div class="note"><div>foo</div></div>
<p>Foobar</p>
</div>
Of course, note won't work here (the red line doesn't extend beyond the green container). I've been trying to come up with something, but I couldn't. I can't just close the container, place my note, and open another because border-radius and (and also box shadow, but I left it out from the example) would break then. Using a negative margin on .note also doesn't work, because it adds horizontal scrollbars. I could make .note position: absolute;, but then my note would overlap whatever comes after it.
Any ideas how could I solve it?
Update: Here's a JSFiddle. The second version is what I actually want, except that it creates a vertical scrollbar. The third is like Robert's solution, and the only problem is that it takes the div out of flow, and I'd like to avoid hacks like adding a margin-top to the following element because I don't know the length of the note in advance.
.note {
background: red;
position: absolute;
left:0;
right:0;
}
Here's a jsfiddle:http://jsfiddle.net/ySVZb/
Note that I changed some widths so it's easier to see in the jsfiddle screen, but the size is irrelevant. Also note that because I've taken the note div outside the normal flow, you will need to add an appropriate margin to anything that follows or it will fall behind the note div. Some generic like .note + * {margin-top: 2em} will work in some cases, but it will override any margin top already on that element, in those cases you'll need a more specific fix like .note + p {margin-top: 3em;} jsfiddle showing that here: http://jsfiddle.net/ySVZb/1/
I'm trying to get my horizontal rule to ignore the parent padding.
Here's a simple example of what I have:
#parent {
padding:10px;
width:100px;
}
hr {
width:100px;
}
You will find that the horizontal rule extends out of the parent by 10px. I'm trying to get it to ignore the padding that everything else in the parent div needs.
I'm aware that I could make a separate div for everything else; this is not the solution I'm looking for.
Easy fix, just do
margin:-10px
on the hr.
For image purpose you can do something like this
img {
width: calc(100% + 20px); // twice the value of the parent's padding
margin-left: -10px; // -1 * parent's padding
}
In large this question has been answered but in small parts by everyone. I dealt with this just a minute ago.
I wanted to have a button tray at the bottom of a panel where the panel has 30px all around. The button tray had to be flush bottom and sides.
.panel
{
padding: 30px;
}
.panel > .actions
{
margin: -30px;
margin-top: 30px;
padding: 30px;
width: auto;
}
I did a demo here with more flesh to drive the idea. However the key elements above are offset any parent padding with matching negative margins on the child. Then most critical if you want to run the child full-width then set width to auto. (as mentioned in a comment above by schlingel).
Another solution:
position: absolute;
top: 0;
left: 0;
just change the top/right/bottom/left to your case.
Kinda late.But it just takes a bit of math.
.content {
margin-top: 50px;
background: #777;
padding: 30px;
padding-bottom: 0;
font-size: 11px;
border: 1px dotted #222;
}
.bottom-content {
background: #999;
width: 100%; /* you need this for it to work */
margin-left: -30px; /* will touch very left side */
padding-right: 60px; /* will touch very right side */
}
<div class='content'>
<p>A paragraph</p>
<p>Another paragraph.</p>
<p>No more content</p>
<div class='bottom-content'>
I want this div to ignore padding.
</div>
I don't have Windows so I didn't test this in IE.
fiddle:
fiddle example..
If you have a parent container with vertical padding and you want something (e.g. an image) inside that container to ignore its vertical padding you can set a negative, but equal, margin for both 'top' and 'bottom':
margin-top: -100px;
margin-bottom: -100px;
The actual value doesn't appear to matter much. Haven't tried this for horizontal paddings.
margin: 0 -10px;
is better than
margin: -10px;
The later sucks content vertically into it.
Here is another way to do it.
<style>
.padded-element{margin: 0px; padding: 10px;}
.padded-element img{margin-left: -10px; width: calc(100% + 10px + 10px);}
</style>
<p class="padded-element">
<img src="https://images.pexels.com/photos/3014019/pexels-photo-3014019.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940">
</p>
Here are some examples on repl.it: https://repl.it/#bryku/LightgrayBleakIntercept
Your parent is 120px wide - that is 100 width + 20 padding on each side so you need to make your line 120px wide. Here's the code. Next time note that padding adds up to element width.
#parent
{
width: 100px;
padding: 10px;
background-color: Red;
}
hr
{
width: 120px;
margin:0 -10px;
position:relative;
}
If your after a way for the hr to go straight from the left side of a screen to the right this is the code to use to ensure the view width isn't effected.
hr {
position: absolute;
left: 0;
right: 0;
}
The problem could come down to which box model you're using. Are you using IE?
When IE is in quirks mode, width is the outer width of your box, which means the padding will be inside. So the total area left inside the box is 100px - 2 * 10px = 80px in which case your 100px wide <hr> will not look right.
If you're in standards mode, width is the inner width of your box, and padding is added outside. So the total width of the box is 100px + 2 * 10px = 120px leaving exactly 100px inside the box for your <hr>.
To solve it, either adjust your CSS values for IE. (Check in Firefox to see if it looks okay there). Or even better, set a document type to kick the browser into strict mode - where also IE follows the standard box model.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
...
http://www.quirksmode.org/css/quirksmode.html
You just need to add negative margins to the child that match the padding of the parent. No need to set a width, change the box-sizing, or use absolute positioning.
#parent {
padding: 10px;
width: 100px;
}
hr {
margin-right: -10px;
margin-left: -10px;
// For modern browsers you can use margin-inline: -10px
}
The reason you don't need to set a width is because the hr element is a block element. It's width defaults to "auto", which means it will expand to fill it's parent (minus padding, margin, and border).
easy fix.. add to parent div:
box-sizing: border-box;