Panel with Collapsible Set and Listview set to em25 too wide in 'Overlay' Mode - jquery-mobile

I have some nested recursive functions which dynamically create collapsible with listviews that are in a side panel. I found the default 17em to be too small, especially as the nested text starts to get short. So I found the styles in the css which set it and I overrode those to use 25em. This might be a bit too much after testing on some devices. However I digress.
The thing I am here to ask is why my collapsible overflows the panel when I use data-display="overlay", when I set it to 'reveal' it looks fine. I thought it might be all my nested content, so I made a fiddle with static content here: http://jsfiddle.net/LF6UR/
<div data-role="panel" id="left-panel" data-display="overlay" data-position="left" data-position-fixed="true" data-swipe-close="true" data-dismissible="true">
and I can see it is not that, perhaps there is some other CSS property for the panel that I am not aware of. There seem to be lots of niggly little settings to get to know with this framework. Hope someone out there can help because I really think 'overlay' is better than pushing my main content area.

jQM adds a negative left and right margin to collapsibles within the collapsible set. You can override the margin like this:
.ui-collapsible-set .ui-collapsible{
margin-left: 0;
margin-right: 0;
}
Updated FIDDLE
Also, changing your collapsible set to data-inset="true" fixes the issue.

a solution without setting collapsibles to inset...which is important because I have nested collapsibles is to simply set the 'magic' .ui-panel-inner class which JQM puts in as an 'enhancement' but which makes it a bit difficult for traditional webdevelopers to know to apply styles to their controls.
.ui-panel-inner {
/*width: 25em;*/
padding: .2em 1.2em;
}
http://jsfiddle.net/magister/LF6UR/8/

Related

Is there any way to use composition to alter the CSS of an web-component with a shadow dom?

my team lead has decided to use LitElement to create framework-agnostic web components, which makes sense, as we're creating a company-wide UI library that would be ideal to be used with Vue2, Vue3, React, Preact, and others.
However, I'm extremely worried about styling. Right now with our current (Vue 2) based UI library, if one of our teams needs to override the internal styling of an element for whatever reason (usually edge cases), one of the things they can do is use CSS Composition in order to do exactly that. Something like:
// in components/my-element.js
class MyElement extends LitElement {
render(){
return html`
<div class="stackui-my-element">
<p class="paragraph">A paragraph</p>
</div>
`;
}
}
customElements.define('my-element', MyElement);
// in app/businessthing.js
import React from 'react';
import {css} from 'styled-components'
const customCSS = css`
.this-thing {
& .stackui-my-element .paragraph {
border: 2px dotted pink;
}
}
`
export default (props) => <div class="this-thing"><my-element /></div>
As far as I can tell, the above code won't work ("My Paragraph" would not be surrounded with pink polka dots) because MyElement has its own shadow dom, and you can't reach in it from without to change the styles of the element.
Is there some sort of exception to the rule, or can you reach inside the shadow dom somehow? Other than losing CSS encapsulation, what are the other effects of disabling the shadow dom?
As you mention, when using Shadow DOM, style encapsulation would prevent users of the component from affecting the styling of the component's internals.
However, there are several ways to achieve what you want with different degrees of flexibility, all of them are part of how the Shadow DOM spec behaves and not Lit-specific, so, you could use this with Vanilla Web Components or components created with other libraries too.
Which of the following ways works better will depend on how strict you want to enforce styling rules for your component.
All the samples below will assume the internal DOM of the component looks like your sample
<div class="stackui-my-element">
<p class="paragraph">A paragraph</p>
</div>
Use custom CSS properties (CSS variables)
This approach is good when you want to limit the customization to only specific parts.
For example, to allow for the user to only be able to change the border for the paragraph, you could use a CSS variable with a fallback for the border in the style for your component's shadow DOM like this:
.paragraph {
border: var(--myel-paragraph-border, 1px solid black);
}
And then, users who wish to customize said border could just change the value for that CSS variable through inline styles or a class.
<style>
.fancy-border {
--myel-paragraph-border: 2px dotted pink;
}
</style>
<my-element class="fancy-border"></my-element>
The biggest limitation of this approach is that you would need to add a CSS variable for every property you wish to allow to be customized.
However, this can be an advantage for some use cases (like say, strict design systems) because it will not allow users to customize anything you don't wish to customize.
Use Shadow Parts
Shadow parts are one of the newer parts of the shadow DOM spec but browser support is pretty good by this point. They allow you to define arbitrary parts of your component you wish to be fully customizable from outside the shadow DOM.
To use them, you need to add the part attribute to the HTML node you wish to define as the part.
<div class="stackui-my-element">
<p part="paragraph" class="paragraph">A paragraph</p>
</div>
And when using the component, add the ::part() selector to the styles so that you can customize that specific part rather than the component host. It works pretty similar to how you would styles things such as a native input placeholder and so on.
<style>
.fancy::part(paragraph) {
/* you can do whatever you want here */
border: 2px dotted pink;
color: blue;
font-style: italic;
}
</style>
<my-element class="fancy"></my-element>
As you can see, shadow parts will allow you to override every style applied to the node, so, you must be careful when to use them as users might end up being able to customize things you don't want them too.
Final notes:
You could also achieve a similar thing using slots, but that might not be an easy change considering the contents of your question.
Here's an article in case you want more info on how styling Shadow DOM from outside the component works. (Disclaimer: I'm the author of that article.)

