0

Using Bootstrap 4.1 and using an example from the docs, just switching "href" for "data-target".

Example

<ul class="nav nav-tabs" id="myTab" role="tablist">
  <li class="nav-item">
    <a class="nav-link active" id="home-tab" data-toggle="tab" data-target="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" id="profile-tab" data-toggle="tab" data-target="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" id="contact-tab" data-toggle="tab" data-target="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a>
  </li>
</ul>
<div class="tab-content" id="myTabContent">
  <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">AAA</div>
  <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">BBB</div>
  <div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">CCC</div>
</div>

Tabs are working fine on all desktop browsers I have tried, including Safari, and all Android browsers I have tried as well.

However, on all iOS devices the tabs are inactive, that is, they are not switching, neither the tab links, nor the displayed content.

Anyone have an idea what I am doing wrong, or if this is a bug in Bootstrap 4.1?

donV
  • 1,051
  • 6
  • 15

1 Answers1

2

According to HTML docs, a <a> is "interactive content" "if it has a href attribute". iOS implementation of this definition is literal and click events are ignored on anchors without href.

The proper way to enable clicks on iOS native devices is to use the id of the .tab-pane as href.
You could do it manually or you could use this lil' snippet which simply copies them from data-target, only on native iOS devices and only if the anchor does not already have a href attribute.
I haven't tested it on an iOS device but it should work:

$(window).on('load', () => {
  let iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
  if (iOS)
    $('[role="tablist"] .nav-link').each((i,e) => {
      if (!$(e).attr('href'))
        $(e).attr('href', $(e).data('target'));
    })
})

Note all Bootstrap 4 tabs examples use href attributes. Before asking about or reporting a potential Bootstrap "bug", make sure your markup is valid and not missing anything compared to the Bootstrap docs examples.


Here's a test using your markup:

$(window).on('load', () => {
  let iOSdevice = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform)
  if (iOSdevice)
    $('[role="tablist"] .nav-link').each((i,e) => {
      if (!$(e).attr('href'))
        $(e).attr('href', $(e).data('target'))
    })
})
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>

<ul class="nav nav-tabs" id="myTab" role="tablist">
  <li class="nav-item">
    <a class="nav-link active" id="home-tab" data-toggle="tab" data-target="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" id="profile-tab" data-toggle="tab" data-target="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" id="contact-tab" data-toggle="tab" data-target="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a>
  </li>
</ul>
<div class="tab-content" id="myTabContent">
  <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">AAA</div>
  <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">BBB</div>
  <div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">CCC</div>
</div>

For iOS detection I used this SO answer.

tao
  • 59,850
  • 12
  • 84
  • 110
  • Thanks for the nice solution! Regarding your comment about a "bug": The markup is valid and Bootstrap does document in the examples that "data-target" is a valid alternative to "href" and it does work. – donV Jul 05 '18 at 21:37
  • I meant invalid as interactive content. From a technical point of view, the elements are used as interactive content and, without `href`, by definition, anchors are not interactive content. No matter how popular, Bootstrap can't change that, unless they copy `data-target` to `href` at page load, to validate it (as interactive content). Even if it currently works in some browsers without `href`, the spec says it should not. Therefore I'd do the copying for all browsers, not only for iOS. – tao Jul 06 '18 at 09:06