Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Engineering Beautiful and Accessible Text (360i...

Engineering Beautiful and Accessible Text (360iDev)

An integral part of design systems and style guides is typography. Typography declares how text will appear in your product by specifying the font family, size, weight, line height, etc. While much of our focus on design goes towards colors, icons, and images, text is the primary way users interact with the majority of apps. Learn how to implement typography in your apps in a way that is accurate to the source designs, fully accessible, and that makes assembling pixel perfect implementations of the source designs a breeze.

Mark Pospesel

August 29, 2022
Tweet

More Decks by Mark Pospesel

Other Decks in Technology

Transcript

  1. YML.co 3 A design and technology agency that exports Silicon

    Valley to the world. We’re YML To us it is a mindset rooted in velocity, innovation and experimentation.
  2. Typography is… • Font (font family, font weight, and font

    size) • Plus Attributes • Line height • Letter spacing • Text Decoration • Text Case • etc.
  3. Y—MatterType github.com/yml-org/YMatterType • Support line height and other typographical properties

    (letter spacing, text decorations, text cases, and more) across labels, buttons, text fi elds, and text views • Support Dynamic Type scaling and Accessibility Bold Text on custom fonts • Accelerate accurate translation of Figma designs into code by having text-based elements with the exact same intrinsic size (based upon line height) as the corresponding elements in Figma
  4. Y—MatterType github.com/yml-org/YMatterType public extension Typography { struct Body { ///

    Body / Small (14/21 pt, regular) public static let small = Typography( familyName: "NunitoSans", fontWeight: .regular, fontSize: 14, lineHeight: 21 ) } }
  5. Y—MatterType github.com/yml-org/YMatterType • Dynamic Type • Design accurate line height

    • Design accurate intrinsicContentSize • Proportional line height scaling • Accessibility Bold Text support for custom fonts
  6. Y—MatterType github.com/yml-org/YMatterType • Letter spacing (kerning) • Text case (ALL

    CAPS, lowercase, TitleCase) • Text decoration (underline, strikethrough) • Maximum scaling by point size or scale factor • … and more to come
  7. Typography Renders font + attributes using UITraitCollection • Controls can

    be unit tested across all possible combinations of • preferredContentSizeCategory • legibilityWeight
  8. YCoreUI github.com/yml-org/YCoreUI /// Determines whether the contrast between this `UIColor`

    and the provided /// `UIColor` is suf fi cient to meet the recommendations of W3's WCAG 2.0. /// /// The recommendation is that the contrast ratio between text and its /// background should be at least 4.5 : 1 for small text and at least /// 3.0 : 1 for larger text. /// - Parameters: /// - otherColor: the other color to compute contrast with /// - context: the context of the color comparison (default = `.normalText`) /// - level: the WCAG standard to test against (default = `.AA`) /// - Returns: `true` if the two colors meet the speci fi ed WCAG minimum contrast ratio, otherwise `false` /// - Warning: Combining context == `.uiComponent` and level == `.AAA` will return `false` for all color pairings /// because there is no AAA contrast threshold level de fi ned for UI Components. public func isSufficientContrast( to otherColor: UIColor, context: WCAGContext = .normalText, level: WCAGLevel = .AA ) -> Bool { let threshold = context.threshold(for: level) return contrastRatio(to: otherColor) > threshold }
  9. YCoreUI github.com/yml-org/YCoreUI /// Contrast ratio between two colors according to

    W3's WCAG 2.0: /// https://www.w3.org/TR/WCAG20/#contrast-ratiodef /// - Parameter otherColor: the color to calculate contrast ratio with /// - Returns: the contrast ratio between the two colors ranging from 1.0 (identical) to 21.0 /// (the contrast between pure white and pure black) public func contrastRatio(to otherColor: UIColor) -> CGFloat { let ourLuminance = self.luminance let theirLuminance = otherColor.luminance let lighterColor = min(ourLuminance, theirLuminance) let darkerColor = max(ourLuminance, theirLuminance) return 1 / ((lighterColor + 0.05) / (darkerColor + 0.05)) }
  10. YCoreUI github.com/yml-org/YCoreUI /// Relative luminance of a color according to

    W3's WCAG 2.0: /// https://www.w3.org/TR/WCAG20/#relativeluminancedef private var luminance: CGFloat { let rgba = rgbaComponents return 0.2126 * inverseGammasRGB(rgba.red) + 0.7152 * inverseGammasRGB(rgba.green) + 0.0722 * inverseGammasRGB(rgba.blue) }
  11. YCoreUI github.com/yml-org/YCoreUI /// Helper method for calculations used in `luminance`

    private func inverseGammasRGB(_ channelValue: CGFloat) -> CGFloat { if channelValue <= 0.03928 { return channelValue / 12.92 } return pow(((channelValue + 0.055) / 1.055), 2.4) }
  12. UIColor.isSufficientContrast(to:context:level:) Renders using UITraitCollection • Pairings of foreground and background

    colors can be unit tested across all possible combinations of • userInterfaceStyle • accessibilityContrast
  13. Making Text Accessible • accessibility labels • accessibility hints •

    Dynamic Type • Bold Text • Color (WCAG) • Dark Mode • Increased Contrast
  14. Parting thoughts • Never constrain width or height of any

    view that contains text • Device size • Device orientation • Localization • Dynamic Type
  15. Parting thoughts • Never constrain width or height of any

    view that contains text • Every full-screen view is a scroll view • What happens to your view when it is: • Scaled to accessibilityExtraExtraExtraLarge • Rotated to Landscape • On an iPhone SE1 (or an iPhone 8 in Zoomed display mode) • Localized in German (or any other “verbose” language) • With the keyboard visible
  16. Engineering Beautiful and Accessible Text 29 August 2022 • Mark

    Pospesel • @mpospese • Feedback appreciated! • Repos: • github.com/yml-org/YMatterType • github.com/yml-org/YCoreUI