Different alignment of ::after pseudo element in a flex-box in Safari - css

While implementing a simple toggle control I encountered a problem that only seems to appear in Safari. The same code works fine in Firefox and Chrome.
.mgs.huge {
font-size: 36pt;
}
input.mgs.toggle {
display: none;
}
label.mgs.toggle {
display: flex;
flex-direction: row;
align-items: center;
width: max-content;
position: relative;
--toggle-color: 49, 112, 212;
}
/* The toggle background. */
label.mgs.toggle::before {
display: inline-block;
content: "";
height: 12px;
width: 23px;
border: 1px solid rgba(var(--toggle-color), 1);
background-color: rgba(var(--toggle-color), 0.75);
border-radius: 25pt;
margin-right: 4px;
}
label.mgs.toggle.huge::before {
height: 35px;
width: 69px;
}
/* The circle (handle) in the toggle - unchecked, standard size. */
label.mgs.toggle::after {
flex: 0 0 auto;
align-self: center;
content: "";
position: absolute;
width: 12px;
height: 12px;
left: 1px;
background-color: white;
border-radius: 50%;
transition: left 0.2s;
}
label.mgs.toggle.huge::after {
width: 35px;
height: 35px;
}
input:checked.mgs.toggle.huge + label::after {
left: 35px;
}
<input type="checkbox" class="mgs toggle huge" readonly="" id="toggle6" value="">
<label for="toggle6" class="mgs toggle huge">Huge</label>
In Safari the white knob doesn't align vertically. By specifying a top value you can align it manually (in this case by adding 11px top to label.mgs.toggle.huge::after), but unfortunately this shows another problem: Firefox doesn't use the same vertical offset as Chrome and Safari do: the circle is offset subtly by half a pixel or so.
Hence I would prefer a solution where Safari does the automatic vertical centering, as it is supposed in this flex-box layout.
Here's also a fiddle to play with: https://jsfiddle.net/3Ltkwaux/.

Related

How to show custom horizontal scrollbar on mobile?

I've made a custom horizontal scrollbar in elementor with custom css, it works for desktop view but it doesn't work for mobile view, what am I missing? the following is the custom css that I use
.scroller-card {
display: flex;
flex-direction: column;
min-width: 300px;
flex-basis: 300px;
border-radius: var(--whiskey-radius);
margin: 8px;
padding: 16px;
color: var(--whiskey-color);
background-color: var(--whiskey-panel-background);
transition: all 150ms ease-out;
}
.scroller-cards {
display: flex;
flex-wrap: nowrap;
overflow-x: scroll;
-webkit-overflow-scrolling: touch;
-ms-overflow-style: none;
scrollbar-width: none;
transform-style: preserve-3d;
perspective: 800px;
padding: 24px 0;
}
*, *:before, *:after {
box-sizing: auto;
}
.scroller-cards::-webkit-scrollbar {
-webkit-appearance: none;
width: 5px;
height: 5px;
}
.scroller-cards::-webkit-scrollbar-thumb {
border-radius: 0;
background-color: #0F2B4A;
background: #0F2B4A;
border-radius: 16px;
opacity: .5;
}
Here are the results
I'm still new to coding so please help
Remove flex-wrap on screen below 1024px.
Reason: On screen below 1024px, cards moved on next line and content width of container is not greater than you container max width. That's why scroll is not applying
Your code doesn't work on both Firefox desktop and Firefox mobile.
You're setting the scrollbar width to zero in this line:
scrollbar-width: none;
Later you're setting the scrollbar width here:
.scroller-cards::-webkit-scrollbar {
-webkit-appearance: none;
width: 5px;
height: 5px;
}
But because FF does not support -webkit-scrollbar your code doesn't work.
See ::-webkit-scrollbar on caniuse.com

How to set absolute positionning in react component

