CSS specificty issue - html

I have a nested div like this
<div class="myDiv">
<div class="myOtherDiv">
In my CSS I want myOtherDiv to have margin: 0 auto; but not myDiv
If I write
.myDiv{
margin: 0 auto;
}
It applies to both with the specificty of 0,1,0
But
.myDiv .myOtherDiv{
margin:0 auto;
}
Nothing happens. Which is weird, visual code reports the specificity of this to be 0,2,0 which is higher so should it not apply?

As you have not provided all of the CSS code it is hard to tell. However,
Issues with margin: 0 auto;
are you usually a result of the element not being a block element or contain a width.
Since div is a block element naturally, it takes up the entire width available even if you only have 1 letter inside that div(I.e <div>A</div>
You must declare a width before centering your div items.
So for example:
.myDiv {
width: 50%;
margin: 0 auto;
}
Im regards to specificity,
If the parent <div> doesn't have a width assigned margin:0 autowill not do anything. However, if you assign a width then the block will not occupy all the page's space, and then the block itself is centered, but the items of the child div will not be centered or affected.
If you assign both the child and parent div margin:0 auto without either having a set width it will produce a null effect without affecting positioning at all because each block is just taking up all the space possible within the page.
If you want the child div block centered, then assign a width to the child div, and leave the parent div alone. Since the parent occupies all the page's width space, the child div will be centered on the page using margin:0 auto; and the width you assigned.

.myDiv .myOtherDiv {} or just .myOtherDiv {} should be good to target myOtherDiv.
Did you give the div a width? Block level elements like div's default to 100% widht of their parent. So you need to set a specific smaller width, or use display: table; so the content decides the width. See below:
.myDiv{
background: blue;
}
.myOtherDiv{
margin: 0 auto;
display: table;
background: red;
}
<div class="myDiv">
<div class="myOtherDiv">content
</div>
</div>

Related

Padding missing on one side of scrollable div

Take a look at my snippet.
The parent div has a scrollbar and a child div.
Why is the padding (5px) missing on the right side?
#moh
{
background:red;
overflow-x:auto;
width:100px;
padding:5px; // this padding should be on all 4 sides
}
#moh div
{
width:500px;
height:50px;
background:green;
}
<div id="moh">
<div></div>
</div>
To get the bounty I want to know the reason for the missing padding. Maybe there is a name for this phenomenon. Or may it be a browser bug?
It would be excellent to know the part in the CSS or HTML specification which is responsible for the missing padding. But this is not required to get the bounty (Because I know it's hard to find).
#moh
{
background:red;
overflow-x:auto;
width:100px;
padding:5px;
}
#moh div
{
/* width:500px; */
height:50px;
background:green;
}
<html>
<head>
</head>
<body>
<div id="moh">
<div></div>
</div>
</html>
The padding on the right hand side doesn't appear because, the total width of the parent div is 100px(width) + 10px(padding) while the width for the chid div is explicitly set to 500px.
Since the chid div is a block level element and width property greater than that of the parent, it will move past the parent element and hide the right border from the parent div.
Solutions
either remove the width attribute in the child div (so it will take full width of the parent)
or set the width of the parent to at least 500px which is the width of the child element
The reason for this can tell. It's hard to explain, but I'll try. Your" moh " div width value is 100px," moh " in the div width value is 500px. The order of items on Pages is normally left to right. If you do not apply overflow, you see the overflowing sections :
#moh {
background: red;
width: 100px;
padding: 5px; // this padding should be on all 4 sides
}
#moh div {
width: 500px;
height: 50px;
background: green;
}
<div id="moh">
<div></div>
</div>
As you can see, there's an overflow from left to right. when you give overflow, The Overflow will be hidden automatically. So where's the overflow ? (left ? right ? ) That's why it will try to hide everything from the overflow, that is, the part that goes out when it doesn't fit. The part he's trying to hide is in the padding, so that part doesn't show up.
I'm sorry if I said anything that would be misunderstood. Maybe I helped you understand a little bit.
It happens because #moh is 100px and the inner div is 500px. The solution is to set them both to 500px and wrap them with a 3rd div that is limited to 100px with overflow-x.
#wrapper {
overflow-x: auto;
width: 100px;
}
#moh {
background: red;
width: 500px;
padding: 5px; // this padding should be on all 4 sides
}
#moh div {
width: 500px;
height: 50px;
background: green;
}
<div id="wrapper">
<div id="moh">
<div></div>
</div>
</div>
#wrap
{
overflow-x:auto;
width:100px;
}
#inner
{
background:red;
padding: 15px;
width: 500px;
}
#inner div
{
width:500px;
height:100px;
background:green;
}
<div id="wrap">
<div id="inner">
<div></div>
</div>
</div>
one solution would be this:
I had to add some more HTML but hope it solves your problem
It's because of the html behavior of block element like DIV and css overflow property.
By default html elements flow from left to right.
Browsers by Default behavior is -
If parent DIV have any width property (or specific width
inherited) and no css overflow rule is defined, and if child DIV
have defined width which is more than the parent can accommodate,
then it will overflow and will grow beyond the right edge of parent.
To control how Parent Div will deal with overflowing, css overflow
property can be used. overflow:hidden will instruct browser to crop
the exceeding width div at the edge.
overflow-x:auto will instruct browser that, when child element
exceeded width beyond the edge then add scrollbar at x-axis.
So, in the example case above, the child div is having greater width than parent and it is exceeding of the parent. And parent div is having 'overflow-x:auto' rule defined, the scrollbar is appearing upto the edge of parent.
Since padding is inside the edge of the div, it does not considered.
If you want to have padding on all side of the parent div.
Treat the parent div as a grandparent by adding one more div inside a parent and moving child div in it.
On grandparent div you can add required padding and width.
3 On new parent set width:100% which will expand to fit in a grandparent and setting overflow-x:autorule will add scrollbar when the child div expand beyond the parent width.
So, the code will be something like -
#moh
{
background:red;
width:100px;
padding:5px; // this padding should be on all 4 sides
}
#moh div
{
width:500px;
height:50px;
background:green;
}
div{
box-sizing:border-box;
}
#moh div.moh-container{
width:100%;
overflow-x:auto;
}
<!-- Grand parent Div for padding and width -->
<div id="moh">
<!-- Parent Div width 100% to fit in grandparent and overflow rule -->
<div class='moh-container'>
<!-- child element with exceeding width -->
<div></div>
</div>
</div>
Fiddle -
https://jsfiddle.net/guruling/471ka569/13/

