Margin effecting center aligned items in flexbox row - html

I'm pretty new when it comes to flexbox but it seems a lot of properties work the same way.
However, when it comes to align items center I'm used to the way inline-block handles margins where it creates a space within the whole row even if it's on a specific element.
With flexbox it seems to only move that element off the axis. Fiddle attached, let me know if I am doing something wrong here. Using bootstrap css with only a few other styles to show what's going on.
https://jsfiddle.net/fv1gm67f/3/
<div id="header-top">
<div class="container">
<div class="row flex-wrap align-items-center">
<div class="header-top-social-media-icons-outer col col-auto">
<nav class="header-top-social-media-icons text-center icons-circle icons-sm">
<ul class="social-media-icons">
<li><i class="fa fa-facebook"></i></li>
<li><i class="fa fa-twitter"></i></li>
<li><i class="fa fa-instagram"></i></li>
<li><i class="fa fa-youtube"></i></li>
<li><i class="fa fa-envelope"></i></li>
</ul>
</nav>
</div>
<div class="header-top-menu-outer col col-auto">
<nav class="header-top-menu">
<ul id="menu-header-top-menu" class="menu">
<li>My Account</li>
<li>Sample Page</li>
<li>Blog Posts</li>
</ul>
</nav>
</div>
</div>
</div>

If i understood you correctly. You want to keep the 2 columns aligned vertically automatically. I think you can achieve this with the property align-self:baseline. Please add the following css class to your fiddle and you will see that whether you give margin bottom or top to the icons col, the right column will align itself based on that margin and keep in line.
.col-auto{
align-self:baseline;
}
Hope this answers your question.
[EDIT For More Explaination]
As per your comment you are correct that align-self is for items within flexbox. If you notice then your .flex-wrap class is putting display:flex on main container with has 2 columns child as flex items. And then you have display:flex on the inner nav ul as well which is nested. You needed to set the align-self to baseline for the parent flexbox in order for the 2 col items to align to each other.
Here is a very good article with complete guide to flexbox.
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Hope this explanation gives more info to others as well.
Happy Coding :)

Give your social media icons a margin of 0.
.social-media-icons li {
margin-bottom:0px;
}

As Russell Alan alluded to, it is a box model issue. The padding-top and padding-bottom on the ul.social-media-icons element is throwing the y axis off. The li elements also have a margin-bottom that adds to the issue. The following CSS should fix the issue:
CSS
/*This is so you can get a visual on exactly what the boxes are doing*/
.col-auto {
background-color: #CCC;
border: solid 1px #000;
}
ul.social-media-icons {
padding-top: 0;
padding-bottom: 0;
}
.social-media-icons li {
margin-bottom: 0;
}
jsFiddle
Ultimately, however, I think it might be best to set a min-height on the .row.flex-wrap children.

display: inline-block; margin-bottom: Npx does not affect the centering of other display: inline-block elements within a common parent element.
https://jsfiddle.net/dkoadaya/
I modified your fiddle above to center some inline-block elements and show that the behavior is the same.

Related

Vertically centered text using bootstrap's flex utils not working in IE11

