Safari Bug :First-Child Doesn't Update Display:Block When Items Are Removed with Js

My React component does not update in the Safari browser

So I did solve the very bizarre issue after a few days.

What was happening was I guess the engine in the Safari browser was not re-rendering the little badge icon correctly. I would print out the value inside the DOM, OUTSIDE of the styled badge I was using, and the number would update as expected... Leading me to believe the issue was related to styles.

THEN after removing what I thought was the CSS causing the issue, I noticed that it looked like safari was 'partially' updating the value in the badge. It appears to have half re-rendered, and the previous number collides with the new value... Not sure if this is some obscure problem with the render engine?

Sample Image

After adding and removing all the CSS one by one, the issue remained so I decided to trick the browser to 'force' render with a simple calculation inside the grandchild where it was being rendered:

const safariRenderHack = { opacity: count % 2 ? 1 : 0.99 };

<div style={safariRenderHack}>{count}</div>

Sample Image

Not a great solution but oh well I guess it's fixed. ha

Flex items don't show in line in Webkit browsers

Why the cogwheel ends up on the second line is because of a webkit bug that does not render fieldset elements as a flexbox container

Here is a list of flexbugs mentioning the same bug: Some html elements cant be flex containers

If you add a div as an inner wrapper it will work.

<fieldset>
<div class="flex-search">
....
</div>
</fieldset>

Stack snippet