Xpages NamePicker dialog alignment and width

<xe:namePicker id="npUserNames" for="hdnUserNames">
<xe:this.dataProvider>
<xe:dominoViewNamePicker viewName="Techs"></xe:dominoViewNamePicker>
</xe:this.dataProvider>
</xe:namePicker>
The Names in the left box of the dialog are center aligned. Same with the right (selected values) box.
I have tried text-align: left css in every possible surrounding element...The table cell, the table it is in, the surrounding div tag, the panel, the layout, the entire xpage. And the content of the namepicker dialog is still centered. How do I fix that? How can I specify the width of the dialog box?
Also, in IE11, the "X" button does not work. Nothing happens when you click it.
I'd recommend interrogating the HTML generated using your browser's developer tools to see if there's a class defined for the relevant HTML tags that you can override. If so, you can use that. If not, you may need to create your own Renderer or extension of the Name Picker to generate different HTML. That will be more complicated, but the trade-off of any framework is limited configurability at the cost of quicker development.
I'm not doing exactly what Withers suggested, but it did lead me to a solution based on a comment somewhere else.
I added a class dojo attribute and assigned a new css class to it. Only issue is that it is shifting everything in the dialog to the left...but it's ok for now.
<xe:this.dojoAttributes>
<xp:dojoAttribute name="class" value="namePickerClass">
</xp:dojoAttribute>
</xe:this.dojoAttributes>
CSS:
.namePickerClass { margin: 0 auto; width: 50%; text-align:left; border: 1px solid blue; scrolling: none;
}

Set display of section tags to flex or grid

With Reveal.js, I would like to use flexbox and/or grids to layout slides. Unfortunately, it seems Reveal.js always overrides the display property of section tags with block as part of its slide show/hide logic. Viz:
<section class="mylayout">
<div>...</div>
<div>...</div>
</section>
section.mylayout {
display: flex;
}
Has no effect, because Reveal.js adds a style="display: block" attribute to the section tag.
Is there any way around this? It works to put a nested div inside the section and have that be grid/flex, but it just feels clunky and gross to have an extra layer in there that adds no other value than a workaround.
Has anyone else found a different way to address it?
You can set it to use flexbox in the initialization settings now. See this update on the documentation.

-webkit-overflow-scrolling Problems With Objects Inserted Into DOM

I'm using -webkit-overflow-scrolling:touch for native scrolling capabilities on my iPad. But I've come into quite an odd problem:
I have one div with various children. If these children are big enough to create the need for scrolling, the device properly scrolls correctly, with momentum and all. However, if this div is not big enough to require scrolling, and suddenly has elements inserted into it and now does require scrolling, you will not be able to scroll the element at all.
I hope that wasn't too incredibly confusing, but if someone could shed some light on what to do in this situation, that would be fantastic. There isn't much documentation about this property out there.
EDIT: Tried testing this a lot, and it seems now it's just a generally intermittent problem. Every 1 out of 5 times or so, scrolling just fails for my entire web app, no matter the contents.
I had the same issue and it seems like assigning the CSS class after the new DOM element is added seems to work fine:
// your code to add a div to the DOM
// the div contains a scrollable div with the content class
setTimeout(function(){
// this is using JQuery
div.find(".content").addClass("overflowScroll");
}, 1);
// CSS class
.overflowScroll {
overflow: hidden;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
// The HTML for the div
// I am adding a dynamic list to the content div
// which should use the overflow scroll
<div class="panel">
<div class="header">
</div>
<div class="content"></div>
</div>

jQuery Mobile: multi-line buttons, in a vertical control group

On my jQuery Mobile page, i'm using a horizontal control group for some buttons.
But in some languages the text within these buttons is too long.
Instead of wrapping the text within each button, the buttons themselves wrap onto the next line.
this is the base code:
<div data-role="controlgroup" data-type="horizontal">
short button
really really really insanely long button is really really insanely long. No really, who makes buttons this big?
</div>
and with this css, we convince it to wrap inside the buttons. Otherwise the text is truncated with an ellipsis
.ui-btn-inner{
white-space: normal !important;
}
On the third page of this fiddle the problem is demonstrated
http://jsfiddle.net/koesper/R8Kwe/
Anyone have any ideas how I might tackle this?
Thanks in advance,
Casper
ps. Inspiration for the original fix came from Tosh in Jquery Mobile Multiline Button
You could set widths for the links in your control-group:
.ui-page .ui-content .ui-controlgroup a {
width : 49%;
}​
This will keep them on the same line. Here is a demo: http://jsfiddle.net/R8Kwe/6/
Also, just to be thorough, the white-space : normal actually needs to be applied to the .ui-btn-text element which is a child of the .ui-btn-inner element (so it still receives the inherited value).
Trim your long buttons - that's a usability issue. If you have action buttons named that long seems like that just defeats the purpose of an action? Other than that I wouldn't use controlgroups for something like this. I would use a custom data theme & some grids to house my buttons inline.

Resources