I realize this question has been asked a lot
Example 1
Example 2
Example 3
but my question is different because I have the desired effect working on all browsers except IE11.
I'm aware of the flex auto margin bug, but my layout avoids using those so I don't believe that's the problem.
This is the layout I want to, and do achieve in modern browsers.
This works in Edge, Firefox, and Chrome. But in IE11, this is the result.
Here is the HTML
<div class="container pt-5 pb-5">
<div class="quote-container d-flex flex-column justify-content-center">
<p class="bold-weight extra-large-heading italic text-center">
<i class="fas fa-quote-left quotes mr-2" aria-hidden="true"></i>
Facts are meaningless. You could use facts to prove anything that's even remotely true.
<i class="fas fa-quote-right quotes ml-2" aria-hidden="true"></i>
</p>
<p class="text-muted text-center">– Homer Simpson</p>
</div>
</div>
And here is my CSS although very little of it has to do with the layout. The salmon color is only there to make seeing the container easier.
.quote-container{
min-height:600px;
background:salmon;
}
.quotes {
color:
#FFA300;
}
/*Generic Styles*/
.extra-large-heading {
font-size: 2rem;
}
.italic{
font-style:italic;
}
.bold-weight {
font-weight: 700;
}
I have created a fiddle that recreates this issue.
https://jsfiddle.net/1wztmvo5/1/
If you want to see the issue in IE11, you'll have to use this embed link.
https://jsfiddle.net/1wztmvo5/1/embedded/result,css,html,js
Any help would be really appreciated. I'm pulling my hair out over this one.
You have encount the bug that min-height property is ignored on Internet Explorer 11 with use Flexbox. This bug is listed GitHub's Flexbugs repository.
Flexbug #3
min-height on a flex container won't apply to its flex items
In order for flex items to size and position themselves, they need to know how big their containers are. For example, if a flex item is supposed to be vertically centered, it needs to know how tall its parent is. The same is true when flex items are told to grow to fill the remaining empty space.
In IE 10-11, min-height declarations on flex containers work to size the containers themselves, but their flex item children do not seem to know the size of their parents. They act as if no height has been set at all.
This bug's one of the workaround is wrap the flex container other flex container.
jsFiddle for result check in IE11
.quote-container{
min-height:600px;
background:salmon;
}
.quotes {
color:
#FFA300;
}
/*Generic Styles*/
.extra-large-heading {
font-size: 2rem;
}
.italic{
font-style:italic;
}
.bold-weight {
font-weight: 700;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/js/all.min.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container pt-5 pb-5">
<div class="d-flex flex-column"><!-- Add wrapper flex container -->
<div class="quote-container d-flex flex-column justify-content-center">
<p class="bold-weight extra-large-heading italic text-center">
<i class="fas fa-quote-left quotes mr-2" aria-hidden="true"></i>
Facts are meaningless. You could use facts to prove anything that's even remotely true.
<i class="fas fa-quote-right quotes ml-2" aria-hidden="true"></i>
</p>
<p class="text-muted text-center">– Homer Simpson</p>
</div>
</div>
</div>

Two auto width flexbox columns with only one that wraps

I have two auto width flexbox columns displayed inline. I expect to have dynamic content in the columns so I am trying to figure out a way to wrap only the first column which contains the menu items.
I know I can wrap both of them using the "flex-wrap" class on the "d-flex" div but I only want to wrap the first auto width column while keeping the two columns inline of each other.
I am using Bootstrap 4 CSS which already contains the flexbox classes I am using, please see an example on the fiddle I've provided.
My desired result would be something like this image example:
https://jsfiddle.net/j9v70qvy/
<div id="header-middle">
<div class="container">
<div class="row align-items-center">
<div class="header-middle-mobile-menu-outer col col-auto hidden-md-up">
<a class="header-middle-mobile-menu-toggle">
<i class="fa fa-bars"></i>
</a>
</div>
<div class="logo-outer col col-auto">
<div class="logo-image">
<a href="#">
<img src="https://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&cad=rja&uact=8&ved=0ahUKEwiamcGxuM3VAhUTwWMKHVWaBgMQjRwIBw&url=http%3A%2F%2Fwww.freepik.com%2Ffree-vector%2Flogo-sample-text_701628.htm&psig=AFQjCNEHXsgvhjDI__g4Vk4GETXnCeRu6A&ust=1502481095339508">
</a>
</div>
</div>
<div class="d-flex col pl-0 pr-0 align-items-center justify-content-end justify-content-md-start">
<div class="flex-wrap header-middle-menu-outer col col-auto hidden-sm-down">
<nav class="header-middle-menu">
<ul>
<li>Home</li>
<li>About</li>
<li>Portfolio</li>
<li>Blog</li>
<li>Sample Page</li>
<li>Terms and Conditions</li>
<li>Privacy Policy</li>
</ul>
</nav>
</div>
<div class="header-middle-social-media-icons-outer col col-auto">
<nav class="header-middle-social-media-icons text-center icons-circle icons-sm">
<ul class="social-media-icons">
<li><i class="fa fa-facebook"></i></li>
<li><i class="fa fa-twitter"></i></li>
<li><i class="fa fa-instagram"></i></li>
<li><i class="fa fa-youtube"></i></li>
<li><i class="fa fa-envelope"></i></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
Okay, I think I finally figured out what the deal is. The Bootstrap defaults for some classes you have are different from what you want in this case.
You need to override the default styling for .col-auto on .header-middle-menu-outer. It is the flex-shrink value of 0 in the shorthand flex property that is killing you. Since the columns aren't allowed to shrink, you're getting things pushed off the side of the screen, and no wrapping is happening.
The default flex styling will suffice for .header-middle-menu-outer, so you can just use this in your CSS:
.header-middle-menu-outer.col {
flex: initial;
}
That will set things back to the default of flex: 0 1 auto, which will mean that the left column will be allowed to shrink while the right column will continue not shrinking. So the left column will wrap, and the right won't.
I would say you could simply strip away the col-auto class (which you may do anyway), but then you'd fall back to the styling for .col, which also includes the same problematic style: flex: 0 0 auto. So unless you want to remove that class too, you'll probably have to use an overriding style in your CSS either way.
Updated fiddle.
As a side note, I'd recommend you re-visit which classes you include on each element. If you inspect things in your browser console, you'll see that you have a lot of competing styles being applied by those classes, which aren't helping you out any. For example, .d-flex contains both justify-content-end and justify-content-md-start, which do exactly the opposite thing. But in this case, I believe you need neither. In the fiddle I linked above, if you delete both those classes, the layout doesn't change at all.
Also, the classes col-auto and col are very similar. In the case above for .header-middle-menu-outer, even though removing col-auto won't fix your problem, you might do it anyway because I'm not sure that class is really adding anything at this point.
I suspect there are many classes you could eliminate and then if there is a certain style rule for one of those removed classes that you want to include, just drop that in your stylesheet as a one-off.

Flexbox difficulties aligning icons to bottom of container

I'm having some difficulties with flexbox. As you can see, I have an aside element that holds an ordered list of social media icons. For some reason, I'm unable to make these icons stick to the BOTTOM on the containing div.
HTML CODE
<div class="outercontainer group">
<div class="dividing-row span_1_of_2 col">
<p> here is some text </p>
<aside>
<ol class="category-name">
<li><i class="fa fa-pinterest-p"></i></a></li>
<li><i class="fa fa-flickr"></i></a></li>
</ol>
</aside>
</div>
</div>
CSS CODE
.outercontainer // this keeps all containers the same height in fluid design
{
display: flex;
flex-wrap: wrap;
}
ol.category-name
{
display: inline-block;
color: #FFF;
align-self: flex-end!important; // this does not work
}
Can anyone help? am I missing the obvious?
Many thanks,
p
Here are a few things to consider:
When you create a flex container only the child elements become flex items. Any descendant elements beyond the children are not flex items and flex properties don't apply to them.
If you want to apply flex properties to the children of flex items, you need to make the flex item a flex container, as well. In other words, you need to create nested flex containers.
You haven't specified any heights for your containers. So the height of each container is based on the height of the content. If the content is a single row, you really don't have much height.
So in your HTML structure, the flex container is...
<div class="outercontainer group">
and the only flex item is...
<div class="dividing-row span_1_of_2 col">
The <p>, <aside>, <ol> and <li> are regular block elements. Flex properties don't apply.
If you want to use flex properties to align the social media icons at the bottom of the container, you need to make the parent a flex container and give it a height.
Here's a demo with more details: http://jsfiddle.net/f1qnjwd3/1/
Couple of more notes:
In your ordered list, you're missing an opening <a> tag.
In my demo, the heights are for demo purposes only. They may not align perfectly because I wasn't trying to create a perfect layout, just an illustration of how this answer works.

Unable to center div on bootstrap 3

I'm unable to center a lot of div since I upgrade my bootstrap from 2.1 to 3.0
For example with this code:
<div id="center" class="container">
<div class="row">
<div class="btn-toolbar">
<div class="btn-group">
<a class="btn btn-default" href="#">test</a>
</div>
</div>
<br />
<p>Am I centered ?</p>
<a class="btn btn-default" href="#">Back</a>
</div>
</div>
I had this rule:
#center {
margin: 0 auto;
}
But the result is:
Or another example, how to center this:
<div id="center" class="container">
<div class="row">
<li class="col-md-5">
<ul class="list-unstyled">
<li><i class="icon-user"></i> aaaaaaaaa</li>
<li><i class="icon-envelope"></i> bbbbbbbbbb</li>
<li><i class="icon-envelopebug"></i> cccccccccccc</li>
</ul>
</li>
<li class="col-md-5">
<ul class="list-unstyled">
<li><i class="icon-user"></i> aaaaaaaaa</li>
<li><i class="icon-envelope"></i> bbbbbbbbbb</li>
<li><i class="icon-envelopebug"></i> cccccccccccc</li>
</ul>
</li>
</div>
</div>
Thank you for your help
In order to center a block level element using margin: 0 auto; it must also have a width that is smaller than its containing block (for the auto value to make sense) - because #container is spanning the width of its parent (the <body>) there is simply no margin to distribute.
An alernative approach to margin: 0 auto; would be to set .btn-toolbar to inline-block and then centering it by adding text-align: center; to its containing block. You can apply the same concept to the second example:
http://fiddle.jshell.net/52VtD/94/
In this instance, margin:0 auto doesn't work because the width of the element is 100%. If you want it to work, you would have to set a width on the element:
.btn-toolbar {
width: 50px;
margin: 0px auto;
}
If you want to center the text and the button, you could add the class text-center to the parent element, in this case: .row. The styling of this class is simply text-align: center.
<div class="row text-center">
..
</div>
EXAMPLE HERE
As #Adrift points out, it would be much more efficient to center the element by making it inline-block, as you can use text-align:center as opposed to margin:0 auto and avoid having to set a fixed width on the element. This will ensure that the element is centered regardless of its width. (example here) - don't forget you can just add the class text-center to the parent for centering.
It's also worth noting that inline/inline-block elements respect white-space in the markup, and thus generate space if present. If you want to remove this space, see this answer.

twitter bootstrap margin-left -20px issue

I'm having an issue using twitter bootstrap on my webpage http://scrapp.site90.com/ . Header is wrapped in container and has .row around it, but seems that because of margin-left: -20px this row cannot align with other content. Is it possible to fix it? I tried to change value of margin-left, but then layout gets really messed up.
Instead of using the span* you could use pull-left on the H1..
<div class="row">
<h1 class="pull-left">Take a look at our work to see what we mean</h1>
<div>
<ul class="social inline pull-right">
<li>..</li>
</ul>
</div>
</div>