How to center fixed content in flexbox container in Safari? - css

Following code works as expected (block is centered) in Chrome and Firefox but in Safari child container is slightly off:
#container {
width: 100%;
background: yellow;
height: 20px;
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
}
#content {
padding: 0px;
background: linen;
position: fixed;
}
My question would be - how to center "position: fixed" element in a "display: flexbox" parent in Safari?

Element with position: fixed (or position: absolute) won't behave in the same way in Safari as they do in Chrome/Firefox.
To center a flex item in Safari you need to use transform: translate
Updated codepen
Stack snippet
#container {
width: 100%;
background: yellow;
height: 20px;
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
}
#content {
padding: 0px;
background: linen;
position: fixed;
left: 50%;
transform: translateX(-50%);
}
<div id="container">
<div id="content">THIS CONTENT IS NOT CENTERED IN SAFARI</div>
</div>

Related

How can I fix a div relative to a scrollable container?

Please see this minimum example
.container {
position: relative;
width: 200px;
height: 200px;
border: 3px solid gray;
overflow: scroll;
}
.box {
width: 100%;
height: 800px;
background: linear-gradient(0deg, rgba(34,193,195,1) 0%, rgba(253,187,45,1) 100%);
}
.loading-cover {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: white;
opacity: 0.5;
display: flex;
justify-content: center;
align-items: center;
}
<div class="container">
<div class="loading-cover">
Loading
</div>
<div class="box"></div>
</div>
I want to fix the white overlay when scrolling.
I've tried inset: 0 or width: 100%;height:100%; on loading-cover, but no luck.
position: sticky; is also unusable in this case because it sticks to the window viewport, not the scrollable container.
Is there any way I can solve this problem?
This might not be the shortest path to a solution, but it does work. It might hold up in cross-browser testing if you don't need to support IE.
This is using a loading class on the container that applies a sticky ::before pseudo-element, with a negative bottom margin to make the content pop up underneath it. A little goofy, but it's a weird situation. I also removed some unnecessary width values and changed overflow to overflow-y, which may or may not be useful in your situation.
With this, you could turn on and off the "Loading" message by adding or removing the class to the container.
.container {
position: relative;
width: 200px;
height: 200px;
border: 3px solid gray;
overflow-y: scroll;
}
.box {
height: 800px;
background: linear-gradient(0deg, rgba(34,193,195,1) 0%, rgba(253,187,45,1) 100%);
}
.container.loading::before {
position: sticky;
top: 0;
height: 200px;
margin-bottom: -200px;
background: white;
opacity: 0.5;
display: flex;
align-items: center;
justify-content: center;
content: 'Loading';
}
<div class="container loading">
<div class="box"></div>
</div>

How to add an image on top of a fixed position container?

