Files
ionic-framework/core/src/css/link.ionic.scss
Sean Perkins a57be0941d feat(css): global link classes for standalone and underline (#29298)
Issue number: Internal

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->

N/A

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- Adds two global classes for `.ionic-link` (standalone) and
`.ionic-link-underline` (underline) appearances.
- The global classes apply when directly applied to an anchor element
(`a`) or when used on a parent container that renders a link internally.

**Usage**

Developers will need to import the link global stylesheet at this time
to leverage the following CSS classes.

```html
<!-- Basic Usage -->
<a href="#" class="ionic-link">Standalone</a>
<a href="#" class="ionic-link-underline">Underline</a>

<!-- Nested Usage -->
<div class="ionic-link">
  <a href="#">Standalone</a>
</div>
<div class="ionic-link-underline">
  <a href="#">Underline</a>
</div>
```

**Focus and Activated States**

Developers should apply the `ion-focusable` and `ion-activatable`
classes to the anchor elements to enable proper styling on a mobile
device. For web-only usages, the fallback `:focus` and `:active` pseudo
states will apply correctly.

```html
<!-- Basic Usage -->
<a href="#" class="ionic-link ion-focusable ion-activatable">Standalone</a>
<a href="#" class="ionic-link-underline ion-focusable ion-activatable">Underline</a>
```

### Design Changes

This section is areas of the implementation that are not consistent with
the design and why.

1. Font size: Link font sizing is inherited from its content. This is to
provide visual consistency when using a link within a paragraph or
existing text content. Links should not have an explicit font size, but
can be customized by the developer if a specific font size is desired.
2. Color: `currentColor` was used in place of
`$ionic-color-neutral-900`. This is to provide better visual consistency
when a link is used within content. Text color should be set on the body
or text content, which would apply neutral-900 in places where it is
applied.
3. The text underline offset in the designs is ~3px, but all of the
design implementation is on a 4px grid. We've landed on 2px for the
offset here.

Discussed with Design and these proposed changes were verbally approved.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!--
  If this introduces a breaking change:
1. Describe the impact and migration path for existing applications
below.
  4. Update the BREAKING.md file with the breaking change.
5. Add "BREAKING CHANGE: [...]" to the commit description when merging.
See
https://github.com/ionic-team/ionic-framework/blob/main/.github/CONTRIBUTING.md#footer
for more information.
-->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
2024-04-10 16:00:03 -04:00

121 lines
2.5 KiB
SCSS

@use "../foundations/ionic.vars" as tokens;
// Link: Shared Styles (Standalone & Underline)
// -------------------------------------------------------------------------------
@mixin link-shared {
display: inline-flex;
align-items: center;
gap: 4px;
transition: color 0.2s ease-in-out;
font-weight: 400;
text-decoration-color: inherit;
text-underline-offset: 2px;
cursor: pointer;
// Link: Visited
// -------------------------------------------------------------------------------
&:visited {
color: tokens.$ionic-color-info-500;
}
}
// Link: Standalone
// -------------------------------------------------------------------------------
@mixin ionic-link {
@include link-shared;
// Link: Standalone - Hover
// -------------------------------------------------------------------------------
@media (any-hover: hover) {
&:hover {
text-decoration: underline;
}
}
color: tokens.$ionic-color-info-400;
text-decoration: none;
// Link: Standalone - Focus
// -------------------------------------------------------------------------------
&:focus,
&.ion-focused {
outline: 2px solid tokens.$ionic-color-primary-100;
outline-offset: 2px;
text-decoration: underline;
}
// Link: Standalone - Active
// -------------------------------------------------------------------------------
&:active,
&.ion-activated {
color: tokens.$ionic-color-info-500;
text-decoration: underline;
}
}
a.ionic-link,
:not(a).ionic-link a {
@include ionic-link;
}
// Link: Underline
// -------------------------------------------------------------------------------
@mixin ionic-link-underline {
@include link-shared;
// Link: Underline - Hover
// -------------------------------------------------------------------------------
@media (any-hover: hover) {
&:hover {
color: tokens.$ionic-color-info-400;
}
}
color: currentColor;
text-decoration: underline;
// Link: Underline - Focus
// -------------------------------------------------------------------------------
&:focus,
&.ion-focused {
outline: 2px solid tokens.$ionic-color-primary-100;
outline-offset: 2px;
color: currentColor;
text-decoration: none;
}
// Link: Underline - Active
// -------------------------------------------------------------------------------
&:active,
&.ion-activated {
color: tokens.$ionic-color-info-500;
}
}
a.ionic-link-underline,
:not(a).ionic-link-underline a {
@include ionic-link-underline;
}