i'm trying to create a custom button for my portfolio.
This button will be animated, the top part sliding in from left and the bottom part sliding in from right when hovered.
At the center of it will be the Category linked to this button.
Here an illustration :
How can i set my text in the center for every that i will create ? I can't use "position: absolute" property cause the reference would be the webpage and not the position where the custom component is declared...
Here my actual code :
CSS
const CatStyle = styled.div`
box-shadow: 0px 0px 2px 2px rgba(0,0,0,0.75);
height: 50px;
max-width: 150px;
background-color: white;
display: flex;
justify-content: center;
flex-direction: column;
cursor: pointer;
transition : background-color 0.5s ease-out;
:hover div{
display: flex;
}
.catContent {
position: relative;
align-self: center;
font-size: 1.5rem;
}
.topSlideAnimation {
display: none
height: 50%;
background-color: green;
}
.botSlideAnimation {
transition : background-color 0.5s ease-out;
display: none;
height: 50%;
background-color: blue;
}
`
JSX
const ButtonCat = (props) => (
<CatStyle>
<div className="topSlideAnimation"></div>
<div className="catContent">Hello</div>
<div className="botSlideAnimation"></div>
</CatStyle>
)
Not done any jsx so not sure what your catstyle tag would render, but if you can just render a button (or div), I would do the following
Make an outer container that is flex (for aligning text in center)
Make an inner container that is for the text (so you can position it relatively and add a z-index to it)
Add pseudo elements to your outer container for the animated bits (rather than having 2 empty divs)
* {
box-sizing: border-box;
}
.button {
display: inline-flex; /* make flex for centring */
justify-content: center; /* vertically centre */
align-items: center; /* horizontally centre */
position: relative; /* for adding absolute positioned children */
min-height: 50px; /* test value to show text is centred */
overflow: hidden; /* hide pseudo elements when not shown */
}
.button:before,
.button:after {
content: ''; /* make coloured animatable bits */
display: block;
height: 50%;
width: 100%;
position: absolute;
transition: all 1s ease-in;
z-index: 1;
}
.button:before {
top: 0;
right: 100%;
background: grey;
}
.button:hover:before {
right: 0;
}
.button:after {
top: 50%;
left: 100%;
background: darkgrey;
}
.button:hover:after {
left: 0;
}
.text {
position: relative; /* needs to have a higher z-index than the pseduo elements so text appears on top */
z-index: 2;
}
<button class="button"><span class="text">test content</span></button>

CSS border in Chrome: strange grey line

I have a problem with a border in Chrome. The green border has some grey lines.
Firefox: not visible -> ok!
Chrome: not visible but visible in the dev tools, mobile phone.
Chrome on my phone: visible
Here is a screenshot that shows my problems!
https://abload.de/img/cssiee7s.jpg
1) When you go to http://www.seelenpuls.at/hpneu/m_biografie_leander_de.php
there are two small grey lines
2) When you go to http://www.seelenpuls.at/hpneu/m_neues_de.php there are even more problems.
3) The menu button has an orange border (mobile only) ... and I don't know why as there is no such color in my CSS.
Please help!
Here's the code. The bold part is the border that causes the problems.
* { padding: 0; margin: 0; }
body
{
font-family: sans-serif, Verdana, Arial;
color: #000000;
background-color: #556B2F;
}
#center {
position: relative;
width: 350px;
height: 630px;
box-sizing: border-box;
margin: 5px auto 0px auto;
}
#logo {
position: absolute;
width: 350px;
height: 220px;
background-color: #ffffff;
box-sizing: border-box;
background-image: url("img/m_bg_c.jpg");
background-repeat: no-repeat;
background-size: 350px 220px;
}
#navi
{
position: absolute;
top: 175px;
width: 60px;
height: 40px;
font-size: 16px;
color: #000000;
background-color: #ffffff;
margin-left: 10px;
}
#header
{
position: absolute;
top: 187px;
width: 238px;
height: 30px;
font-size: 16px;
color: #000000;
left: 85px;
}
#content
{
position: absolute;
top: 218px;
width: 350px;
box-sizing: border-box;
color: #000000;
background-color: #ffffff;
font-size: 14px;
overflow: auto;
padding-left: 5px;
padding-right: 5px;
**border-bottom: 5px solid #556B2F**;
}
Ok so there is a couple of things that are going on in your css.
White lines
For your content div, I would use a width of 100% for mobile devices now, as you scale to tablets and desktops you can change to a more fixed or fluid width. I would also remove the border bottom property. This is not fully extending to the width of the content box and I am unsure if it has to do with the border-sizing property you are using. I would also apply the border-sizing this way so it is applied to every element in your html
* {
box-sizing: border-box;
}
Orange border - this is caused by the :focus pseudo css property of the button you are using, you can remove it this way
button:focus {
outline: none;
}
CSS Normalize or CSS Reset - consider using one of these stylesheets in your website. They help you rendering all elements more consistently through all browsers. This will save you the time of remove the :focus property, like I mentioned above in any project moving forward. Most popular CSS frameworks utilize this to normalize basic styles.
Link to Normalize.css

