mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-23 10:53:34 +03:00
Content card design improvements (#19737)
refs. https://linear.app/tryghost/issue/DES-122/bookmark-card-issues This PR addresses the following content card related problems: 1. The design of the following cards are more self-contained so it makes more sense to use `px` for their font-sizes and spacings so it looks the same regardless of the theme. Of course themes still can override these values. Updated cards to use `px` for font sizing: - audio - bookmark - file - product 2. So far header and signup cards had been using `rem` for font-sizes and some sizing. This commit updates these to use `em` instead so that it's consistent with all other cards. 3. The favicon sometimes is not available for bookmark cards. This PR also fixes that by providing a default favicon for these cases.
This commit is contained in:
parent
c7e475feb0
commit
8f3617aaa8
@ -7,7 +7,8 @@
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 96px;
|
||||
border-radius: 3px;
|
||||
border-radius: 6px;
|
||||
padding: 4px;
|
||||
box-shadow: inset 0 0 0 1px rgba(124, 139, 154, 0.25);
|
||||
}
|
||||
|
||||
@ -25,7 +26,7 @@
|
||||
background: transparent;
|
||||
object-fit: cover;
|
||||
aspect-ratio: 1/1;
|
||||
border-radius: 2px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.kg-audio-thumbnail.placeholder {
|
||||
@ -55,8 +56,8 @@
|
||||
padding: 8px 12px;
|
||||
border: none;
|
||||
font-family: inherit;
|
||||
font-size: 1.15em;
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 1.15em;
|
||||
background: transparent;
|
||||
}
|
||||
@ -72,9 +73,9 @@
|
||||
min-width: 38px;
|
||||
padding: 0 4px;
|
||||
font-family: inherit;
|
||||
font-size: .85em;
|
||||
font-size: 12.5px;
|
||||
font-weight: 500;
|
||||
line-height: 1.4em;
|
||||
line-height: 1em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@ -82,9 +83,9 @@
|
||||
width: 56px;
|
||||
color: #ababab;
|
||||
font-family: inherit;
|
||||
font-size: .85em;
|
||||
font-size: 12.5px;
|
||||
font-weight: 500;
|
||||
line-height: 1.4em;
|
||||
line-height: 1em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@ -127,9 +128,9 @@
|
||||
min-width: 37px;
|
||||
padding: 0 4px;
|
||||
font-family: inherit;
|
||||
font-size: .85em;
|
||||
font-size: 12.5px;
|
||||
font-weight: 600;
|
||||
line-height: 1.4em;
|
||||
line-height: 1em;
|
||||
text-align: left;
|
||||
background: transparent;
|
||||
white-space: nowrap;
|
||||
|
@ -13,7 +13,7 @@
|
||||
.kg-bookmark-card a.kg-bookmark-container:hover {
|
||||
display: flex;
|
||||
text-decoration: none;
|
||||
border-radius: 3px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid rgb(124 139 154 / 25%);
|
||||
overflow: hidden;
|
||||
color: inherit;
|
||||
@ -31,14 +31,14 @@
|
||||
}
|
||||
|
||||
.kg-bookmark-title {
|
||||
font-size: 1.5rem;
|
||||
font-size: 15px;
|
||||
line-height: 1.4em;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.kg-bookmark-description {
|
||||
display: -webkit-box;
|
||||
font-size: 1.4rem;
|
||||
font-size: 14px;
|
||||
line-height: 1.5em;
|
||||
margin-top: 3px;
|
||||
font-weight: 400;
|
||||
@ -54,7 +54,7 @@
|
||||
align-items: center;
|
||||
margin-top: 22px;
|
||||
width: 100%;
|
||||
font-size: 1.4rem;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
@ -12,10 +12,10 @@
|
||||
align-items: stretch;
|
||||
justify-content: space-between;
|
||||
color: inherit;
|
||||
padding: 6px;
|
||||
padding: 12px;
|
||||
min-height: 92px;
|
||||
border: 1px solid rgb(124 139 154 / 25%);
|
||||
border-radius: 3px;
|
||||
border-radius: 5px;
|
||||
transition: all ease-in-out 0.35s;
|
||||
text-decoration: none;
|
||||
width: 100%;
|
||||
@ -34,26 +34,27 @@
|
||||
}
|
||||
|
||||
.kg-file-card-title {
|
||||
font-size: 1.15em;
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 1.3em;
|
||||
}
|
||||
|
||||
.kg-file-card-caption {
|
||||
font-size: 0.95em;
|
||||
font-size: 14px;
|
||||
line-height: 1.3em;
|
||||
opacity: 0.6;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.kg-file-card-title + .kg-file-card-caption {
|
||||
margin-top: -3px;
|
||||
flex-grow: 1;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.kg-file-card-metadata {
|
||||
display: inline;
|
||||
font-size: 0.825em;
|
||||
font-size: 14px;
|
||||
line-height: 1.3em;
|
||||
margin-top: 2px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.kg-file-card-filename {
|
||||
@ -63,14 +64,15 @@
|
||||
|
||||
.kg-file-card-filesize {
|
||||
display: inline-block;
|
||||
font-size: 0.925em;
|
||||
font-size: 14px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.kg-file-card-filesize:before {
|
||||
display: inline-block;
|
||||
content: "\2022";
|
||||
margin-right: 4px;
|
||||
margin-left: 6px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.kg-file-card-icon {
|
||||
@ -81,6 +83,7 @@
|
||||
width: 80px;
|
||||
min-width: 80px;
|
||||
height: 100%;
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
.kg-file-card-icon:before {
|
||||
@ -94,7 +97,7 @@
|
||||
background: currentColor;
|
||||
opacity: 0.06;
|
||||
transition: opacity ease-in-out 0.35s;
|
||||
border-radius: 2px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.kg-file-card a.kg-file-card-container:hover .kg-file-card-icon:before {
|
||||
@ -123,7 +126,7 @@
|
||||
}
|
||||
|
||||
.kg-file-card-small .kg-file-card-metadata {
|
||||
font-size: 1.0em;
|
||||
font-size: 14px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@
|
||||
|
||||
.kg-content-wide .kg-header-card-content .kg-header-card-image {
|
||||
height: 100%;
|
||||
padding: 8rem 0;
|
||||
padding: 5.6em 0;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
@ -112,22 +112,22 @@
|
||||
|
||||
.kg-header-card h2.kg-header-card-heading {
|
||||
margin: 0;
|
||||
font-size: clamp(2.4rem, 4vw, 3.6rem);
|
||||
font-size: clamp(1.7em, 4vw, 2.5em);
|
||||
font-weight: 700;
|
||||
line-height: 1em;
|
||||
line-height: 1.05em;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.kg-header-card.kg-width-wide h2.kg-header-card-heading {
|
||||
font-size: clamp(2.4rem, 5vw, 4.8rem);
|
||||
font-size: clamp(1.7em, 5vw, 3.3em);
|
||||
}
|
||||
|
||||
.kg-header-card.kg-width-full h2.kg-header-card-heading {
|
||||
font-size: clamp(2.8rem, 5.6vw, 6rem);
|
||||
font-size: clamp(1.9em, 5.6vw, 4.2em);
|
||||
}
|
||||
|
||||
.kg-header-card.kg-width-full.kg-layout-split h2.kg-header-card-heading {
|
||||
font-size: clamp(2.8rem, 4vw, 4.8rem);
|
||||
font-size: clamp(1.9em, 4vw, 3.3em);
|
||||
}
|
||||
|
||||
/* Subheading */
|
||||
@ -139,7 +139,7 @@
|
||||
.kg-header-card .kg-header-card-subheading {
|
||||
max-width: 40em;
|
||||
margin: 0;
|
||||
font-size: clamp(1.05em, 2vw, 2rem);
|
||||
font-size: clamp(1.05em, 2vw, 1.4em);
|
||||
font-weight: 500;
|
||||
line-height: 1.2em;
|
||||
}
|
||||
@ -153,23 +153,24 @@
|
||||
}
|
||||
|
||||
.kg-header-card.kg-width-wide .kg-header-card-subheading {
|
||||
font-size: clamp(1.05em, 2vw, 2.2rem);
|
||||
font-size: clamp(1.05em, 2vw, 1.55em);
|
||||
}
|
||||
|
||||
.kg-header-card.kg-width-full .kg-header-card-subheading:not(.kg-layout-split .kg-header-card-subheading) {
|
||||
max-width: min(65vmax, 1200px);
|
||||
font-size: clamp(1.05em, 2vw, 2.4rem);
|
||||
font-size: clamp(1.05em, 2vw, 1.7em);
|
||||
}
|
||||
|
||||
.kg-header-card.kg-width-full.kg-layout-split .kg-header-card-subheading {
|
||||
font-size: clamp(1.05em, 2vw, 2.2rem);
|
||||
font-size: clamp(1.05em, 2vw, 1.55em);
|
||||
}
|
||||
|
||||
.kg-header-card.kg-v2 .kg-header-card-button {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
height: 4.6rem;
|
||||
height: 2.9em;
|
||||
min-height: 46px;
|
||||
padding: 0 1.2em;
|
||||
outline: none;
|
||||
border: none;
|
||||
@ -243,15 +244,15 @@
|
||||
}
|
||||
|
||||
.kg-content-wide .kg-header-card-content .kg-header-card-image {
|
||||
padding: 2.4rem 0 0;
|
||||
padding: 1.7em 0 0;
|
||||
}
|
||||
|
||||
.kg-content-wide.kg-swapped .kg-header-card-content .kg-header-card-image {
|
||||
padding: 0 0 2.4rem;
|
||||
padding: 0 0 1.7em;
|
||||
}
|
||||
|
||||
.kg-header-card.kg-v2 .kg-header-card-button {
|
||||
height: 4.2rem;
|
||||
height: 2.9em;
|
||||
}
|
||||
|
||||
.kg-header-card.kg-v2.kg-width-wide .kg-header-card-button,
|
||||
|
@ -36,8 +36,8 @@
|
||||
.kg-product-card h4.kg-product-card-title {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
font-size: 1.4em;
|
||||
font-weight: 600;
|
||||
font-size: 21px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
line-height: 1.15em;
|
||||
@ -51,7 +51,7 @@
|
||||
.kg-product-card .kg-product-card-description ol,
|
||||
.kg-product-card .kg-product-card-description ul {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
||||
font-size: 0.95em;
|
||||
font-size: 14px;
|
||||
line-height: 1.5em;
|
||||
opacity: .7;
|
||||
margin-bottom: 0;
|
||||
@ -94,7 +94,7 @@
|
||||
}
|
||||
|
||||
.kg-product-card-rating-star {
|
||||
height: 28px;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
@ -116,14 +116,14 @@
|
||||
position: static;
|
||||
align-items: center;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
||||
font-size: 0.95em;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 1em;
|
||||
text-decoration: none;
|
||||
width: 100%;
|
||||
height: 2.4em;
|
||||
border-radius: 5px;
|
||||
padding: 0 1.2em;
|
||||
height: 38px;
|
||||
border-radius: 6px;
|
||||
padding: 0 12px;
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@
|
||||
|
||||
.kg-content-wide .kg-signup-card-content .kg-signup-card-image {
|
||||
height: 100%;
|
||||
padding: 8rem 0;
|
||||
padding: 5.6em 0;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
@ -105,22 +105,22 @@
|
||||
|
||||
.kg-signup-card h2.kg-signup-card-heading {
|
||||
margin: 0;
|
||||
font-size: clamp(2.4rem, 4vw, 3.6rem);
|
||||
font-size: clamp(1.7em, 4vw, 2.5em);
|
||||
font-weight: 700;
|
||||
line-height: 1em;
|
||||
line-height: 1.05em;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.kg-signup-card.kg-width-wide h2.kg-signup-card-heading {
|
||||
font-size: clamp(2.4rem, 5vw, 4.8rem);
|
||||
font-size: clamp(1.7em, 5vw, 3.3em);
|
||||
}
|
||||
|
||||
.kg-signup-card.kg-width-full h2.kg-signup-card-heading {
|
||||
font-size: clamp(2.8rem, 5.6vw, 6rem);
|
||||
font-size: clamp(1.9em, 5.6vw, 4.2em);
|
||||
}
|
||||
|
||||
.kg-signup-card.kg-width-full.kg-layout-split h2.kg-signup-card-heading {
|
||||
font-size: clamp(2.8rem, 4vw, 4.8rem);
|
||||
font-size: clamp(1.9em, 4vw, 3.3em);
|
||||
}
|
||||
|
||||
/* Subheading */
|
||||
@ -132,7 +132,7 @@
|
||||
.kg-signup-card .kg-signup-card-subheading {
|
||||
max-width: 40em;
|
||||
margin: 0;
|
||||
font-size: clamp(1.05em, 2vw, 2rem);
|
||||
font-size: clamp(1.05em, 2vw, 1.4em);
|
||||
font-weight: 500;
|
||||
line-height: 1.2em;
|
||||
}
|
||||
@ -146,16 +146,16 @@
|
||||
}
|
||||
|
||||
.kg-signup-card.kg-width-wide .kg-signup-card-subheading {
|
||||
font-size: clamp(1.05em, 2vw, 2.2rem);
|
||||
font-size: clamp(1.05em, 2vw, 1.55em);
|
||||
}
|
||||
|
||||
.kg-signup-card.kg-width-full .kg-signup-card-subheading:not(.kg-layout-split .kg-signup-card-subheading) {
|
||||
max-width: min(65vmax, 1200px);
|
||||
font-size: clamp(1.05em, 2vw, 2.4rem);
|
||||
font-size: clamp(1.05em, 2vw, 1.7em);
|
||||
}
|
||||
|
||||
.kg-signup-card.kg-width-full.kg-layout-split .kg-signup-card-subheading {
|
||||
font-size: clamp(1.05em, 2vw, 2.2rem);
|
||||
font-size: clamp(1.05em, 2vw, 1.55em);
|
||||
}
|
||||
|
||||
/* Subscribe form */
|
||||
@ -203,7 +203,8 @@
|
||||
|
||||
.kg-signup-card-input {
|
||||
width: 100%;
|
||||
height: 4.6rem;
|
||||
height: 2.9em;
|
||||
min-height: 46px;
|
||||
margin: 0 3px 0 0;
|
||||
padding: 12px 16px;
|
||||
border: none;
|
||||
@ -220,7 +221,8 @@
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
height: 4.6rem;
|
||||
height: 2.9em;
|
||||
min-height: 46px;
|
||||
padding: 0 1.2em;
|
||||
outline: none;
|
||||
border: none;
|
||||
@ -355,21 +357,21 @@
|
||||
}
|
||||
|
||||
.kg-content-wide .kg-signup-card-content .kg-signup-card-image {
|
||||
padding: 2.4rem 0 0;
|
||||
padding: 1.7em 0 0;
|
||||
}
|
||||
|
||||
.kg-content-wide.kg-swapped .kg-signup-card-content .kg-signup-card-image {
|
||||
padding: 0 0 2.4rem;
|
||||
padding: 0 0 1.7em;
|
||||
}
|
||||
|
||||
.kg-signup-card-input {
|
||||
height: 4.2rem;
|
||||
height: 2.9em;
|
||||
padding: 6px 12px;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.kg-signup-card-button {
|
||||
height: 4.2rem;
|
||||
height: 2.9em;
|
||||
}
|
||||
|
||||
.kg-signup-card.kg-width-wide .kg-signup-card-button,
|
||||
|
@ -82,7 +82,7 @@
|
||||
padding: 0 4px;
|
||||
color: #fff;
|
||||
font-family: inherit;
|
||||
font-size: .85em;
|
||||
font-size: 12.5px;
|
||||
font-weight: 500;
|
||||
line-height: 1.4em;
|
||||
white-space: nowrap;
|
||||
@ -91,7 +91,7 @@
|
||||
.kg-video-time {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-family: inherit;
|
||||
font-size: .85em;
|
||||
font-size: 12.5px;
|
||||
font-weight: 500;
|
||||
line-height: 1.4em;
|
||||
white-space: nowrap;
|
||||
@ -142,7 +142,7 @@
|
||||
padding: 0 4px;
|
||||
color: #fff;
|
||||
font-family: inherit;
|
||||
font-size: .85em;
|
||||
font-size: 12.5px;
|
||||
font-weight: 600;
|
||||
line-height: 1.4em;
|
||||
text-align: left;
|
||||
|
@ -221,6 +221,35 @@ describe('Oembed API', function () {
|
||||
|
||||
should.exist(res.body.errors);
|
||||
});
|
||||
|
||||
it('should replace icon URL when it returns 404', async function () {
|
||||
// Mock the page so it contains a readable icon URL
|
||||
const pageMock = nock('http://example.com')
|
||||
.get('/page-with-icon')
|
||||
.reply(
|
||||
200,
|
||||
'<html><head><title>TESTING</title><link rel="icon" href="http://example.com/icon.svg"></head><body></body></html>',
|
||||
{'content-type': 'text/html'}
|
||||
);
|
||||
|
||||
// Mock the icon URL to return 404
|
||||
nock('http://example.com/')
|
||||
.head('/icon.svg')
|
||||
.reply(404);
|
||||
|
||||
const url = encodeURIComponent(' http://example.com/page-with-icon\t '); // Whitespaces are to make sure urls are trimmed
|
||||
const res = await request.get(localUtils.API.getApiQuery(`oembed/?url=${url}&type=bookmark`))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
.expect(200);
|
||||
|
||||
// Check that the icon URL mock was loaded
|
||||
pageMock.isDone().should.be.true();
|
||||
|
||||
// Check that the substitute icon URL is returned in place of the original
|
||||
res.body.metadata.icon.should.eql('https://static.ghost.org/v5.0.0/images/link-icon.svg');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with unknown provider', function () {
|
||||
|
@ -259,6 +259,15 @@ class OEmbedService {
|
||||
});
|
||||
}
|
||||
|
||||
if (metadata.icon) {
|
||||
try {
|
||||
await this.externalRequest.head(metadata.icon);
|
||||
} catch (err) {
|
||||
metadata.icon = 'https://static.ghost.org/v5.0.0/images/link-icon.svg';
|
||||
logging.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
version: '1.0',
|
||||
type: 'bookmark',
|
||||
|
Loading…
Reference in New Issue
Block a user