Safari details-summary problem

This works on “every browser” (…I have tested :-)) on Mac, PC and Android but not Safari. My intention is to use a minimum of Javascript. Hence I try to use “details/summary”, but this fails on The New Internet Explorer (Safari)

My simple question is if there is a work around that lines the text correct on Safari?

My wild guess is that this flex fails on Safari.

summary {
  display: flex; <------ Does not work on Safari?
  height: 42px;
  width: 200px;
  list-style-type: none;
  outline: none;
}

Yes, I managed to fix it on Safari, but then it break all other browsers.

image

So, how do I fix it for other browsers? :slight_smile:

Finally I found a solution.

summary span{  <----added <span> tag
  display: flex;
  height: 42px;
  width: 200px;
  list-style-type: none; <---added this to make work on other browsers
  outline: none;
}

Unfortunately your code is invalid so I wouldn’t rely on any behaviours until you fix the html :slight_smile:

In a ul all content must be inside a li element.

Run your code through the html validator if you don’t know why it is wrong :slight_smile:

(It probably makes no difference to your problem but I don;t have Safari to test while I’m away.)

Is it no longer needed to have a body tag in a html file?

I’m not familiar with JSFiddle, but in Codepen you don’t need the head section or the body or html tags.

1 Like

No need for head and body in JSFiddle. Codepen and JsFiddle are about the same. The difference is that JSFiddle tells you more what is wrong and I find it easier to format. And you have to save to refresh the fiddle. It is most a personal preference IMO.

1 Like

Looking deeper into this and there seems to be some issues with Details/Summary and Safari behaviours and others have suggested using an inner element instead. (Although it does seem to work ok on Safari IOS).

There’s a timely article here that may be of interest and has a link to display problems (Lea Verou).

When I get back from my break in a couple of weeks I’ll have to do more testing on this :slight_smile:

2 Likes

I’m back now and can test on Safari and the solution was simple and took about 10 seconds :slight_smile: You just needed vertical-align:middle on the svg.

svg {
  width: 42px;
  height: 42px;
  padding-left: 0px;
  vertical-align:middle;
}

That works everywhere.:slight_smile:

(Of course your html is still wrong as you have omitted the list parents for the details/summary as already mentioned.)

No error reported by Validator.W3 :slight_smile:

It seems to work without vertical-align:middle, but thank you for your tip. It might be handy in the future…

You changed the structure on that one. I was referring to this one.

Yes but you added a non essential span. My version doesn’t need the span :slight_smile: and addresses the problem from the first post.:slight_smile:

1 Like

I was bored :slight_smile: so I was just playing around with a more semantic structure and I would have used something like this.

<nav class="mainnav" id="mainnav">
  <ul>
    <li>Row 1</li>
    <li>Row 2</li>
    <li>Row 3</li>
    <li class="sub">
      <details>
        <summary>Subnav 1</summary>
        <ul>
          <li>Subrow 1</li>
          <li>Subrow 2</li>
          <li>Subrow 3</li>
        </ul>
      </details>
    </li>
    <li class="sub">
      <details>
        <summary>Subnav 2</summary>
        <ul>
          <li>Subrow 4</li>
          <li>Subrow 5</li>
          <li>Subrow 6</li>
        </ul>
      </details>
    </li>
    <li>Row 4</li>
  </ul>
</nav>

As you called it your mainnav then it should be a nav element. Also as this is one list you shouldn’t really have multiple uls as that doesn’t make semantic sense. It should be one ul for the top level and nested uls for the second level as is the general practice for dropdown type menus.

This gives semantic structure and a more readable html in order to understand the structure. I’m not keen on lots of svgs in the markup when they could be in the css and out of the way (especially when they are basically eye candy).

I had a quick re-jig of the css and used css instead of svg but of course svg would look a little nicer but there’s no reason why they can’t be in the CSS instead.

The html is much cleaner and less likely to get broken but there is still the issue of keyboard users to contend with as you removed the outline making it impossible to navigate with the keyboard (a color change or similar would do but to remove it altogether is a cardinal sin :)).

As I said I just did this for fun and exercise and I don’t expect you to change your finished product now that you’ve moved on with it. It just may be of interest in passing.

Amazing what you can do with CSS! I have lot to learn :slight_smile:

But I have 2 follow up questions:

  1. How do you manage this if you want different icons on each level using CSS? Some of them might be more complicated than the one icon example.

  2. Can you create this menu “dynamic” from JSON data using CSS?

I am aware of that this might be possible, but is the complexity not moved from one place to another?

Yes if there are many icons then yes you probably need to use the svg in the html method as you will have more control over their fill and stroke colors although you could do them as background svg sprites it’s probably not worth the extra effort.

I would still use the structure I showed but add your svg into the mix. As the svgs are all the same size (and they all should be) then you can simplify the css without using flex and just place the images into the space as required. Either method is ok but the simpler the better.

There is still the question about keyboard accessibility to consider and also what happens if text runs to more than one line (or if restricted to one line you would need to control the overflow).

1 Like

You mean in this way?

.icn {
    float: right;
    width: 16px;
    height: 10px;
    content: "";
    background: url('#arrow-right');
}

No I think for that way to work you would need to save the svg and then you can use the background url to point to the image and its id:

.myelement {
 background: url('./sprite.svg#circle');
}

That’s explained here.

I was thinking more along the lines of something like this.

.icon{
      background-image: url("data:image/svg+xml,***<single icon encoded encoded svg goes here>***");
    }

The drawback is the fill color (and other attributes) can’t be changed unless you change the color in the encoded url.

Therefore I think the best method is still the one you are using if you want multiple svgs and gives you more control and no htttp requests for the sprites. :slight_smile:

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.