margin-left doesn't work in Firefox

In my code margin-left: is working only in the other browsers. In Firefox it seems I need to double every values i give to the margin-left: that works for the other browers. The element i need to marge is the blue circle.
If I inspect the element and change the css in the inspector and then i give margin-left: 60px (my margin-left: is normally 30px) it works. The same goes for 1em (is i put a 2em it works).
I just strated a formation so i'm not an expert, so if one of you can see where I've made a mistake, thanks in advance for telling me !
Here's my code
.cercle-logo {
height: 65px;
width: 65px;
color: #5CADD3;
border: 2px solid #EBEBEB;
margin-top: 15px;
border-radius: 100%;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
.cercle-logo:before {
content: "";
border: 5px solid white;
width: 24px;
height: 24px;
border-radius: 100%;
background-color: #5cadd3;
position: absolute;
margin-left: 2em;
box-sizing: border-box;
}
<div>
<span class="cercle-logo"><i class="fa fa-chart-pie fa-2x"></i></span>
</div>
Some browser use the parent padding as an offset for the absolute position child elements (chrome does this), because it's obvious that you will move the element using left,right,top,bottom not the margins
Say you have padding-left:20px, on the parent, and you set position absolute on one of it's children, if you won't see much changes, because some browsers uses that 20px and add it as an offset left:20px
One simple solution is to rest the offset, then use margins to push it, which i don't recommend you can use the left property to push it.
.cercle-logo {
height: 65px;
width: 65px;
color: #5CADD3;
border: 2px solid #EBEBEB;
margin-top: 15px;
border-radius: 100%;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
.cercle-logo:before {
content: "";
border: 5px solid white;
width: 24px;
height: 24px;
border-radius: 100%;
background-color: #5cadd3;
position: absolute;
left: 3.7em;
box-sizing: border-box;
}
<div>
<span class="cercle-logo"><i class="fa fa-chart-pie fa-2x"></i></span>
</div>
Thank you for your answer but I might have done something wrong because even though your explanation were clear, and the "code snippet" works well (I test it directly on Firefox), when i write is in Bracket and test it, it moves my blue circle totally on the left but this time on every browsers ...
Is there something I missed ?
Thank you for your time anyway !

Sub-Pixels calculated and rendered differently among browsers

The purpose:
I am working on a code similar to this to create a component where an input field has an embedded button:
http://codepen.io/anon/pen/pgwbWG?editors=110
As you can see, the button is positioned absolutely with top and bottom set to 0, to achieve a 100% height element.
Also to note is that the border of the text-input must stay visible and also wrap the button.
To achieve this I added a margin: 1px to the button so that there is (should be) space to display the surrounding text-input red border (usually when the input field content is invalid).
The problem:
is that on Firefox it is (mostly) rendered correctly, while on Chrome (and apparently on the newest Safari) it will have a 1px gap at the bottom of the button.
CSS seems ok but it appears to be a calculation/rounding problem in the rendering, where the bottom or the top margin of the button are not really 1px (can see it inspecting the element).
And also the padding of the input seems to influence in that.
At different zoom-rates it will add or remove 1px of margin to the top or the bottom of the button, resulting in a 1px-gap or in a covered-border.
As I set the button margin to 0px then the bottom margin is fixed but I loose the 1px margin on the top, finishing to cover the red border of the text-input.
The examples:
Probably I am not clear or too verbose in explaining it, so here are some screenshots of the bug, from different zooms on Chrome (note the CSS is always the same):
The solution:
I was not able to find a cross-browser solution.
How to deal with it and get a consistent component?
(no Javascript please)
As you already know, the problem arises from a different approach to subpixel calculus between browsers
In Chrome, for instance, borders can have a fractional size, but margins are handled different (as integers).
I don't have documentation about it from the Chrome team, but it's what can be seen in dev tools:
AFAIK, there is not a way to change that.
Instead, you can transfer the use of the margin in the button to a border.
Since you need to get space for the 1px border of the input, do the same in the button, set a 1px border (instead of a margin), and set it transparent.
The remaining trick is to set the background-clip property to padding box, so that this transparency is not affected by the background
There is another bug in Chrome, the padding expressed in em is not reliable at this level of precision when the browser is zoomed. I changed this in the snippet.
Since we are using the border button to get the dimension ok, we can style the border using instead a inset shadow.
* {
margin: 0; padding: 0; box-sizing: border-box;
}
button, input, wrapper {
display: inline-block; border-radius: 3px;
}
.wrapper {
position: relative;
width: 60%;
margin: 1em;
background-color: #ccc;
}
input {
border: 1px solid red;
width: 100%;
background-color: limegreen;
line-height: 3em;
/* padding: 0.75em; */
padding: 10px;
}
button {
position: absolute;
right: 0;
top: 0;
bottom: 0;
border: 1px solid transparent;
width: 7em;
margin: 0px;
background-clip: padding-box;
box-shadow: inset 0px 0px 0px 2px black;
}
<div class="wrapper">
<input type="text">
<button>Test</button>
</div>
Another example, where the button has a border. But we need a wrapper around it to get the dimensions ok.
* {
margin: 0; padding: 0; box-sizing: border-box;
}
button, input, wrapper {
display: inline-block; border-radius: 3px;
}
.wrapper {
position: relative;
width: 60%;
margin: 1em;
background-color: #ccc;
}
input {
border: 1px solid red;
width: 100%;
background-color: limegreen;
line-height: 3em;
/* padding: 0.75em; */
padding: 10px;
}
.buttonwrap {
position: absolute;
right: 0;
top: 0;
bottom: 0;
border: 1px solid transparent;
width: 7em;
margin: 0px;
background-clip: padding-box;
}
button {
position: absolute;
right: 0px;
top: 0;
bottom: 0;
width: 100%;
border: 2px solid blue;
margin: 0px;
}
<div class="wrapper">
<input type="text">
<div class="buttonwrap">
<button>Test</button>
</div>
</div>
Use http://autoprefixer.github.io/ to get the cross browser support you need for display: flex;
button, input, wrapper {
display: inline-block; <----- Remove "display: inline-block;"
border-radius: 3px;
}
.wrapper {
position: relative;
display: -webkit-box;<----- Add "display: flex;"
display: -webkit-flex;<----- Add "display: flex;"
display: -ms-flexbox;<----- Add "display: flex;"
display: flex;<----- Add "display: flex;"
width: 60%;
margin: 1em;
background-color: #ccc;
}
Extra reading and learning material:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
http://flexbox.io/#/
https://philipwalton.github.io/solved-by-flexbox/demos/holy-grail/
http://www.sketchingwithcss.com/samplechapter/cheatsheet.html
Note: to overide a flex rule you will need to use flex shorthand rather than specific over-ride due to current browser shortfalls eg.
.item {
flex: 0 0 300px;
}
/* overide for some reason */
.item {
flex: 1 0 300px;
}
/* NOT */
.item {
flex-grow: 1;
}
You MAY need to do an over-ride for ie11:
.ie11std .wrapper {
display:table;
}
.ie11std .item {
display:table-cell;
}
although this won't be responsive.

Resources