I would like to create a following shaped notice bar on the bottom of my webpage (sticky).
Here is my HTML
<div class="notice-container">
<div class="wave"></div>
<div>
<p>Content here</p>
</div>
</div>
And here is my CSS, I tried several things, but here is the latest:
.notice-container {
display: block;
height: auto;
background-color: #ccc;
position: fixed;
bottom: 0;
left: 0;
right: 0;
width: 100%;
}
.wave:after {
content: "";
background-image: url('../wave.png');
background-repeat: repeat-x;
position: absolute;
top: 0;
margin: -30px;
width: 100%;
height: auto;
}
Since the container has a position: fixed, how can I get the repeat-x work on the wave? I would like to display the background-image on top of the container div.
Your pseudo element needs display: block; and also a specified height attribute. Since the value auto would just tell it to extend to fit its contents (and it has none), then the height value would remain 0.
.wave:after {
content: "";
display: block; /* <- Add this */
background-image: url('../wave.png');
background-repeat: repeat-x;
position: absolute;
top: 0;
margin: -30px;
width: 100%;
height: 60px; /* Or whatever your wave.png requires */
}
Place your url and justice the sizes of image in background-size. Also do not forget to change needed height of pseudo element which is also needs to configure margin-top and top
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
footer {
width: 100%;
height: 70px;
border: 5px solid red;
border-top: 0;
margin-top: 20px;
position: relative;
}
footer:after {
width: 100%;
display: block;
content: '';
height: 20px;
position: absolute;
left: 0;
top:-20px;
background-image: url(https://i.stack.imgur.com/z4HMY.png);
background-size: 10% 20px;
}
<footer></footer>

Fixed div inside relative parent is not working as expected in Safari

I have a fixed div inside of a relative positioned div. I want the div to be fixed to the top of the page and contained within my relative positioned parent.
A common example of this use case is a sticky website sidebar in a two column layout.
As I understand. Setting the top: 0 on my fixed div will fix it to the top. Setting margin-left: 0 on my fixed div will align it with its relatively positioned parent.
This works fine on all browsers except Safari (version < 10). Is there any way to fix this issue that doesn't involve user agent sniffing.
Here is a bare-minimum fiddle illustrating isolating issue below:
http://jsfiddle.net/vgc1ekbg/4/
Here's another fiddle illustrating the issue in the context of a two-column website layout: http://jsfiddle.net/dpmj3y0n/1/
Edited based on last fiddle shared in comments.
* {
box-sizing: border-box;
}
.wrapper {
max-width: 960px;
height: 2000px;
margin: 0 auto;
text-align: center;
/* line-height: 580px; */
}
.layout {
height: 2000px;
/*padding-left: 20px;*/
/* padding-right: 350px; */
/*margin-right: 192px;*/
}
.layout:before, .layout:after {
content: "";
display: table;
}
.layout:after {
clear: both;
}
.col-main {
width: calc(100% - 184px);
margin-left: -8px;
margin-top: -8px;
height: 580px;
float: left;
position: relative;
left: 200px;
background-color: #f16529;
line-height: 580px;
}
.col-sub {
/* margin-right: -100%; */
position: absolute;
top: 0;
left: 0;
width: 200px;
line-height: 580px;
/* height: 580px; */
background-color: #f0dddd;
float: left;
}
.sticky {
position: fixed;
top: 0;
left: 0;
width: 200px;
height: 100px;
overflow: hidden;
z-index: 100;
background-color: gray;
color: red;
line-height: 100px;
}
<div class="wrapper">
<div class="layout">
<div class="col-main">Main Content</div>
<div class="col-sub">Sidebar Content
<div class="sticky">
Sticky Content
</div>
</div>
</div>
</div>
if you intent to center align, you can use left: 50%; and transform: translateX(-50%); to both .column and .sticky
http://jsfiddle.net/vgc1ekbg/5/

Align text on top, right, bottom and left of image?

I'm trying to add text on all four sides of image but i cant get the right text to align properly. The right text is still on left side.
FIDDLE: https://jsfiddle.net/y75L0ww9/
<span class="top">Text on top</span>
<span class="left">Text on left side</span>
<img src="http://www.uaa.alaska.edu/web/images/horizontal-large.jpg" />
<span class="right">Text on right side</span>
<span class="bottom">Text on bottom</span>
img {
max-width: 100%;
height: auto;
border: 0px none;
vertical-align: middle;
display:block;
margin:0 auto;
}
.top, .bottom {
display: block;
text-align: center;
margin-left: auto;
margin-right: auto;
overflow: hidden;
}
.left {
display: inline-block;
background-color: #FF0;
transform: rotate(-90deg);
position: relative;
top: 200px;
left: 0px;
}
.right {
display: inline-block;
background-color: #F00;
transform: rotate(90deg);
position: relative;
right: 0px;
bottom: 200px;
}
You should add wrapper around Your image (for now it can be body), ad give it position: relative; Then modify .right class:
.right {
display: inline-block;
background-color: #F00;
transform: rotate(90deg) translate(0, -50%);
position: absolute;
right: 0px;
top: 50%;
}
updated fiddle
(btw. in wider viewport the left text is also not so nicely layed out right now ;) )
You will have to wrap all those 5 elements into another element, e.g.:
.wrapper {
display: inline-block;
position: relative;
}
Having this, you'll be able to easily align your spans inside by giving them position: absolute.
use position: absolute; instead of position: relative;
Updated fiddle

Vertical centering with flexbox when items have :after background images

How do I vertically center divs inside their container using flexbox if those divs have background images attached to their :after pseudo-element?
On Chrome 33 these divs align to the top: http://jsfiddle.net/6SQ6W/
HTML:
<div id="container">
<div id="left_and_right">
<div>Left</div>
<div>Right</div>
</div>
</div>
CSS:
#container {
height: 300px;
width: 300px;
background: blue;
color: white;
position: relative;
}
#container #left_and_right {
position: absolute;
height: 100%;
width: 100%;
display: -webkit-box;
display: -webkit-flex;
display: flex;
align-items: center;
}
#container #left_and_right div, #container #left_and_right div:after {
height: 50px;
width: 100px;
}
#container #left_and_right div {
background: green;
/* THIS PREVENTS VERTICAL CENTERING BUT SEEMS NEEDED FOR THE REST OF THE STUFF */
position: absolute;
}
#container #left_and_right div:after {
content:"";
position: absolute;
background-image: url(http://www.animatedgif.net/lipsmouth/kissing_e0.gif);
text-indent: -9999px;
left: 0;
}
#container #left_and_right div:nth-of-type(2) {
right: 0;
}

Resources