Use display: flex as the 'opened' state instead of display: block with fancy-box 2 - css

I want to use display: flex as the 'opened' state instead of display: block with fancy-box 2.
Currently the element gets display: block; inline.
I'm trying to track down where to change it, but maybe I just need to nest a div in the pop-up. Has anyone done this before?
markup
<div class='thing-that-triggers'>
<span>thing</span>
<div class='pop-up'>
<div class='text'>
text
</div>
<div class='image'>
image
</div>
</div>
</div>
<div class='thing-that-triggers'>...</div>
<div class='thing-that-triggers'>...</div>
styles
.pop-up
display: flex // setup
flex-direction: column
display: none // hide it for fancybox
.text
width: 100%
.image
display: none // hide on small screen
#media $break-point-2
flex-direction: row
align-items: center
.block
split-in(2)
.text
flex-center-child()
.recipe
// centered
.image
display: block // show second panel
jQuery
$('.thing-that-triggers').fancybox({...});

You have 3 choices if fancybox doesn't give you any options to change it.
Change it directly in the source code (not the best approach).
Nest another div so that the added display doesn't affect yours (as you mentioned).
Override it yourself in the beforeShow callback. You'll need to use jQuery each to get a reference to the current .pop-up and a closure to keep the reference and use it later:
function handleDisplay($popup) {
var closure = function() { $popup.css('display', 'flex'); };
return closure;
}
$('.thing-that-triggers').each(function() {
var displayHandler = handleDisplay($(this).children('.pop-up'));
$(this).fancybox({
beforeShow: displayHandler
}
});
See the documentation for other available callbacks.

Just add an inner div and set the flex stuff on it - and leave the outer div for fancybox.
This IS an answer, but I'd much prefer not to change my markup + I think this question is going to get asked a lot in the near future. So, a JS solution is what'll I'll mark as the best answer.
markup
<div class='thing-that-triggers'>
<span>thing</span>
<div class='pop-up'>
<div class='inner'>
<div class='text'>
text
</div>
<div class='image'>
image
</div>
</div>
</div>
</div>
styles
.pop-up
display: none
.inner
display: flex // setup
flex-direction: column
.text
width: 100%
.image
display: none // hide on small screen
#media $break-point-2
.inner
flex-direction: row
align-items: center
.block
split-in(2)
.text
flex-center-child()
.recipe
// centered
.image
display: block // show second panel

Related

Flexbox toolbar with a ton of nesting

I am trying to build a flexbox type container with a search and filters and buttons. I am having trouble getting the desired behaviour. The toolbar-container class is the main flex container, which holds search-bar and filter-group as the top-level flex-items. I am getting confused as to how approach setting up filter-group as a nested flex-container to which the desired behavior is to push the buttons to the end of the row (far right, equivalent to float: right) and give the filters the largest amount of space, wrapping below as the window resizes but maintaining the positions of search and buttons on either side. I have tried using the below css the seperate the fitlers from the buttons but there filters and buttons stay grouped together like this:
search-bar-filters-buttons---------------------------------------------------
Below is desired layout, with only the filters wrapping to the space below when the space decreases.
search-bar-filters-----------------------------------------------------buttons
<div class="toolbar-container">
<div class="search-bar"></div>
<div class="filter-group">
<div class="filters"></div>
<div class="buttons"></div>
</div>
</div>
.toolbar-container {
display: flex;
}
.search {
}
.filter-group {
display: flex;
justify-content: space-between;
}
.filters {
flex-wrap: wrap;
}
.buttons {
}
You need to add flex: 1 for you .filter-group to take all remaining space. Demo:
.toolbar-container {
display: flex;
}
.filter-group {
display: flex;
flex: 1; /* new */
justify-content: space-between;
}
.filters {
flex-wrap: wrap;
}
<div class="toolbar-container">
<div class="search-bar">Search bar</div>
<div class="filter-group">
<div class="filters">Filters</div>
<div class="buttons">Buttons</div>
</div>
</div>

Safari bug ? Translating table-row-group using GSAP make caption jump to bottom

We are animating a calendar using GSAP. The calendar is draw using css table, row and caption...
We wanted to animated some part of this table.
But better than words here is a codepen to open on safari:
https://codepen.io/anon/pen/rmrJRy
var body = document.getElementById('body')
TweenMax.to(body, 1, {x: 400});
.table {
display: table;
width: 500px;
}
.header-group {
display: table-header-group;
}
.body {
display: table-row-group;
}
.caption {
display: table-caption;
}
.cell {
display: table-cell;
border: solid 1px blue;
text-align: center;
}
.row {
display: table-row;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.1/TweenMax.min.js"></script>
<div class="table">
<div class="caption">Fevrier 2017</div>
<div class="header-group">
<div class="row">
<div class="cell">L</div>
<div class="cell">M</div>
<div class="cell">M</div>
<div class="cell">J</div>
<div class="cell">V</div>
</div>
</div>
<div class="body" id="body">
<div class="row">
<div class="cell">1</div>
<div class="cell">2</div>
<div class="cell">3</div>
<div class="cell">4</div>
<div class="cell">5</div>
</div>
</div>
</div>
PS: I just decided to hack around with some position absolute. But would like to hear to better solutions.
The key point in your example is the "TweenMax" operation, which will adds a "transform" property to the "body" class. It seems a bug of Safari: if a positioned element, or a element who creates a new stacking context, appears as a child element of the table, a re-render bug of caption will be caused in Safari.
Unfortunately, there seems no better solution, for now.
Absolute position maybe the best choice you should rely on.
Yes, here maybe a better solution. We already known that Safari cannot handle the situation we've mentioned above by itself, appropriately. So, we can try to tell it how to prepare a rerender for the table caption. Adding a will-change property to the caption element is the way. In this case, we add the will-change with the value "transform" to the caption. Then, everything will be Okay.
The details about will-change property could be checkout here

Dynamic equal width children

Is there any way to get all children of a parent to be the same width without having the parent be a block level element?
Basically I want all the "columns" in the jsfiddle to have the same width but I don't want the container to span the entire width of the container, only the necessary width.
Edit: I am looking for a way to handle a dynamic number of children
Edit2: Updated the fiddle and code to make widths more obvious
Thanks!
HTML
<div class="container">
<div>
Short
</div>
<div>
SomethingSuperLong
</div>
<div>
Ok
</div>
</div>
https://jsfiddle.net/0g9af1dh/2
Check the below snippet.
var maxWidth = 0;
$('.container > div').each(function() {
var thisWidth = $(this).outerWidth();
if(maxWidth < thisWidth) {
maxWidth = thisWidth;
}
});
$('.container > div').width(maxWidth);
.container {
display: inline-flex;
}
.container > div {
border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="container">
<div>
Short
</div>
<div>
Something super long
</div>
<div>
Ok
</div>
</div>
Edit: May be if you are open for script as well. Neglect otherwise.
So, the capabilities of flex, but with inline behavior? Hmmm...
.container {
display: inline-flex;
}
.container > div {
flex: 1 0 0;
border: 1px solid red;
}
<div class="container">
<div>
Short
</div>
<div>
Something super long
</div>
<div>
Ok
</div>
</div>
Well if you just want them to be the same size you can do it like this.
.container > div {
width: 33.3%;
}
If it's not what you want, tell me in the comments and I will update it.
just change your css to
.container {
display: flex;
}
.container > div {
flex:1;
border: 1px solid red;
}
my solution is very similar to this solution
But in his solution he left them as display: table which makes the outer div share qualities of display: block
If you change it to use display: inline-table it takes on inline characters. To show that it is inline I placed test inline next to the outer div.
This solution does require you set a width for your outer container. Based on your question details I think this works for you but if it doesn't let me know and I can tweak the answer.

Aligning two elements differently in same div

I have multiple elements in the a single div.
I want to align one element as "text-align: right" and another element "text-align: left"
Check the below code:
<div class="image_meaning" style="display: none; background-color: white; height: 35px; margin-left: 1px;">
<input type="checkbox" id="points" value="Temporal Filter" style="text-align: left; "/>
<label for="tempral_filter" style="text-align: left; ">Points</label>
<img style="text-align: right;" src="{{ STATIC_URL }}img/cross.png"/>-abc
<img style="text-align: right;" src="{{ STATIC_URL }}img/blue_triangle.png"/>-cde
</div>
but when I run the code it places both the element to the left.
any idea how to do it?
Answer
There are a few ways to solve your issue the most common one is using the css float property (as of 2016). The more modern ways are using flexbox or grid.
Solution using flexbox
You could use display: flex to do this.
Flexbox is only supported by newer browsers, If IE (9 and below) is your friend please stay away from this method.
Example html:
<div class="wrapper">
<div class="block"></div>
<div class="block"></div>
</div>
Example css:
.wrapper { display: flex; }
.block { width: 50%; }
Live demo.
Solution using grid
You could use the new display: grid to do this.
Grid layout is only supported by the most modern browsers (Sep 2017), If you are building on evergreen browsers then great, if not use flex.
Example html:
<div class="wrapper">
<div class="block"></div>
<div class="block"></div>
</div>
Example css:
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
}
Live demo.
Solution using float
The css float property is the classic way to do this and can be dated back to prehistoric times so it supports basically every browser. The only caveat to this would be the clearfix issue (see below).
Example html:
<div class="wrapper">
<div class="block-left"></div>
<div class="block-right"></div>
</div>
Example css:
.block-left { float: left; }
.block-right { float: right; }
Please be aware that floated elements cause their parent to disregard them when it comes to their height. If that is an issue (usually it is), you can use the clearfix hack to solve this situation.
You would define it like so:
.cf:before,
.cf:after {
content: " ";
display: table;
}
.cf:after { clear: both; }
And then on your parent element:
<div class="wrapper cf">
This will allow the parent to correctly receive the floated elements height.
Read more about what is the clearfix hack.
Live demo.
Other solutions
Solution using inline-block
You could also possibly use the inline-block property to put your elements side by side.
Note that the inline-block option will need to account for white space in the html between the blocks. To counter this, either remove the space like below, add a negative margin or define the font-size on the parent as 0.
Example html:
<div class="wrapper">
<div class="block"></div><div class="block"></div>
</div>
Example css:
.block { display: inline-block; }
/* Optional zero font for wrapper
Then reset blocks to normal font-size */
.wrapper { font-size: 0; }
.block { font-size: 16px; }
/* Optional negative margin if you can't
remove space manually in the html.
Note that the number is per use case. */
.block { margin-left: -.25em; }
Live demo.
Solution using position: absolute
Another way to do it would be to absolutely position your elements with a relative container. This method has the issue of being less flexible than the others when building responsive layouts and alike.
Example html:
<div class="wrapper">
<div class="block block-left"></div>
<div class="block block-right"></div>
</div>
Example css:
.wrapper { position: relative; }
.block { position: absolute; }
.block-left { left: 0; }
.block-right { right: 0; }
Live demo.
Why your solution is not working
You are using the text-align css property which will effect inline elements and text but it can't be used to shift the element like you would with the float property.
The text-align property effects the children of the element it is applied to.
Use float: left and float: right instead of text-align

How do I right align div elements?

The body of my html document consists of 3 elements, a button, a form, and a canvas. I want the button and the form to be right aligned and the canvas to stay left aligned. The problem is when I try to align the first two elements, they no longer follow each other and instead are next to each other horizontally?, heres the code I have so far, I want the form to follow directly after the button on the right with no space in between.
#cTask {
background-color: lightgreen;
}
#button {
position: relative;
float: right;
}
#addEventForm {
position: relative;
float: right;
border: 2px solid #003B62;
font-family: verdana;
background-color: #B5CFE0;
padding-left: 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
<script type="text/javascript" src="timeline.js"></script>
<link rel="stylesheet" href="master.css" type="text/css" media="screen" />
</head>
<body bgcolor="000" TEXT="FFFFFF">
<div id="button">
<button onclick="showForm()" type="button" id="cTask">
Create Task
</button>
</div>
<div id="addEventForm">
<form>
<p><label>Customer name: <input></label></p>
<p><label>Telephone: <input type=tel></label></p>
<p><label>E-mail address: <input type=email></label></p>
</form>
</div>
<div>
<canvas id="myBoard" width="600" height="600" style="background:lightgray;">
<p>Your browser doesn't support canvas.</p>
</canvas>
</div>
</body>
</html>
Floats are okay, but problematic with IE 6 & 7.
I'd prefer using the following on the inner div:
margin-left: auto;
margin-right: 0;
See the IE Double Margin Bug for clarification on why.
You can make a div that contains both the form & the button, then make the div float to the right by setting float: right;.
Old answers. An update: use flexbox, pretty much works in all browsers now.
<div style="display: flex; justify-content: flex-end">
<div>I'm on the right</div>
</div>
And you can get even fancier, simply:
<div style="display: flex; justify-content: space-around">
<div>Left</div>
<div>Right</div>
</div>
And fancier:
<div style="display: flex; justify-content: space-around">
<div>Left</div>
<div>Middle</div>
<div>Right</div>
</div>
You can use flexbox with flex-grow to push the last element to the right.
<div style="display: flex;">
<div style="flex-grow: 1;">Left</div>
<div>Right</div>
</div>
Note that while this answer is not wrong, it is very outdated methodology written in 2015
Other answers for this question are not so good since float:right can go outside of a parent div (overflow: hidden for parent sometimes might help) and margin-left: auto, margin-right: 0 for me didn't work in complex nested divs (I didn't investigate why).
I've figured out that for certain elements text-align: right works, assuming this works when the element and parent are both inline or inline-block.
Note: the text-align CSS property describes how inline content like text is aligned in its parent block element. text-align does not control the alignment of block elements itself, only their inline content.
An example:
<div style="display: block; width: 80%; min-width: 400px; background-color: #caa;">
<div style="display: block; width: 100%">
I'm parent
</div>
<div style="display: inline-block; text-align: right; width: 100%">
Caption for parent
</div>
</div>
Here's a JS Fiddle.
If you have multiple divs that you want aligned side by side at the right end of the parent div, set text-align: right; on the parent div.
Do you mean like this? http://jsfiddle.net/6PyrK/1
You can add the attributes of float:right and clear:both; to the form and button
Maybe just:
margin: auto 0 auto auto;
Simple answer is here:
<div style="text-align: right;">
anything:
<select id="locality-dropdown" name="locality" class="cls" style="width: 200px; height: 28px; overflow:auto;">
</select>
</div>
Sometimes float: left leads to design problems, for that cases you can use display flex like this:
.right {
display: flex;
justify-content: flex-end;
margin-left: auto;
margin-right: 0;
}
<div>
<div class="right">Right</div>
</div>
If you are using bootstrap, then:
<div class="pull-right"></div>
One way could be setting a parent div for those elements that need to be pulled right and do the rest like the way shown in the the example below to have them right-aligned:
.parent-div {
display: flex;
float: right;
}
/*Below: child-div styling is not needed for this purpose! this is just for demonstration:*/
.child-div {
text-align: center;
background-color: powderblue;
margin: auto 10px;
height: 100px;
width: 50px;
}
<div class="">CANVAS div </div>
<div class="parent-div">
<div class="child-div">child 1</div>
<div class="child-div">child 2</div>
<div class="child-div">...</div>
<div class="child-div">child n</div>
</div>
If you don't have to support IE9 and below you can use flexbox to solve this: codepen
There's also a few bugs with IE10 and 11 (flexbox support), but they are not present in this example
You can vertically align the <button> and the <form> by wrapping them in a container with flex-direction: column. The source order of the elements will be the order in which they're displayed from top to bottom so I reordered them.
You can then horizontally align the form & button container with the canvas by wrapping them in a container with flex-direction: row. Again the source order of the elements will be the order in which they're displayed from left to right so I reordered them.
Also, this would require that you remove all position and float style rules from the code linked in the question.
Here's a trimmed down version of the HTML in the codepen linked above.
<div id="mainContainer">
<div>
<canvas></canvas>
</div>
<div id="formContainer">
<div id="addEventForm">
<form></form>
</div>
<div id="button">
<button></button>
</div>
</div>
</div>
And here is the relevant CSS
#mainContainer {
display: flex;
flex-direction: row;
}
#formContainer {
display: flex;
flex-direction: column;
}
display: flex;
justify-content: space-between;
hasnt been mentioned. if there are 2 elements (even if one is an empty div) it will place one on the left and one on the right.
<div style="display: flex; justify-content: space-between;">
<div id="emptyDiv"></div>
<div>I'm on the right</div>
</div>
You can simply use padding-left:60% (for ex) to align your content to right and simultaneously wrap the content in responsive container (I required navbar in my case)
to ensure it works in all examples.
You can do it easy by just add this css:
(Works in IE11)
<div>
<!-- Subtract with the amount of your element width -->
<span style="margin-left: calc(100vw - 50px)">Right</span>
</div>
I know this is an old post but couldn't you just use <div id=xyz align="right"> for right.
You can just replace right with left, center and justify.
Worked on my site:)

Resources