Force elements to always be inside a DIV

One thing I always seem to fight within web development is keeping things inside a div element. I often run into issues where I have a list of div wrappers with more divs and content within, and eventually, one of them bleeds out and causes a nightmare when it comes to styling. An example if I may.
If you inspect the element you'll notice the banner-content div doesn't wrap all of the content. The images and span elements are outside of it's reach, even so the icon-wrapper content does (once again) wrap around everything. I believe I know that the answer to that one (the img height is set to 100%).
It doesn't seem that big of a problem now, but when trying to align things with much more content and forms and responsive design, it gets kinda crazy. It almost feels like I'm adding some hacky code to make it all form nicely. Realistically it seems like everything stayed within my parent div sizes and elements, everything would behave as expected.
Is there a way to force divs to contain all the child node's within its reach?
.wrapper {
width:100%;
display:flex;
flex-direction:column;
}
.cool-banner {
display:flex;
height:60vh;
}
.banner-picture {
width:50%;
}
.banner-picture img {
object-fit: none;
object-position: center;
height: 100%;
width: 100%;
}
.banner-content {
display:flex;
flex-direction: column;
height:100%;
}
.icon-list {
display:flex;
}
.icon-wrapper {
display:flex;
flex-direction:column;
height:40vh;
}
.icon-wrapper img {
object-fit: contain;
object-position:center;
width:100%;
height:100%;
}
<div class="wrapper">
<div class="cool-banner">
<div class="banner-picture">
<img src="https://cdn.shopify.com/s/files/1/1150/2512/files/WG_Grill_ShootBeside_Oct2017-7_dd4f32ad-38ac-4a49-8a3c-332ba067835e_810x540.jpg?v=1553613536"/>
</div>
<div class="banner-content">
<h1>I'm Content</h1>
<div class="icon-list">
<div class="icon-wrapper">
<img src="https://cdn.shopify.com/s/files/1/1150/2512/t/41/assets/fire-silver.png?51152"/>
<span>Nice Fire</span>
</div>
<div class="icon-wrapper">
<img src="https://cdn.shopify.com/s/files/1/1150/2512/files/EPDA-Logo-small_x100-ConvertImage_small.png?v=1559164248"/>
<span>Nice Award</span>
</div>
</div>
</div>
</div>
If I'm understanding the question, there are a number of ways to constrain children so that they don't extend outside of their parent.
If you set overflow: hidden on the parent, children that are wider or taller than the parent will clip at the edges of the parent, though their width will remain the same.
You can set max-width: 100% on children to keep them from growing wider than the parent's width.
You can also set display: flex on the parent and min-width: 0 on the children to constrain children to the parent.
Things get a little dicier if you need to constrain heights, because children typically only respect their parent's height if the parent's height is explicitly set.
Sometimes you just cant fit your size 10 foot into a size 7 shoe.
That image takes up 50%, while not having enough real estate for the other column's content. Case in point - In your example, removing the flex-direction:column of .banner-content wraps all children as you may have intended

Set same width to multiple vertical elements, according to widest one

