In my Vue app, I’m using JointJS to create a process diagram.
Everything works fine on Chrome – both locally and in the testing environment.
On Safari, it also works fine locally, but after being deployed to the testing environment – styles break.
There are 2 elements in the process (we can call them “Input” and “Output”), which contain a list of items inside. In case there are too many items, I want to be able to scroll – therefore, I’ve added overflow-y: auto; to the div styles. Instead, those items are rendered in the top-left corner of the canvas for some reason.
I’ve read that there are some issues with overflow-y: auto; on Safari, so I’ve changed it to overflow-y: scroll; – but it doesn’t help. Seems like for some reason scroll doesn’t work – just on Safari & testing environment… any idea how to solve it?
Everything works well when I’m removing overflow-y: scroll; line:

… or, keeping it, but removing some element from the list, so it prevents overflowing:

Unfortunately, scrolling is essential here.
Here’s a function responsible for generating those 2 elements:
const generateMassDataHtml = (title, massData = null, totalMass = null) => `
<div style="height: ${unitOpHeight}px; padding: 10px 16px; width: 100%; overflow-y: ${isSafari ? 'scroll' : 'auto'};">
<p style="text-align: center; ${textLabelStyle} font-weight: 600; margin-bottom: 4px;">${title}</p>
<hr style="border: none; border-top: 1px solid #e0e0e0; margin: 0 0 10px 0;">
${
this.hasResults && massData && totalMass
? Object.entries(massData).map(([name, mass]) => `
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center; margin-bottom: 8px;">
<p style="text-align: center; ${textLabelStyle} font-weight: 500; margin-bottom: 0;">${name}</p>
${
this.isFree && mass.component
? `<span style="${getHiddenValueBlockStyle()}"></span>`
: `<p style="text-align: center; ${textValueStyle} margin-bottom: 0;">${mass.value.toLocaleString('en-US', { maximumFractionDigits: 0 })} kg</p>`
}
</div>
`).join('') + `
<p style="text-align: center; ${textLabelStyle} font-weight: 500; margin-bottom: 0;">Total Mass:</p>
<p style="text-align: center; ${textValueStyle}; margin-bottom: 0;">${totalMass.toLocaleString('en-US', { maximumFractionDigits: 0 })} kg</p>
`
: this.hasConfiguration
? `<p style="text-align: center; ${textLabelStyle} margin-top: 20px;">No results can be calculated, please reconfigure the process parameters</p>`
: `<p style="text-align: center; ${textLabelStyle} margin-top: 20px;">No process parameters configured</p>`
}
</div>
`
…
const input = new joint.shapes.standard.Rectangle()
input.resize(unitOpWidth, unitOpHeight)
const inputX = xStart + (stepWidth * (elementsCount % unitsPerRow))
const inputY = yStart + (Math.floor(elementsCount / unitsPerRow) * (unitOpHeight + yGap))
input.position(inputX, inputY)
elementsCount++
input.markup = [
{ tagName: 'rect', selector: 'body' },
{
tagName: 'foreignObject',
selector: 'fo',
attributes: { width: unitOpWidth, height: unitOpHeight },
children: [
{
namespaceURI: 'http://www.w3.org/1999/xhtml',
tagName: 'div',
selector: 'htmlContent',
attributes: { style: unitOpCardStyle }
}
]
}
]
const inputHtml = generateMassDataHtml('DSP Input', this.hasResults ? this.massData.input : null, this.hasResults ? this.results.input.mass : null)
input.attr({
body: { fill: '#fff', rx: 16, ry: 16, stroke: '#e0e0e0' },
fo: { width: unitOpWidth, height: unitOpHeight },
htmlContent: { html: inputHtml }
})
input.addTo(this.graph)


