Center except when an overlap would occur - css

I'm trying to accomplish a toolbar layout that includes 3 components. The left and center are flexible in size to the point where I don't think standard responsive breakpoints will do the job. The flexible center should be centered relative to the viewport when space allows. However, if the center and left would be overlapping, the center section is permitted to become off-center in order to avoid having to hide content.
Toolbar with wide viewport:
Toolbar with narrow viewport. Note the Section Title is not perfectly centered. This is desireable because it would overlap the breadcrumb:
I thought maybe flexbox could do this, but I'm struggling to make it work. Below is an attempt I have made to do this using flexbox.
HTML:
<div class="toolbar">
<div>Site / Section A / Section A1 / Section A1b</div>
<div class="section-title">This Section Title</div>
<div>Site Search</div>
</div>
CSS:
.toolbar {
display: flex;
background-color: #3F51B5;
color: white;
padding: 10px 0;
}
.section-title {
flex-grow: 1;
text-align: center;
}
http://plnkr.co/edit/YoD0yLWliXhu191jUrv4?p=preview

As you're using flexbox, you can use justify-content declaration instead of text-align.
Like this:
.section-title {
justify-content:space-between;
}
There's a great article about it here.

Related

Flex-box with the central element that fills all the free space [duplicate]

This question already has answers here:
Make a div fill the height of the remaining screen space
(41 answers)
Closed 4 years ago.
I am trying to design the web page with the following document tree (as to avoid the appearance of the scroll as much as possible):
html
head
body
div (flex-box - height 100%)
header (flex-child - fixed height)
main (flex-child - consumes all the remainig space/height)
footer (flex-child - fixed height)
Apparently, flex-box is the best solution, but I am reading this nice guide https://css-tricks.com/snippets/css/a-guide-to-flexbox/ and it appears that there are only limited options how to distribute the space (how to distribute the height of elements) - there are some "growth" properties but nothing else. How can I make the structure I am aiming to achieve? I have no code because I don't see the necessary CSS properties for making even a starter example.
I suppose this is what you're looking for. If you want to use flex you would set its direction to column, and set the height of the container as 100vh, then you set the flex-grow property to the body of the page so it uses the remaining space.
Better see it in full screen
.container {
display: flex;
flex-direction: column;
height: 100vh;
}
header {
background: red;
height: 40px;
}
.body {
flex-grow: 1;
background: green;
}
footer {
background: blue;
height: 40px;
}
<div class="container">
<header>
</header>
<div class="body">
</div>
<footer>
</footer>
</div>

Positioning of elements in a box with Flexbox

I have been trying to make a row of responsive boxes present a nicer look. After lots of effort and googling, I am here to get a word from experts. Please check the image below:
Outermost red is a bootstrap flexible row with display:flex;
Each box, the first of which is represented by green box, has flex: 1 ...;
Until this point, there is no issue and my CSS works perfect on all screen sizes showing all the boxes in same height and width. I just have two issues which I need help on.
Issue 1:
I need that lower part of box (represented by orange border) may always get positioned to the bottom of green box. This way all the buttons will appear in same line.
I tried to use a wrapper div in each box and then set position attribute for wrapper to relative and those of inner divs (yellow & orange) to absolute. Then I set the lower one to bottom: 0px;. But it does not work with flex and needs me to mention fixed height of wrapper which I cannot mention.
Issue 2:
In the box with the blue border I need the text of all lines to be justified except the last line which should be left aligned.
Issue 1
Assign display: flex to the div that is presented by the green box. After that, add align-self: flex-end; to the orange box. The orange box should now be displayed at the end of the green box.
Issue 2
Use the following fix to achieve what you want:
.blue-box {
text-align: justify;
-moz-text-align-last: right;
text-align-last: left;
}
The problem is that this wis not supported by Safari on Mac and iOS devices. You would have to add more markup to also cover Safari. An example would be to wrap each text line into a p tag if it's possible. Then you could do this:
.blue-box p {
text-align: justify;
}
.blue-box p:last-child {
text-align: left;
}
Please report back if the fixes do work for you or not.
The best way to solve this is to use flexbox.
.promo-boxes {
width: 100%;
display: flex;
justify-content: space-between;
background-color:black;
}
.promo-box {
width: 100px;
border: solid 1px #ccc;
background-color:red;
display: flex;
}
.btns-wrapper {
margin-top: auto;
align-self: flex-end;
}
<div class="promo-boxes">
<div class="promo-box">
<div>test 2</div>
<div class="btns-wrapper">
<button>
subscribe
</button>
</div>
</div>
<div class="promo-box">
<div>
test 3
</div>
<div class="btns-wrapper">
</div>
</div>
<div class="promo-box">
<div>
test 4 <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
loooong
</div>
<div class="btns-wrapper">
</div>
</div>
</div>