$('.flex-search input[type="radio"]').click(function() {  $(this).closest('span')    .css('display', 'none')    .delay(500)    .queue(function(next) {      $(this).removeAttr('style');      next();    });  $(this).closest('fieldset')    .find('input[type="text"]')    .attr('placeholder', $(this).closest('label').text())    .focus();});
* {  margin: 0;  padding: 0;  border: medium none;  border-spacing: 0;  outline: none;  outline: 0;  color: inherit;  font-family: inherit;  font-size: inherit;  font-weight: inherit;  line-height: inherit;  text-align: inherit;  text-decoration: none;  text-indent: 0;  list-style: none outside none;  background: none repeat scroll 0 0 transparent;}
*::-moz-focus-inner { border: 0; padding: 0;}
html { color: #222; font-family: Arial, Helvetica, sans-serif; font-size: 10px; font-weight: normal; text-align: left; height: 100%;}
body { font-size: 1.4rem; line-height: 1.5em; min-height: 100%; background-color: #fff;}
div { margin: 150px auto 0; width: 300px;}
::-webkit-input-placeholder { color: #666; font-size: 85%;}
:-moz-placeholder { color: #666; font-size: 85%;}
::-moz-placeholder { color: #666; font-size: 85%;}
:-ms-input-placeholder { color: #666; font-size: 85%;}
:focus::-webkit-input-placeholder { color: #ccc;}
:focus:-moz-placeholder { color: #ccc;}
:focus::-moz-placeholder { color: #ccc;}
:focus:-ms-input-placeholder { color: #ccc;}
.flex-search { position: relative; display: -webkit-flex; display: flex; -webkit-align-items: stretch; align-items: stretch; width: 100%; border: 1px solid #222; border-radius: .4em; background-color: #fff;}
.flex-search> :first-child { -webkit-flex: 1; flex: 1;}
.flex-search> :last-child { width: 2em; border-left: 1px solid #ccc; cursor: pointer;}
.flex-search> :last-child:after { content: '\00a0'; display: block; width: 100%; height: 100%; background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAEG0lEQVQ4EQEQBO/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhwAAAOwAAAASAAAAEgAAAOwAAACIAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQAAAADAAAAG8AAAAAAAAADAAAAM8AAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAACIAAAAEwAAAAYAAAAHAAAALwAAACQAAADRAAAA2QAAACkAAABdAAAAvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOwAAAD4AAAAsAAAAG4AAAAAAAAAAAAAAG4AAACwAAAA+AAAAOwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAIEAAADHAAAAAAAAAAAAAAAAAAAAAAAAAMcAAACBAAAAFAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOwAAAD4AAAAsAAAAG4AAAAAAAAAAAAAAG4AAACwAAAA+AAAAOwAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAiAAAAM8AAAAGAAAAVAAAABcAAAAAAAAA6QAAAKwAAAD6AAAAMQAAAHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFcAAAD4AAAAgQAAAIEAAAD4AAAAVwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhwAAAOwAAAASAAAAEgAAAOwAAACIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6eSOOoDWnnAAAAABJRU5ErkJggg==') no-repeat center center; opacity: 0.5;}
.flex-search> :last-child:hover:after { opacity: 1;}
.flex-search> :last-child> :first-child { position: absolute; right: -1px; bottom: 0; display: none; padding: 0 .25em 2.1em 0; color: #fff;}
.flex-search> :last-child:hover> :first-child { display: block; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;}
.flex-search label { display: block; cursor: pointer; background-color: #ccc;}
.flex-search label>span { position: relative; display: block; font-size: 85%; text-align: right; padding: .2em .8em .2em 30%;}
.flex-search label:hover>span,.flex-search input[type="radio"]:checked~span { color: #999; background-color: #eee;}
.flex-search input[type="radio"]:checked~span:before { position: absolute; left: .7em; content: '✔';}
.flex-search input[type="radio"] { display: none;}
.flex-search input[type="text"] { width: 100%; box-sizing: border-box; padding: .2em .8em;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div>  <fieldset>    <div class="flex-search">      <span>        <input type="text" name="id" placeholder="contains">      </span>      <span>        <span>          <label><input type="radio" name="t-id" value="c" checked="checked"><span>contains</span></label>          <label><input type="radio" name="t-id" value="s"><span>starts with</span></label>          <label><input type="radio" name="t-id" value="e"><span>ends with</span></label>          <label><input type="radio" name="t-id" value="i"><span>equals</span></label>        </span>      </span>    </div>  </fieldset></div>

iPad Safari scrolling causes HTML elements to disappear and reappear with a delay

I was using translate3d before. It produced unwanted results. Basically, it would chop off and not render elements that were offscreen, until I interacted with them. So, basically, in landscape orientation, half of my site that was offscreen was not being shown. This is a iPad web application, owing to which I was in a fix.

Applying translate3d to relatively positioned elements solved the problem for those elements, but other elements stopped rendering, once offscreen. The elements that I couldn't interact with (artwork) would never render again, unless I reloaded the page.

The complete solution:

*:not(html) {
-webkit-transform: translate3d(0, 0, 0);
}

Now, although this might not be the most "efficient" solution, it was the only one that works. Mobile Safari does not render the elements that are offscreen, or sometimes renders erratically, when using -webkit-overflow-scrolling: touch. Unless a translate3d is applied to all other elements that might go offscreen owing to that scroll, those elements will be chopped off after scrolling.

(This is the complete answer to my question. I had originally marked Colin Williams' answer as the correct answer, as it helped me get to the complete solution. A community member, @Slipp D. Thompson edited my question, after about 2.5 years of me having asked it, and told me I was abusing SO's Q & A format. He also told me to separately post this as the answer.
@Colin Williams, thank you! The answer and the article you linked out to gave me a lead to try something with CSS. So, thanks again, and hope this helps some other lost soul. This surely helped me big time!)

Why does the general-sibling combinator allow toggling pseudo-element's content, but not the adjacent-sibling?

This is a long-standing bug in WebKit browsers related to the use of certain dynamic pseudo-classes with next-sibling combinators. This happens whether you're applying styles to the sibling element itself or a pseudo-element of that sibling element.

I don't know if anybody has filed a bug report yet, but this has been seen rather frequently on the site:

  • Webkit bug with `:hover` and multiple adjacent-sibling selectors
  • CSS adjacent sibling selectors, Safari and <nav> elements

Strangely it was also reported that Chrome had issues with the general sibling combinator, but as you note it works in your given scenario:

  • Why doesn't this CSS selector work: a:hover ~ span?

So either that was fixed, or something else triggers/triggered it.

How can I force WebKit to redraw/repaint to propagate style changes?

I found some complicated suggestions and many simple ones that didn’t work, but a comment to one of them by Vasil Dinkov provided a simple solution to force a redraw/repaint that works just fine:

sel.style.display='none';
sel.offsetHeight; // no need to store this anywhere, the reference is enough
sel.style.display='';

I’ll let someone else comment if it works for styles other than “block”.

Thanks, Vasil!

Element with CSS display: none; breaking layout - causing misalignment

Scrap Approach and Use Background Images

http://jsfiddle.net/P5CKC/2/

<ul class="menu">
<li><span>Li</span></li>
<li><span>Li</span></li>
<li><span>Li</span></li>
<li class="change"><span>Li</span></li>
<li><span>Li</span></li>
</ul>

CSS

ul.menu {
overlflow: hidden;
}
ul.menu li {
float: left;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10pt;
text-align:center;
margin: 0 0 0 -25px;
width: 152px;
line-height: 35px;
height: 35px;
background: url(../bct-white.png) no-repeat;
color: #0091c1;
}
ul.menu li span {
background: url(/green.png) no-repeat 5px 6px;
display: block;
}
ul.menu li.change span {
background-image: url(/red.png);
}

CSS2.0 and browser compatibility

The code application I have provided is Css2.0 and should easily work in IE7 and above.

  1. Removed img tags and implemmented aesthetics (images) as backgrounds
  2. Extra span had to be added because CSS2 allows only 1 background image per element
  3. Li tag holds the arrow background; span tag holds the pepper background
  4. Updated id="change" to class="change". UNLESS you are 100% certain that you will only have one #change element, use a class. This is purely styling and it prevents you from having two menu lists on the same page.
  5. Tweaked your CSS styling a bit as follows:

Removed top padding and increased the height. So your li elements are the same height BUT then added line-height: 35px -> this is the best way to vertically center text. Utlizing top padding works but it is prone to poor browser inconsistency.

Change li elements to floats. Floated elements are the most IE7 friendly method! Even IE6 will not bug out but I don't have that old version to test your webpage in. FYI - ul.menu has to have overflow: hidden to clear the floats.

position: relative; 
cursor: default;

Unless you changed the defaults, you can keep these two properties out. cursor should be default. Position: relative is unnecessary - you aren't using absolute positioning or anything that warrants its need. Now, you can keep these in your declaration. I just like code to be as "slim" as possible.

final words:

Take a look at my CSS. Notice how I used ul.menu in all my declaration. You may want to get in the habit of doign the same; this provides the developer some insight on what the HTML looks like and more importantly - your css will not get overrided if you decide to add <div class=menu> later on. Specfically .menu img would apply to any image tag within the menu div.

Okay - that's it. Let me know if there are any clarfications.

FYI - seeing as this question has a bounty, if you provide me with the background images I can polish my code to suit your needs 100% - perhaps upload them in an edit of your answer.

Chrome / Safari not filling 100% height of flex parent

Solution

Use nested flex containers.

Get rid of percentage heights. Get rid of table properties. Get rid of vertical-align. Avoid absolute positioning. Just stick with flexbox all the way through.

Apply display: flex to the flex item (.item), making it a flex container. This automatically sets align-items: stretch, which tells the child (.item-inner) to expand the full height of the parent.

Important: Remove specified heights from flex items for this method to work. If a child has a height specified (e.g. height: 100%), then it will ignore the align-items: stretch coming from the parent. For the stretch default to work, the child's height must compute to auto (full explanation).

Try this (no changes to HTML):

.container {    display: flex;    flex-direction: column;    height: 20em;    border: 5px solid black}
.item { display: flex; /* new; nested flex container */ flex: 1; border-bottom: 1px solid white;}
.item-inner { display: flex; /* new; nested flex container */ flex: 1; /* new */
/* height: 100%; <-- remove; unnecessary */ /* width: 100%; <-- remove; unnecessary */ /* display: table; <-- remove; unnecessary */ }
a { display: flex; /* new; nested flex container */ flex: 1; /* new */ align-items: center; /* new; vertically center text */ background: orange;
/* display: table-cell; <-- remove; unnecessary */ /* vertical-align: middle; <-- remove; unnecessary */}
<div class="container">  <div class="item">    <div class="item-inner">      <a>Button</a>    </div>  </div>
<div class="item"> <div class="item-inner"> <a>Button</a> </div> </div>
<div class="item"> <div class="item-inner"> <a>Button</a> </div> </div></div>


Related Topics



Leave a reply



Submit