I have a container containing multiple elements with a min-width and some padding to the right and left, the problem is in need them centered and in a column with each one in a separate row, the content of each one of them differs, causing the elements to have different width, like this
+--------- container ---------+
|child1 is too long|
|child2|
|child3 is long|
|child4|
+-----------------------------+
how can I make them all have the width of the largest element while maintaining a max-width in the same time, i.e. if the content gets too long, it breaks down to the next line while maintaining the width.
Attached below a screenshot, the above is the current situation, the one below is the desired result
You can wrap the items with a display:inline-block element,
and wrap that element in a text-align:center element so it would be centered:
.centered{ text-align:center; }
.wrapper{
display: inline-block;
font: 24px Arial;
text-align: left;
}
.wrapper > div{
border: 2px dashed pink;
margin-bottom: 4px;
}
<div class='centered'>
<div class='wrapper'>
<div contenteditable>try typing here</div>
<div contenteditable>aaaaa</div>
<div contenteditable>aaaaa aaaaa</div>
<div contenteditable>aa</div>
<div contenteditable>aaaaaaaaa</div>
</div>
</div>
The inner children are block level elements (<div>) which means they will take the whole width of their parent element, where the parent is an inline-block. This will result the parent is as wide as the widest child.

Div doesn't have height

Why does wrapper div not have a height? If I set the height (height:200px) the green background appears but how to set with auto height?
Here is my code (JSFiddle):
HTML:
<div class="wrapper">
<div class="effect"></div>
<div class="content">
...content
</div>
</div>
CSS:
.content {
position: absolute;
background-color:red;
}
.wrapper, .effect {
background: green;
}
.wrapper {
position: relative;
width: 630px;
}
.effect {
width:100%;
position: absolute;
}
It is not working (i.e. parent element not having any height) because all the immediate descendant of the .wrapper element is absolutely positioned — this will have the effect of taking them out of the flow of the document, therefore causing the parent's dimension to collapse to nothing.
You will also notice that the effect is the same when you float all
descendants of the parent wrapper, because float also has the
effect of taking normal elements out of the document flow.
There are only two ways to prevent this from happening, both of which involving declaring a certain height for the parent .wrapper element:
Either you explicitly state a height for the parent (see example fiddle)
Or use a relative height (say, in percentages or viewport units) that is not dependent on its own content.
You should reconsider your design strategy, and what you're trying to achieve. There is probably other ways to achieve what you intend to do, will you mind showing us?

CSS alternative to center

People frown upon the center tag, but for me it always works just the way I want it. Nevertheless, center is deprecated so I'll make an effort.
Now I see many people suggest the cryptic CSS margin: 0 auto; but I can't even get it to work (see fiddle here). Other people will go modify position or display, but that always breaks something else.
How can I center a span using css so that it behaves exactly like the center tag?
<div class="container">
<span class='btn btn-primary'>Click me!</span>
</div>
Span is an inline element, and the margin: 0 auto for centering only works on non-inline elements that have a width that is less than 100%.
One option is to set an alignment on the container, though this probably isn't what you want for this situation:
div.container { text-align: center }
http://jsfiddle.net/MgcDU/1270/
The other option is to change the display property of the span:
/* needs some extra specificity here to avoid the display being overwritten */
span.btn.btn-primary {
display: table;
margin: 0 auto;
}
Using display: table eliminates the need to hard code a specific width. It will shrink or grow as appropriate for its content.
http://jsfiddle.net/MgcDU/1271/
You can set .container { text-align:center; } so that everything inside div.container will be centered.
In general, there are two ways centering things.
To center inline elements (such as text, spans and images) inside their parents, set text-align: center; on the parent.
To center a block level element (such as header, div or paragraph), it must first have a specified width (width: 50%; for example). Then set the left and right margins to auto. Your example of margin: 0 auto; says that the top and bottom margin should be 0 (this doesn't matter for centering) ad that the left and right margins should be auto - they should be equal to each other.
The <center> element is really just a block-level element with text-align:center;. If you sent border: solid red 1px; on it, you can see that it's 100% wide, and that everything inside it is centered. If you change text-align to left, then its children are no longer centered. Example: http://jsfiddle.net/KatieK/MgcDU/1275/. Perhaps you should just consider your <div class="container"> with text-align:center; } to be equivalent to <center>.
You make the span block level, give it a width so margin:auto works
see this fiddle
.center {
display:block;
margin:auto auto;
width:150px; //all rules upto here are important the rest are styling
border:1px solid black;
padding:5px;
text-align:center;
}
UPDATE: In order to NOT specify a width and have natural width of element on the span you will have to use textalign on parent
see this fiddle
.container{text-align:center}
.center {
border:1px solid black;
padding:5px;
}
<span> is an inline element. <div> is a block element. That's why it is not centering.
<div class="container" style='float:left; width:100%; text-align:center;'>
<span class='btn btn-primary'>Click me!</span>
</div>
You can center the content of span only when you convert it into block, using 'inline-block' style.
Your parent element needs to have a larger width in order to let a child element be positioned within it. After that the trick with margin: 0 auto; is getting the parent and child container position and display values to be compatible with each other.
.container {
border: 2px dashed;
width: 100%;}
.btn {
display: block;
margin: 0 auto;
width: 25%;
}
http://jsfiddle.net/rgY4D/2/