Horizontally center text in row with floats on both sides, with flexbox?

Here's a CSS puzzle for you all.
I'm using flexbox in my layout. I have a header with a few buttons on the left side, some text in the center, and another button on the right. Here's an ascii drawing:
[btn][btn2][btn3][ text ][btn4]
Unfortunately, this looks weird because the text isn't centered in the header. What I really want is this:
[btn][btn2][btn3][ text ][btn4]
Ideally, I'd like to continue using flexbox to achieve this because it makes most of the horizontal layout really easy, but I'm willing to fall back to floats and/or positioning if need be.
One problem with positioning the text element absolutely is that long text will under/overlap the buttons on the side. I currently use text-overflow: ellipsis and as a bonus, I would love to continue to if possible:
[btn][btn2][btn3][ long text causes elli... ][btn4]
I'm also okay with adding extra container elements if that helps. Perhaps there's a way to solve this by adding left buttons and right buttons in containers and then ensuring those containers are always the same width?
Edit: I think I took a step in the right direction with this CodePen. It properly centers the text. The only downside is that the h1 needs a fixed or percentage width, and if that width is wider than the space available, it seems to just overlap the neighboring elements.
You came very close to a working sample. I forked your CodePen with a solution that don't require widths of any kind. It's using the power of flex to position elements.
The H1 will always be in the middle, with a width of the same size as the surrounding left-btnsand right-btns, using flex: 1;
You can, of course, specify your H1 to a fixed width as you did, or make it for example flex: 2; to have it take up 50% space instead of 33%.
Here's the fork on CodePen. I've removed unnecessary code.
And the code:
HTML
<div class="wrapper">
<div class="left-btns">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<h1>center me! center me! center me! test woah asdf veasdf veasdf veasdf veasdf ve</h1>
<div class="right-btns">
<div class="box"></div>
</div>
</div>
<h1>center me!</h1>
CSS
.wrapper {
background: green;
display: flex;
margin: 5px;
}
h1 {
flex: 1;
text-align: center;
margin: 5px;
background: yellow;
overflow: hidden;
text-overflow: ellipsis;
white-space: noWrap;
}
.box {
width: 50px;
height: 50px;
margin: 1px;
background: red;
}
.left-btns,
.right-btns {
margin: 5px;
display: flex;
flex: 1;
background: blue;
}
.right-btns {
justify-content: flex-end;
}

CSS - aligning wrapped floating divs to the center

I am trying to create something like a gallery that shows different number of images per row based on the width of the browser. This has already been achieved using overflow: hidden in the outer div and float: left in the inner div.
However, what happens with this is that my images are always aligned to the left, leaving alot of whitespace on the right. How do I make it such that the gallery is always centered in the screen no matter how many images there are per row.
My code is on http://codepen.io/anon/pen/KzqAs
Thank you very much. :)
How about this: http://codepen.io/anon/full/mtBbF
HTML
<div class="container">
<div class="red box">red</div>
<div class="blue box">blue</div>
<div class="black box">black</div>
</div>
CSS
body{
text-align:center; /*You would need to define this in a parent of .container*/
}
.container{
display: inline-block;
margin: 0 auto;
text-align: left;
}
.box {
width: 300px;
height: 300px;
float: left;
}
Demonstration
You need to use an id(or class) on the main div. Set width: 300+px and margin: auto
Also your boxes should be with display: inline-block to allow them to begave "inline"
I have changed colors of the boxes a bit for better visibility.

