{"id":2116,"date":"2026-09-27T13:28:20","date_gmt":"2026-09-27T12:28:20","guid":{"rendered":"https:\/\/cerovac.com\/a11y\/?p=2116"},"modified":"2026-09-28T21:45:19","modified_gmt":"2026-09-28T20:45:19","slug":"sorry-for-this-but-please-avoid-lists-in-content-of-mobile-apps","status":"publish","type":"post","link":"https:\/\/cerovac.com\/a11y\/2026\/09\/sorry-for-this-but-please-avoid-lists-in-content-of-mobile-apps\/","title":{"rendered":"Sorry for this &#8211; but please avoid lists in content of mobile apps"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Please don&#8217;t kill the messenger! When <a href=\"https:\/\/cerovac.com\/a11y\/accessibility-services\/\" data-type=\"page\" data-id=\"1513\">I audit accessibility of native mobile apps<\/a>, I often stumble on this problem and I decided to write it down.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Short story &#8211; lists like we know and love them in documents and on the web (web documents and apps) do not exist on native mobile apps. Well, at least not on iOS. Sure, if you use web view you can still have them and they work, but <strong>on native &#8220;native&#8221; iOS you will not find a semantic list for content like you are used to see on the web<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is most certainly also the reason for frameworks like React Native to lack semantics for lists. Because they can not really fake it&#8230;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">But there is List in iOS<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">But, Bogdan, iOS does offer <code>List<\/code> components, you may say.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Indeed it does, but it is not meant for content in the same way as we use <code>&lt;ul><\/code> and <code>&lt;ol><\/code>. If you have seen iOS Settings &#8211; that is the List they are kind of referring to.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">many apps use lists to express an overall information hierarchy and help people navigate it<\/p>\n<cite><a href=\"https:\/\/developer.apple.com\/design\/human-interface-guidelines\/lists-and-tables\" target=\"_blank\" rel=\"noopener\">Apple Human Interface Guidelines on lists and tables (opens in new window)<\/a>.<\/cite><\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">So basically &#8211; List is not quite just a list. It is way more and it is designed to be like that on purpose. We may disagree, but it is a fact. We may, in theory, use List to make a old school list, <strong>but to my knowledge we can not style it to be seen as a part of the content<\/strong> &#8211; we can not make it look and feel like the one on the web.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What about FlatList and SectionList in React Native?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Well, theoretically they seem appropriate. Until you check them with accessibility tools and assistive technology.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Both <code>FlatList<\/code> and <code>SectionList<\/code> bear a promise of semantics at first sight, but lack it when I tested them with VoiceOver (at the time of writing this post at least).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Unfortunately the <code>SectionList<\/code> includes also headings that are not announced as headings, so I must strongly advise against using it at the moment.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Faking a list is dangerous<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once again you can quickly argue that we can always use <code>VStack<\/code> and nest <code>HStack<\/code>, or make a loop with output, and just make a list like that looks identical to <code>&lt;ul><\/code> and <code>&lt;ol><\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sure, you can fake it with different technologies, overriding visual content, adding visual bullets and style it as a list, but you can and probably will introduce accessibility issues by doing so. The behavior with assistive technologies will be broken. And you will most probably make an unequal experience for people that can see the screen and people that use a screen reader.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Info and relationships<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Faking a list visually can work, but then we need to convey information, structure and relationships in text. I will deliberately not provide any examples here, because this is a typical &#8220;it depends&#8221; scenario.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Just some clues, in a list:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Is the order of items meaningless or is it vital to have the items in order?<\/li>\n\n\n\n<li>List size is always important in my book, but is it really in your case?<\/li>\n\n\n\n<li>Are we perhaps nesting lists in lists?<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">So, in theory, we can fake a list and describe it with text. But I am quite confident that the user interface design plan was just a list originally (probably copied from a webpage or document).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What to do with lists on native apps then?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">On Android &#8211; you have much more freedom (please check <a href=\"https:\/\/developer.android.com\/develop\/ui\/compose\/accessibility\/semantics#list-item-info\" target=\"_blank\" rel=\"noopener\">List and item information (opens in new window)<\/a>).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But on iOS &#8211; this is the <strong>time for the famous it depends<\/strong>, sorry. Sometimes we can fake them and make them individually focusable, sometimes we add a heading, for example &#8220;12 favorite products&#8221; before such a list.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The problem is position in set, especially when it is vital info. Perhaps having it in text works then.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When we (try to) operate across platforms, we can now quickly recognize that even if we can re-use the same content for documents, web and Android, we get into trouble with iOS in this case.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Personally I find it almost impossible to understand the decision made to not have a semantic list for content, like we have on the web, but we need to make our best to make things work for people.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Native mobile apps are obviously not web (for better and worse) and we need to design for them specifically for best usability and accessibility by understanding the platform. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Even better &#8211; co-design with people with disabilities and accessibility specialists.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Lists in web (documents) are often extremely useful, no doubt. Mobile apps seem to disagree and if we try to make a list in the content of a mobile app we may introduce a barrier to people using assistive tech. At least on iOS&#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[123,503],"tags":[80,932,90,821,479,239,242,933,29,509],"class_list":["post-2116","post","type-post","status-publish","format-standard","hentry","category-accessibility-testing","category-native-mobile-apps-accessibility","tag-en-301-549","tag-flatlist","tag-ios","tag-list","tag-native","tag-native-mobile-application","tag-react-native","tag-sectionlist","tag-wcag","tag-wcag-1-3-1"],"_links":{"self":[{"href":"https:\/\/cerovac.com\/a11y\/wp-json\/wp\/v2\/posts\/2116","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cerovac.com\/a11y\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cerovac.com\/a11y\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cerovac.com\/a11y\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/cerovac.com\/a11y\/wp-json\/wp\/v2\/comments?post=2116"}],"version-history":[{"count":3,"href":"https:\/\/cerovac.com\/a11y\/wp-json\/wp\/v2\/posts\/2116\/revisions"}],"predecessor-version":[{"id":2120,"href":"https:\/\/cerovac.com\/a11y\/wp-json\/wp\/v2\/posts\/2116\/revisions\/2120"}],"wp:attachment":[{"href":"https:\/\/cerovac.com\/a11y\/wp-json\/wp\/v2\/media?parent=2116"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cerovac.com\/a11y\/wp-json\/wp\/v2\/categories?post=2116"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cerovac.com\/a11y\/wp-json\/wp\/v2\/tags?post=2116"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}