CSS: 3 divs - Resizing 2 outer divs automatically based on width of inner div/text

My problem is best outlined with this schematic/image which outlines how I want it to look:
!
I have a background image and 2 divs for text over the top of it (headline, and intro-text). I also have 2 divs on either side of the headline - these are for the white horizontal stripes.
My issue is that the headline is changeable in a CMS, and I want the horizontal white stripes to automatically fill up the space to the left and to the right of it, regardless of the headline's width.
I can't figure out how to make those 2 horizontal white stripes resize automatically.
Here's my HTML:
<div id="masthead">
<div id="headline-container">
<div id="left-stripe"> </div><div id="headline">{headline}</div><div id="right-stripe"> </div>
</div>
<div class="clear-both"> </div>
<div id="intro-text">{intro_text}</div>
</div>
And here's my CSS - ignore the widths specified for the left-stripe and right-stripe - they're just placeholders:
#masthead {
height: 260px;
}
div#headline-container {
width:960px;
padding:none;
}
div#left-stripe{
float: left;
background-color:#fff;
height: 3px;
width:500px;
display: inline;
}
div#right-stripe{
float: right;
background-color:#fff;
height: 3px;
width:100px;
display: inline;
}
div#headline {
text-align:right;
color: #fff;
font-size: 200%;
float: left;
display: inline;
}
div#intro-text {
text-align: left;
float: right;
width: 300px;
color: #fff;
}
Ideas? Please let me know if I can provide more detail.
I'm a bit too busy to actually test this, but this might give you some direction. i'm not sure the exact effect you're trying to achieve (see comment about finding a live demo someone made).
Regardless, this kind of fluid layout is a bit difficult to achieve reliably with straight CSS. To make it easier I would suggest making the right-stripe a static width.
This CSS solution MIGHT work... no promises.
markup
<div class="container">
<div class="headline-container">
<div class="left-stripe"></div>
<div class="headline">Headline goes here</div>
<div class="right-stripe></div>
</div>
<div class="content"></div>
</div>
CSS
//static width for right stripe
.right-stripe { width: 20px; }
.headline { width: auto; }
.left-stripe { width: auto; }
Using javascript would make it really easy though... here's how i would do it with jQuery. Again, I would make the right-stripe a static width to achieve this effect.
(same markup...)
..
js
var totalWidth = $("#container").width();
var leftWidth = totalWidth - ($("headline").width() + $("right-stripe").width());
$("left-stripe").width(leftWidth);
You can do this dynamically, with jQuery, for example. You take the full width of the 3 div's, drop the size of the inner div and assign dynamically the widths of the 2 outer div's in which the bar should repeat horizontally.
Basically, you will need:
$("#whole-div").width() - $("#inner-div").width() for the outer div's total width. Then, depending on your positioning of the inner-div, you assign values for the outer div's.
For example: whole div has 1000px, inner div has 200px and inner div is positioned 600px left. You will then assign 600px to the left div ($("#whole-div").width() - $("#inner-div").css('left')) and 200px for the right div ($("#whole-div").width() - $("#inner-div").css('left') - $("#inner-div").width()). Of course, you will then set a background-repeat property on the outer div so that the image repeats.
Hope that helps!
UPDATE CSS only fluid solution: http://jsfiddle.net/SebastianPataneMasuelli/XnvYw/1/
it uses the same background image twice, on #masthead and on #headline-container. except ton headline container the background is offset to match its left position relative to its parent element. then we only need one div.line behind it, which gets covered by the background image under the headline and copy, giving the illusion of a seamless image.
do you mean like this?: http://jsfiddle.net/SebastianPataneMasuelli/XnvYw/

Resources